You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kerry/kerry/src/searchdlg.cpp

1859 lines
66 KiB

/***************************************************************************
* Copyright (C) 2005 Novell, Inc. *
* *
* 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; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA *
***************************************************************************/
#include "kerryapp.h"
#include "searchdlg.h"
#include "hitwidget.h"
#include "kwidgetlistbox.h"
#include "kerrylabel.h"
#include <tqlayout.h>
#include <tqtextcodec.h>
#include <kdebug.h>
#include <tdefiledialog.h>
#include <kpushbutton.h>
#include <tdemessagebox.h>
#include <kstandarddirs.h>
#include <tdeapplication.h>
#include <tdefileitem.h>
#include <kiconloader.h>
#include <tdelocale.h>
#include <klineedit.h>
#include <kurllabel.h>
#include <krun.h>
#include <krfcdate.h>
#include <tqtable.h>
#include <tqdir.h>
#include <tqlabel.h>
#include <tqcombobox.h>
#include <tdeio/job.h>
#include <kprotocolinfo.h>
#include <ktrader.h>
#include <kprocess.h>
#include <tqregexp.h>
#include <tdeaction.h>
#include <tdepopupmenu.h>
#include <dcopclient.h>
#include <tqcheckbox.h>
#include <kdesktopfile.h>
#include <tqtoolbutton.h>
#include <kcombobox.h>
#include <kservicegroup.h>
#include <kbookmarkmanager.h>
#include <tqcursor.h>
#include <twin.h>
#include <twinmodule.h>
SearchDlg::SearchDlg(TQWidget *parent, const char *name)
: DCOPObject("search"), HitsLayout(parent, name)
{
#define switchLabelCount 19
static TQLabel* switchLabel[switchLabelCount] = {showEverything, showApplications, showContacts, showDocuments,
showConversations, showImages, showMedia, showWebPages, showFilePathName, sortByType, sortByDate, sortByName, sortByRelevance, showAnyDate, showToday, showSinceYesterday, showThisWeek,
showThisMonth, showThisYear};
#if !GLIB_CHECK_VERSION( 2,36,0 )
g_type_init();
#endif
beagle_search = NULL;
editSearch->setMaxCount(MAX_HISTORY_ITEMS);
editSearch->setDuplicatesEnabled(false);
#if KDE_IS_VERSION( 3, 5, 4 )
KLineEdit *lineedit = new KLineEdit(editSearch);
lineedit->setClickMessage(i18n( "Applications, Contacts, Conversations, Files and more..." ) );
editSearch->setLineEdit(lineedit);
#endif
connect(editSearch->lineEdit(), TQT_SIGNAL(returnPressed()), TQT_SLOT(search()));
connect(editSearch->lineEdit(), TQT_SIGNAL(textChanged(const TQString &)), TQT_SLOT(searchChanged(const TQString &)));
showMode = Everywhere;
dateRange = AnyDate;
showBigTiles = false;
TQFont f= sortByRelevance->font();
f.setBold(true);
TQFontMetrics fm(f);
int minWidth=0;
for (int i=0; i<switchLabelCount; ++i)
minWidth = MAX(minWidth, fm.width(switchLabel[i]->text()));
frame3->setMinimumWidth(minWidth+25);
showEverything->installEventFilter(this);
showApplications->installEventFilter(this);
showContacts->installEventFilter(this);
showDocuments->installEventFilter(this);
showConversations->installEventFilter(this);
showImages->installEventFilter(this);
showMedia->installEventFilter(this);
showWebPages->installEventFilter(this);
showFilePathName->installEventFilter(this);
sortByType->installEventFilter(this);
sortByDate->installEventFilter(this);
sortByName->installEventFilter(this);
sortByRelevance->installEventFilter(this);
showAnyDate->installEventFilter(this);
showToday->installEventFilter(this);
showSinceYesterday->installEventFilter(this);
showThisWeek->installEventFilter(this);
showThisMonth->installEventFilter(this);
showThisYear->installEventFilter(this);
connect(buttonFind, TQT_SIGNAL(clicked()), TQT_SLOT(search()));
connect(buttonClear, TQT_SIGNAL(clicked()), TQT_SLOT(slotButtonClear()));
connect(buttonPrevious, TQT_SIGNAL(clicked()), TQT_SLOT(slotPrevious()));
connect(buttonNext, TQT_SIGNAL(clicked()), TQT_SLOT(slotNext()));
connect(tableHits, TQT_SIGNAL(contextMenuRequested (int, int, const TQPoint &)), TQT_SLOT(slotContextMenu(int, int, const TQPoint &)));
buttonFind->setIconSet( BarIconSet( "key_enter", 22 ) );
buttonConfigure->setGuiItem(KStdGuiItem::configure());
connect(buttonConfigure, TQT_SIGNAL(clicked()), TQT_SIGNAL(configure()));
setMouseTracking(true);
results.setAutoDelete(true);
results.clear();
displayed_results.clear();
displayAmount = 5;
displayOffset = 0;
labelStatus->setAlignment(TQt::SingleLine);
pPreviewJob = 0;
pPreviewMimeTypes = 0;
previewItems.clear();
previewItems.setAutoDelete(true);
pending_showQuickTips=true;
updateStatus();
defaultSortOrder = Modified;
currentSortOrder = defaultSortOrder;
kapp->dcopClient()->setDefaultObject( objId() );
beagleJustStarted = false;
m_searchPixmap->setPixmap( BarIcon( "edit-find", 32 ) );
TQTextCodec::setCodecForCStrings(TQTextCodec::codecForName( "utf8" ));
encodingRegexp = TQRegExp("%[\\dA-F][\\dA-F]");
bookmarkManager = 0;
m_addressBook = 0;
still_searching = false;
}
SearchDlg::~SearchDlg()
{
}
void SearchDlg::showQuickTips()
{
tableHits->clear();
HitWidget* item = new HitWidget(TQString(), TQString());
TQLabel *headerLabel = new TQLabel(item);
headerLabel->setText(i18n("Quick Tips"));
item->insertHeaderWidget(0,headerLabel);
item->setIcon("messagebox_info");
item->setDescriptionText("<qt>"+i18n("- You can use upper and lower case; search is case-insensitive.<br>"
"- To search for optional terms, use OR. ex: <b>George OR Ringo</b><br>"
"- To exclude search terms, use the minus symbol in front, such as <b>-cats</b><br>"
"- When searching for a phrase, add quotes. ex: <b>\"There be dragons\"</b><br>"
"- Add ext:type to specify a file extension, ex: <b>ext:txt</b> or <b>ext:</b> for none")+"</qt>");
tableHits->insertItem(item);
item = new HitWidget(TQString(), TQString());
headerLabel = new TQLabel(item);
headerLabel->setText(i18n("Configuration"));
item->insertHeaderWidget(0,headerLabel);
item->setIcon("package_settings");
item->setDescriptionText("<qt>"+i18n("- Choose what folders and resources shall be indexed - or not.<br>"
"- Change the sort order and the number of shown results.<br>"
"- Define your own shortcuts to invoke the search dialog.")+"</qt>");
KURLLabel *buttonStart = new KURLLabel(item);
buttonStart->setPixmap(SmallIcon("application-x-executable"));
item->insertHitWidget(0,buttonStart);
connect(buttonStart, TQT_SIGNAL(leftClickedURL()), TQT_SIGNAL(configure()));
buttonStart = new KURLLabel(item);
buttonStart->setText(i18n("Open configuration dialog"));
item->insertHitWidget(1,buttonStart);
connect(buttonStart, TQT_SIGNAL(leftClickedURL()), TQT_SIGNAL(configure()));
tableHits->insertItem(item);
labelStatus->setText("");
}
void SearchDlg::search(const TQString & search)
{
SearchDlg::search(search, "everything");
}
void SearchDlg::search(const TQString & search, const TQString &scope)
{
#define showSwitchesCount 9
static TQLabel* showSwitches[showSwitchesCount] = {showEverything, showApplications, showContacts, showDocuments,
showConversations, showImages, showMedia, showWebPages, showFilePathName};
static TQString nameSwitches[showSwitchesCount] = {"everything", "applications", "contacts", "documents",
"conversations", "images", "media", "webpages", "path"};
pending_showQuickTips=false;
showSearchDialog();
TQLabel* newShowLabel = showEverything;
ScopeType newShowMode = Everywhere;
for (int i=0; i<showSwitchesCount; ++i)
if (scope == nameSwitches[i]) {
newShowLabel = showSwitches[i];
newShowMode = (ScopeType)i;
break;
}
if (showMode!=newShowMode) {
TQFont f= showSwitches[showMode]->font();
f.setBold(false);
showSwitches[showMode]->setFont(f);
showMode = newShowMode;
f.setBold(true);
newShowLabel->setFont(f);
}
editSearch->lineEdit()->setText(search);
this->search();
}
void SearchDlg::searchChanged(const TQString & search)
{
TQString _search = search;
buttonFind->setEnabled(_search.replace("*", TQString()).length()>2);
if (!search.isEmpty() && displayed_results.count()==0 && tableHits->count()==1)
tableHits->clear();
if (search.isEmpty() && displayed_results.count()==0 && tableHits->count()==0)
showQuickTips();
}
void SearchDlg::setDisplayAmount(int amount)
{
if (amount<1 || displayAmount==amount)
return;
buttonPrevious->setShown(amount>1);
buttonNext->setShown(amount>1);
displayAmount = amount;
displayOffset = 0;
tableHits->setUpdatesEnabled(false);
fillTableHits();
tableHits->setUpdatesEnabled(true);
updateStatus();
}
void SearchDlg::setSortOrder(int order)
{
static TQLabel* sortSwitches[4] = {sortByType, sortByDate, sortByName, sortByRelevance};
defaultSortOrder = order;
if (currentSortOrder==order)
return;
TQFont f= sortSwitches[currentSortOrder]->font();
f.setBold(false);
sortSwitches[currentSortOrder]->setFont(f);
f.setBold(true);
sortSwitches[order]->setFont(f);
currentSortOrder = order;
if (displayed_results.count())
sortFilterResults();
}
void SearchDlg::slotButtonClear()
{
editSearch->clear();
slotClear();
showQuickTips();
currentSortOrder = defaultSortOrder;
}
void SearchDlg::slotClear()
{
if (beagle_search != NULL) {
kdDebug () << "Previous client w/id " << beagle_search->id << " running ... stopping it." << endl;
beagle_search->stopClient ();
}
displayOffset = 0;
stopPreview();
tableHits->clear();
displayed_results.clear();
results.clear();
updateStatus();
}
void SearchDlg::slotPrevious()
{
if (displayOffset==0)
return;
displayOffset-=displayAmount;
tableHits->setUpdatesEnabled(false);
fillTableHits();
tableHits->setUpdatesEnabled(true);
updateStatus();
}
void SearchDlg::slotNext()
{
if (displayAmount==1 || displayOffset+displayAmount>=(int)displayed_results.count())
return;
displayOffset+=displayAmount;
tableHits->setUpdatesEnabled(false);
fillTableHits();
tableHits->setUpdatesEnabled(true);
updateStatus();
}
void SearchDlg::sortFilterResults()
{
displayOffset = 0;
stopPreview();
tableHits->clear();
displayed_results.clear();
displayResults(results);
updateStatus();
}
void SearchDlg::fillTableHits()
{
stopPreview();
tableHits->clear();
previewItems.clear();
if (displayAmount==1) {
for(int i = 0; i < (int)displayed_results.count(); ++i) {
insertResult(displayed_results.at(i),i);
}
}
else {
if (displayOffset+displayAmount<=(int)displayed_results.count()) {
for(int i = displayOffset; i < displayOffset+displayAmount; ++i) {
insertResult(displayed_results.at(i),i-displayOffset);
}
}
else
for(uint i = displayOffset; i < (displayed_results.count() % displayAmount)+displayOffset; ++i) {
insertResult(displayed_results.at(i),i-displayOffset);
}
}
if (previewItems.count()) {
startPreview(previewItems);
}
}
void SearchDlg::updateStatus()
{
buttonPrevious->setEnabled(displayOffset>0);
buttonNext->setEnabled(displayOffset+displayAmount<(int)displayed_results.count());
labelStatus->setAlignment(TQt::SingleLine);
const int count = displayed_results.count();
TQString text;
if (displayAmount==1)
text=i18n("<b>%1 results</b> found.").arg(displayed_results.count());
else if (count==0)
text=i18n("<qt>No results.</qt>").replace("<qt>",TQString()).replace("</qt>",TQString());
else if (displayOffset==0)
text=i18n("Best <b>%1 results of %2</b> shown.").arg(tableHits->count()).arg(displayed_results.count());
else
text=i18n("Results <b>%1 through %2 of %3</b> are shown.").arg(displayOffset+1).arg(displayOffset+tableHits->count()).arg(displayed_results.count());
#if 0
if (still_searching)
text=text+" <b>"+i18n("(still searching)")+"</b>";
#endif
labelStatus->setText(text);
}
void SearchDlg::search()
{
current_query.set(editSearch->lineEdit()->text());
if (current_query.get().replace("*", TQString()).length()<3)
return;
editSearch->addToHistory(current_query.get());
if (!beagle_util_daemon_is_running()) {
tableHits->clear();
HitWidget* item = new HitWidget(TQString(), TQString());
TQLabel *headerLabel = new TQLabel(item);
headerLabel->setText(i18n("The query for \"%1\" failed.").arg(current_query.get()));
item->insertHeaderWidget(0,headerLabel);
item->setIcon("messagebox_critical");
item->setDescriptionText("<qt>"+i18n("The likely cause is that the Beagle daemon is not running.")+"</qt>");
cb_beagleStart = new TQCheckBox(i18n("Automatically start Beagle daemon at login"),item);
item->insertTextWidget(1,cb_beagleStart);
KURLLabel *buttonStart = new KURLLabel(item);
buttonStart->setPixmap(SmallIcon("application-x-executable"));
item->insertHitWidget(0,buttonStart);
connect(buttonStart, TQT_SIGNAL(leftClickedURL()), TQT_SLOT(slotStartBeagle()));
buttonStart = new KURLLabel(item);
buttonStart->setText(i18n("Click to start the Beagle daemon"));
item->insertHitWidget(1,buttonStart);
connect(buttonStart, TQT_SIGNAL(leftClickedURL()), TQT_SLOT(slotStartBeagle()));
tableHits->insertItem(item);
labelStatus->setText("");
return;
}
slotClear();
labelStatus->setText(i18n("Searching..."));
// Beagle search
if (beagle_search != NULL) {
kdDebug () << "Previous client w/id " << beagle_search->id << " still running ... ignoring it." << endl;
beagle_search->stopClient ();
}
current_beagle_client_id = TDEApplication::random ();
kdDebug () << "Creating client with id:" << current_beagle_client_id << endl;
m_searchPixmap->setMovie(TQMovie(locate( "appdata", "search-running.mng" )));
new_results.clear();
kdDebug() << "searchProgramList" << endl;
searchProgramList(TQString());
kdDebug() << "searchBookmars" << endl;
if (!bookmarkManager)
bookmarkManager = KBookmarkManager::userBookmarksManager();
searchBookmarks(bookmarkManager->root());
kdDebug() << "searchAddressBook" << endl;
searchAddressbook();
displayResults(new_results);
kdDebug() << "starting BeagleSearch" << endl;
beagle_search = new BeagleSearch(current_beagle_client_id, TQT_TQOBJECT(this), current_query.get());
beagle_search->start();
still_searching = true;
}
TQString SearchDlg::takeProperty( const TQString& property, TQStringList& propertyList )
{
TQString ret = TQString();
BeagleSearch::PropertyList::iterator it;
for ( it = propertyList.begin(); it != propertyList.end(); ++it ) {
const TQString search = property+'=';
if ((*it).startsWith(search)) {
ret = (*it).remove(search);
propertyList.erase(it);
break;
}
}
return ret;
}
TQDateTime SearchDlg::datetimeFromString( const TQString& s)
{
int year( s.mid( 0, 4 ).toInt() );
int month( s.mid( 4, 2 ).toInt() );
int day( s.mid( 6, 2 ).toInt() );
int hour( s.mid( 8, 2 ).toInt() );
int min( s.mid( 10, 2 ).toInt() );
int sec( s.mid( 12, 2 ).toInt() );
return TQDateTime(TQDate(year,month,day),TQTime(hour,min,sec));
}
void SearchDlg::slotCleanClientList ()
{
toclean_list_mutex.lock ();
BeagleSearch *old_client = toclean_client_list.take (0);
if (old_client != NULL) { // failsafe
kdDebug () << "Cleanup old client " << old_client->id << endl;
delete old_client;
}
toclean_list_mutex.unlock ();
}
void SearchDlg::customEvent (TQCustomEvent *e)
{
if (e->type () == RESULTFOUND) {
BeagleSearch::BeagleResultList* items = (BeagleSearch::BeagleResultList*) e->data();
if (items->count() == 0 || current_beagle_client_id != items->first()->client_id) {
kdDebug () << "Stale result" << endl;
delete items;
} else {
kdDebug () << "Good results ...total=" << items->count() << endl;
searchHasOutput(*items);
}
} else if (e->type () == RESULTGONE) {
BeagleSearch::BeagleVanishedURIList* items = (BeagleSearch::BeagleVanishedURIList*) e->data();
if (items->list.count() == 0 || current_beagle_client_id != items->client_id) {
kdDebug () << "Stale leaving from " << items->client_id << endl;
delete items;
} else {
kdDebug () << "Good leavings ...total=" << items->list.count() << endl;
searchLostOutput(items->list);
}
} else if (e->type () == SEARCHOVER) {
BeagleSearch *client = (BeagleSearch *) e->data ();
if (client == NULL) {
kdDebug () << "Query finished but client is already deleted" << endl;
searchFinished();
return;
}
// kdDebug () << "Query finished for id=" << client->id << endl;
if (current_beagle_client_id == client->id) {
searchFinished();
}
} else if (e->type () == KILLME) {
BeagleSearch *client = (BeagleSearch *) e->data ();
if (client==beagle_search)
beagle_search = NULL;
if (client->finished ())
delete client;
else {
// add client to cleanup list
toclean_list_mutex.lock ();
toclean_client_list.append (client);
kdDebug () << "Scheduling client to be deleted in 500ms" << endl;
toclean_list_mutex.unlock ();
TQTimer::singleShot (500, this, TQT_SLOT (slotCleanClientList ()));
}
}
}
void SearchDlg::insertResult(BeagleSearch::beagle_result_struct *result,int index)
{
KURL url(*(result->uri));
HitWidget* item = new HitWidget(*(result->uri),*(result->mime_type),tableHits);
item->setCollapsible(result);
item->setCollapsed(!result->show_expanded);
connect(item, TQT_SIGNAL(uncollapsed(HitWidget*)), TQT_SLOT(itemUncollapsed(HitWidget*)));
item->icon->setURL(*(result->uri));
connect(item->icon, TQT_SIGNAL(leftClickedURL()), TQT_SLOT(slotOpen()));
KURLLabel *buttonGo = new KerryLabel(item);
buttonGo->setPixmap(SmallIcon( *(result->mime_type)=="application/x-desktop" ? "application-x-executable" : "document-open") );
buttonGo->setURL(*(result->uri));
item->insertHitWidget(0,buttonGo);
connect(buttonGo, TQT_SIGNAL(leftClickedURL()), TQT_SLOT(slotOpen()));
buttonGo = new KerryLabel(item);
buttonGo->setText( *(result->mime_type)=="application/x-desktop" ? i18n("Run") : i18n("Open") );
buttonGo->setURL(*(result->uri));
item->insertHitWidget(1,buttonGo);
connect(buttonGo, TQT_SIGNAL(leftClickedURL()), TQT_SLOT(slotOpen()));
if (result->tilegroup == BeagleSearch::Website) {
item->setIcon("network");
TQString description = "<qt>";
if (result->hit_type!="Google") {
TQDateTime datetime;
datetime.setTime_t(result->last_index_time);
if (datetime.date().year()>1970)
description = description + i18n("Last viewed: %1").arg(TDEGlobal::locale()->formatDateTime(datetime,false))+"<br>";
}
item->setDescriptionText(description +i18n("URL:")+" "+*(result->uri)+"</qt>");
if (result->snippet)
item->setPropertiesText("<qt>"+*(result->snippet)+"</qt>");
KerryLabel *headerFileLabel = new KerryLabel(item);
TQStringList _properties(result->properties);
TQString title = takeProperty("dc:title",_properties);
if (title.isEmpty())
title = takeProperty("Title",_properties);
headerFileLabel->setText(title.isEmpty() ? i18n("Untitled Page") : title);
headerFileLabel->setAlignment(headerFileLabel->alignment() | TQt::SingleLine);
headerFileLabel->setURL(*(result->uri));
item->insertHeaderWidget(0,headerFileLabel);
connect(headerFileLabel, TQT_SIGNAL(leftClickedURL()), TQT_SLOT(slotOpen()));
}
else if (result->tilegroup == BeagleSearch::Feed) {
item->setIcon("network");
TQDateTime datetime;
datetime.setTime_t(result->last_index_time);
item->setDescriptionText("<qt>"+ i18n("Published: %1").arg(TDEGlobal::locale()->formatDateTime(datetime,false))+"<br>");
if (result->snippet)
item->setPropertiesText("<qt>"+*(result->snippet)+"</qt>");
TQLabel *headerLabel = new TQLabel(item);
headerLabel->setText(i18n("Weblog:"));
headerLabel->setAlignment(headerLabel->alignment() | TQt::SingleLine);
item->insertHeaderWidget(0,headerLabel);
TQStringList _properties(result->properties);
TQString title = takeProperty("dc:title",_properties);
TQString identifier = takeProperty("dc:identifier", _properties);
item->setUri(identifier);
buttonGo->setURL(identifier);
KerryLabel *headerFileLabel = new KerryLabel(item);
headerFileLabel->setText(title.isEmpty() ? i18n("Untitled Entry") : title);
headerFileLabel->setAlignment(headerFileLabel->alignment() | TQt::SingleLine);
headerFileLabel->setURL(identifier);
item->insertHeaderWidget(1,headerFileLabel);
connect(headerFileLabel, TQT_SIGNAL(leftClickedURL()), TQT_SLOT(slotOpen()));
}
else if ((*(result->uri)).startsWith("knotes:/")) {
item->setIcon("knotes");
TQDateTime datetime;
datetime.setTime_t(result->last_index_time);
item->setDescriptionText("<qt>"+ i18n("Last modified: %1").arg(TDEGlobal::locale()->formatDateTime(datetime,false))+"<br>");
if (result->snippet)
item->setPropertiesText("<qt>"+*(result->snippet)+"</qt>");
TQStringList _properties(result->properties);
TQString title = takeProperty("dc:title",_properties);
KerryLabel *headerNameLabel = new KerryLabel(item);
headerNameLabel->setText(title.isEmpty() ? i18n("Untitled") : title);
headerNameLabel->setURL(item->uri());
item->insertHeaderWidget(0,headerNameLabel);
connect(headerNameLabel, TQT_SIGNAL(leftClickedURL()), TQT_SLOT(slotOpen()));
}
else if (result->tilegroup == BeagleSearch::Note) {
item->setIcon("contents2");
TQDateTime datetime;
datetime.setTime_t(result->last_index_time);
item->setDescriptionText("<qt>"+ i18n("Last modified: %1").arg(TDEGlobal::locale()->formatDateTime(datetime,false))+"<br>");
if (result->snippet)
item->setPropertiesText("<qt>"+*(result->snippet)+"</qt>");
TQStringList _properties(result->properties);
TQString title = takeProperty("dc:title",_properties);
KerryLabel *headerNoteLabel = new KerryLabel(item);
headerNoteLabel->setText(title.isEmpty() ? i18n("Untitled Entry") : title);
headerNoteLabel->setAlignment(headerNoteLabel->alignment() | TQt::SingleLine);
headerNoteLabel->setURL(item->uri());
item->insertHeaderWidget(0,headerNoteLabel);
connect(headerNoteLabel, TQT_SIGNAL(leftClickedURL()), TQT_SLOT(slotOpen()));
}
else if ((*(result->uri)).startsWith("calendar:/")) {
item->setIcon("ximian-evolution-calendar");
TQStringList _properties(result->properties);
TQString summary = takeProperty("fixme:summary",_properties);
TQString properties;
TQDateTime datetime;
datetime = datetimeFromString(takeProperty("fixme:starttime",_properties));
properties = properties + i18n("Start time: %1").arg(TDEGlobal::locale()->formatDateTime(datetime,false)) + "<br>";
datetime = datetimeFromString(takeProperty("fixme:endtime",_properties));
properties = properties + i18n("End time: %1").arg(TDEGlobal::locale()->formatDateTime(datetime,false)) + "<br>";
BeagleSearch::PropertyList::iterator it;
for ( it = _properties.begin(); it != _properties.end(); ++it )
properties=properties+(*it);
item->setDescriptionText("<qt>"+properties+"</qt>");
KerryLabel *headerSummaryLabel = new KerryLabel(item);
headerSummaryLabel->setText(summary.isEmpty() ? i18n("No Summary Specified") : summary);
headerSummaryLabel->setURL(item->uri());
item->insertHeaderWidget(0,headerSummaryLabel);
connect(headerSummaryLabel, TQT_SIGNAL(leftClickedURL(const TQString&)), TQT_SLOT(slotOpenEvolution(const TQString&)));
}
else if ((*(result->uri)).startsWith("contacts:/")) {
item->setIcon("ximian-evolution-addressbook");
TQStringList _properties(result->properties);
TQString name = takeProperty("fixme:Name",_properties);
TQString email = takeProperty("fixme:Email1",_properties);
TQString properties;
BeagleSearch::PropertyList::iterator it;
for ( it = _properties.begin(); it != _properties.end(); ++it )
properties=properties+(*it);
if (!properties.isEmpty())
item->setDescriptionText("<qt>"+properties+"</qt>");
KerryLabel *headerNameLabel = new KerryLabel(item);
headerNameLabel->setText(name.isEmpty() ? i18n("No Name Known") : name);
headerNameLabel->setURL(item->uri());
item->insertHeaderWidget(0,headerNameLabel);
connect(headerNameLabel, TQT_SIGNAL(leftClickedURL(const TQString&)), TQT_SLOT(slotOpenEvolution(const TQString&)));
TQLabel *headerLabel = new TQLabel(item);
headerLabel->setText(i18n(","));
item->insertHeaderWidget(1,headerLabel);
KerryLabel *headerEmailLabel = new KerryLabel(item);
headerEmailLabel->setText(email);
headerEmailLabel->setURL(email);
item->insertHeaderWidget(2,headerEmailLabel);
connect(headerEmailLabel, TQT_SIGNAL(leftClickedURL(const TQString&)), TQT_SLOT(slotMailTo(const TQString&)));
}
else if ((*(result->uri)).startsWith("tdeabc:/")) {
item->setIcon("kaddressbook");
TQStringList _properties(result->properties);
TQString name = takeProperty("vCard:FN",_properties);
TQString email = takeProperty("vCard:EMAIL",_properties);
TQString properties;
BeagleSearch::PropertyList::iterator it;
for ( it = _properties.begin(); it != _properties.end(); ++it )
properties=properties+(*it);
if (!m_addressBook)
m_addressBook = TDEABC::StdAddressBook::self( false );
TDEABC::Addressee addresseee = m_addressBook->findByUid( item->uri().mid(8,10) );
TQString number;
number = addresseee.phoneNumber(TDEABC::PhoneNumber::Work).number();
if (!number.isEmpty())
properties=properties+i18n("Business phone: %1").arg(number)+"<br>";
number = addresseee.phoneNumber(TDEABC::PhoneNumber::Cell).number();
if (!number.isEmpty())
properties=properties+i18n("Mobile phone: %1").arg(number)+"<br>";
number = addresseee.phoneNumber(TDEABC::PhoneNumber::Home).number();
if (!number.isEmpty())
properties=properties+i18n("Home phone: %1").arg(number)+"<br>";
if (!properties.isEmpty())
item->setDescriptionText("<qt>"+properties+"</qt>");
KerryLabel *headerNameLabel = new KerryLabel(item);
headerNameLabel->setText(name.isEmpty() ? i18n("No Name Known") : name);
headerNameLabel->setURL(item->uri());
item->insertHeaderWidget(0,headerNameLabel);
connect(headerNameLabel, TQT_SIGNAL(leftClickedURL()), TQT_SLOT(slotOpen()));
if (!email.isEmpty()) {
TQLabel *headerLabel = new TQLabel(item);
headerLabel->setText(i18n(","));
item->insertHeaderWidget(1,headerLabel);
KerryLabel *headerEmailLabel = new KerryLabel(item);
headerEmailLabel->setText(email);
headerEmailLabel->setURL(email);
item->insertHeaderWidget(2,headerEmailLabel);
connect(headerEmailLabel, TQT_SIGNAL(leftClickedURL(const TQString&)), TQT_SLOT(slotMailTo(const TQString&)));
}
}
else if (*(result->mime_type)=="message/rfc822" || (*(result->uri)).startsWith("email:/") ) {
item->setIcon("mail_generic");
TQStringList _properties(result->properties);
TQString subject = takeProperty("dc:title",_properties);
TQString from = takeProperty("fixme:from",_properties);
TQString received = takeProperty("fixme:date",_properties);
TQDateTime received_datetime;
received_datetime = datetimeFromString(received);
if (!received.isEmpty())
item->setDescriptionText("<qt>"+i18n("Received: %1").arg(TDEGlobal::locale()->formatDateTime(received_datetime,false))+"</qt>");
TQString properties;
BeagleSearch::PropertyList::iterator it;
for ( it = _properties.begin(); it != _properties.end(); ++it )
properties=properties+(*it);
if (result->snippet) {
if (!properties.isEmpty())
properties=properties+"<br>";
properties=properties+*(result->snippet);
}
if (!properties.isEmpty())
item->setPropertiesText("<qt>"+properties+"</qt>");
KerryLabel *headerSubjectLabel = new KerryLabel(item);
headerSubjectLabel->setText(subject.isEmpty() ? i18n("No Subject") : subject);
item->insertHeaderWidget(0,headerSubjectLabel);
headerSubjectLabel->setURL(*(result->uri));
connect(headerSubjectLabel, TQT_SIGNAL(leftClickedURL()), TQT_SLOT(slotOpen()));
TQLabel *headerLabel = new TQLabel(item);
headerLabel->setText(i18n("From"));
headerLabel->setAlignment(headerLabel->alignment() | TQt::SingleLine);
item->insertHeaderWidget(1,headerLabel);
KerryLabel *headerFromLabel = new KerryLabel(item);
headerFromLabel->setText(from.isEmpty() ? i18n("Unknown Person") : from);
headerFromLabel->setURL(from);
item->insertHeaderWidget(2,headerFromLabel);
connect(headerFromLabel, TQT_SIGNAL(leftClickedURL(const TQString&)), TQT_SLOT(slotMailTo(const TQString&)));
}
else if (*(result->mime_type)=="application/x-desktop") {
KFileItem *fileitem=new KFileItem(*(result->uri),*(result->mime_type),KFileItem::Unknown);
item->setIcon(fileitem->iconName());
if (!item->isCollapsed() && canPreview(fileitem))
previewItems.append(fileitem);
else
delete fileitem;
KDesktopFile desktopfile(url.path(),true);
if (!desktopfile.readGenericName().isNull()) {
item->setDescriptionText("<qt>"+desktopfile.readGenericName()+"</qt>");
}
TQLabel *headerLabel = new TQLabel(item);
headerLabel->setText(i18n("Application:"));
headerLabel->setAlignment(headerLabel->alignment() | TQt::SingleLine);
item->insertHeaderWidget(0,headerLabel);
KerryLabel *headerFileLabel = new KerryLabel(item);
TQStringList _properties(result->properties);
TQString title = takeProperty("fixme:Name",_properties);
headerFileLabel->setText(title.isEmpty() ? desktopfile.readName() : title);
headerFileLabel->setURL(*(result->uri));
item->insertHeaderWidget(1,headerFileLabel);
connect(headerFileLabel, TQT_SIGNAL(leftClickedURL()), TQT_SLOT(slotOpen()));
}
else if (*(result->mime_type)=="beagle/x-kopete-log" || *(result->mime_type)=="beagle/x-gaim-log") {
if (*(result->mime_type)=="beagle/x-kopete-log")
item->setIcon("kopete");
else
item->setIcon("gaim");
TQDateTime datetime;
datetime.setTime_t(result->last_index_time);
item->setDescriptionText("<qt>"+i18n("Date: %1").arg(TDEGlobal::locale()->formatDateTime(datetime,false)+"</qt>"));
if (result->snippet)
item->setPropertiesText("<qt>"+*(result->snippet)+ "</qt>");
KerryLabel *headerFileLabel = new KerryLabel(item);
headerFileLabel->setURL(*(result->uri));
TQStringList _properties(result->properties);
TQString person = takeProperty("fixme:speakingto",_properties);
headerFileLabel->setText(i18n("Conversation With %1").arg(person.isEmpty() ? i18n("Unknown Person") : person));
item->insertHeaderWidget(0,headerFileLabel);
connect(headerFileLabel, TQT_SIGNAL(leftClickedURL()), TQT_SLOT(slotOpen()));
}
else if (result->tilegroup == BeagleSearch::Packages) {
TQString icon;
if (*(result->mime_type)=="application/x-rpm")
icon = "application-x-rpm";
else if (*(result->mime_type)=="application/x-deb")
icon = "application-x-deb";
else
icon = "kuroo";
item->setIcon(icon);
KerryLabel *headerFileLabel = new KerryLabel(item);
headerFileLabel->setText(url.fileName());
headerFileLabel->setTipText(url.prettyURL());
headerFileLabel->setUseTips();
headerFileLabel->setURL(*(result->uri));
item->insertHeaderWidget(0,headerFileLabel);
connect(headerFileLabel, TQT_SIGNAL(leftClickedURL()), TQT_SLOT(slotOpen()));
TQStringList _properties(result->properties);
TQString homepage = takeProperty("dc:source",_properties);
if (!homepage.isEmpty())
{
TQLabel *headerLabel = new TQLabel(item);
headerLabel->setText(i18n("From"));
headerLabel->setAlignment(headerLabel->alignment() | TQt::SingleLine);
item->insertHeaderWidget(1,headerLabel);
KerryLabel *headerFileLabel = new KerryLabel(item);
headerFileLabel->setText(homepage);
headerFileLabel->setAlignment(headerFileLabel->alignment() | TQt::SingleLine);
headerFileLabel->setURL(homepage);
item->insertHeaderWidget(2,headerFileLabel);
connect(headerFileLabel, TQT_SIGNAL(leftClickedURL(const TQString&)), TQT_SLOT(slotOpenURL(const TQString&)));
}
item->setDescriptionText(takeProperty("dc:subject", _properties));
TQString properties;
TQString install_time_str = takeProperty("fixme:install_time", _properties);
if (!install_time_str.isEmpty())
{
properties=properties+i18n("Installed on: %1").arg(TDEGlobal::locale()->formatDateTime(datetimeFromString(install_time_str),false))+"<br>";
}
TQString install_size_str = takeProperty("fixme:contents_byte_count", _properties);
if (!install_size_str.isEmpty())
{
properties=properties+i18n("Installed size: %1").arg(formatBytes(install_size_str))+"<br>";
}
TQString download_size_str = takeProperty("fixme:size", _properties);
if (!download_size_str.isEmpty())
{
properties=properties+i18n("Download size: %1").arg(formatBytes(download_size_str))+"<br>";
}
BeagleSearch::PropertyList::iterator it;
for ( it = _properties.begin(); it != _properties.end(); ++it )
{
properties=properties+(*it);
}
if (result->snippet) {
if (!properties.isEmpty())
properties=properties+"<br>";
properties=properties+*(result->snippet);
}
if (!properties.isEmpty())
item->setPropertiesText("<qt>"+properties+"</qt>");
item->insertHitSpacing(2,10);
buttonGo = new KURLLabel(item);
buttonGo->setPixmap(SmallIcon("kfm"));
item->insertHitWidget(3,buttonGo);
connect(buttonGo, TQT_SIGNAL(leftClickedURL()), TQT_SLOT(slotOpenDir()));
buttonGo = new KURLLabel(item);
buttonGo->setText(i18n("Reveal in File Manager"));
item->insertHitWidget(4,buttonGo);
connect(buttonGo, TQT_SIGNAL(leftClickedURL()), TQT_SLOT(slotOpenDir()));
}
else if ((*(result->mime_type)).startsWith("audio/")) {
KFileItem *fileitem=new KFileItem(*(result->uri),*(result->mime_type),KFileItem::Unknown);
item->setIcon(fileitem->iconName());
if (!item->isCollapsed() && canPreview(fileitem))
previewItems.append(fileitem);
else
delete fileitem;
TQStringList _properties(result->properties);
TQString title = takeProperty("fixme:title",_properties);
KerryLabel *headerFileLabel = new KerryLabel(item);
if (title.isEmpty())
headerFileLabel->setText(url.fileName());
else
headerFileLabel->setText(title);
headerFileLabel->setTipText(url.prettyURL());
headerFileLabel->setUseTips();
headerFileLabel->setURL(*(result->uri));
item->insertHeaderWidget(0,headerFileLabel);
connect(headerFileLabel, TQT_SIGNAL(leftClickedURL()), TQT_SLOT(slotOpen()));
TQLabel *headerLabel = new TQLabel(item);
headerLabel->setText(i18n("In Folder"));
headerLabel->setAlignment(headerLabel->alignment() | TQt::SingleLine);
item->insertHeaderWidget(1,headerLabel);
KerryLabel *headerDirLabel = new KerryLabel(item);
TQString directory=url.directory();
int i = directory.findRev('/');
if (i>0)
directory=directory.mid(i+1);
headerDirLabel->setText(directory);
headerDirLabel->setURL(url.directory());
headerDirLabel->setTipText(url.directory());
headerDirLabel->setUseTips();
item->insertHeaderWidget(2,headerDirLabel);
connect(headerDirLabel, TQT_SIGNAL(leftClickedURL()), TQT_SLOT(slotOpenDir()));
TQDateTime datetime;
datetime.setTime_t(result->last_index_time);
title = i18n("Last modified: %1").arg(TDEGlobal::locale()->formatDateTime(datetime,false));
item->setDescriptionText("<qt>"+title+"</qt>");
TQString properties;
BeagleSearch::PropertyList::iterator it;
for ( it = _properties.begin(); it != _properties.end(); ++it )
properties=properties+(*it);
if (result->snippet) {
if (!properties.isEmpty())
properties=properties+"<br>";
properties=properties+*(result->snippet);
}
if (!properties.isEmpty())
item->setPropertiesText("<qt>"+properties+"</qt>");
item->insertHitSpacing(2,10);
buttonGo = new KURLLabel(item);
buttonGo->setPixmap(SmallIcon("kfm"));
item->insertHitWidget(3,buttonGo);
connect(buttonGo, TQT_SIGNAL(leftClickedURL()), TQT_SLOT(slotOpenDir()));
buttonGo = new KURLLabel(item);
buttonGo->setText(i18n("Reveal in File Manager"));
item->insertHitWidget(4,buttonGo);
connect(buttonGo, TQT_SIGNAL(leftClickedURL()), TQT_SLOT(slotOpenDir()));
}
else {
KFileItem *fileitem=new KFileItem(*(result->uri),*(result->mime_type),KFileItem::Unknown);
item->setIcon(fileitem->iconName());
if (!item->isCollapsed() && canPreview(fileitem))
previewItems.append(fileitem);
else
delete fileitem;
KerryLabel *headerFileLabel = new KerryLabel(item);
headerFileLabel->setText(url.fileName());
headerFileLabel->setTipText(url.prettyURL());
headerFileLabel->setUseTips();
headerFileLabel->setURL(*(result->uri));
item->insertHeaderWidget(0,headerFileLabel);
connect(headerFileLabel, TQT_SIGNAL(leftClickedURL()), TQT_SLOT(slotOpen()));
TQLabel *headerLabel = new TQLabel(item);
headerLabel->setText(i18n("In Folder"));
headerLabel->setAlignment(headerLabel->alignment() | TQt::SingleLine);
item->insertHeaderWidget(1,headerLabel);
KerryLabel *headerDirLabel = new KerryLabel(item);
TQString directory=url.directory();
int i = directory.findRev('/');
if (i>0)
directory=directory.mid(i+1);
headerDirLabel->setText(directory);
headerDirLabel->setURL(url.directory());
headerDirLabel->setTipText(url.directory());
headerDirLabel->setUseTips();
item->insertHeaderWidget(2,headerDirLabel);
connect(headerDirLabel, TQT_SIGNAL(leftClickedURL()), TQT_SLOT(slotOpenDir()));
TQString title;
if (*(result->mime_type)=="inode/directory") {
int count = TQDir(url.path()).count() -2 ;
if (count==0)
title=i18n("Empty");
else
title=i18n("Contains 1 item","Contains %n items",count);
}
else {
TQDateTime datetime;
datetime.setTime_t(result->last_index_time);
title = i18n("Last modified: %1").arg(TDEGlobal::locale()->formatDateTime(datetime,false));
}
item->setDescriptionText("<qt>"+title+"</qt>");
TQString properties;
BeagleSearch::PropertyList::iterator it;
for ( it = result->properties.begin(); it != result->properties.end(); ++it )
properties=properties+(*it);
if (result->snippet) {
if (!properties.isEmpty())
properties=properties+"<br>";
properties=properties+*(result->snippet);
}
if (!properties.isEmpty())
item->setPropertiesText("<qt>"+properties+"</qt>");
item->insertHitSpacing(2,10);
buttonGo = new KURLLabel(item);
buttonGo->setPixmap(SmallIcon("kfm"));
item->insertHitWidget(3,buttonGo);
connect(buttonGo, TQT_SIGNAL(leftClickedURL()), TQT_SLOT(slotOpenDir()));
buttonGo = new KURLLabel(item);
buttonGo->setText(i18n("Reveal in File Manager"));
item->insertHitWidget(4,buttonGo);
connect(buttonGo, TQT_SIGNAL(leftClickedURL()), TQT_SLOT(slotOpenDir()));
}
item->score->setText(i18n("<p align=\"center\">Score: %1</p>").arg(result->score,0,'f',1));
tableHits->insertItem(item,index);
}
void SearchDlg::itemUncollapsed(HitWidget* item)
{
KFileItem *fileitem=new KFileItem(item->uri(),item->mimetype(),KFileItem::Unknown);
if (canPreview(fileitem))
previewItems.append(fileitem);
startPreview(previewItems);
}
void SearchDlg::searchHasOutput(BeagleSearch::BeagleResultList &items)
{
BeagleSearch::BeagleResultList* searchResults = new BeagleSearch::BeagleResultList;
for (BeagleSearch::BeagleResultList::ConstIterator it = items.begin(); it != items.end(); ++it) {
BeagleSearch::beagle_result_struct* result = (*it);
if ((*(result->uri)).find(encodingRegexp)>0) {
KURL kurl(*(result->uri));
*(result->uri)=kurl.url();
}
if (!checkUriInResults(*(result->uri)) && !(*(result->uri)).startsWith("kbookmark:/")) {
result->show_expanded=showBigTiles;
results.append(result);
searchResults->append(result);
}
}
displayResults(*searchResults);
}
void SearchDlg::displayResults(BeagleSearch::BeagleResultList &items)
{
bool rebuildDisplay = false;
if (displayAmount==1)
tableHits->setUpdatesEnabled(false);
for (BeagleSearch::BeagleResultList::ConstIterator it = items.begin(); it != items.end(); ++it) {
BeagleSearch::beagle_result_struct *result = *it;
bool show = false;
switch (showMode)
{
case Everywhere:
show = true;
break;
case Applications:
show = ( result->tilegroup == BeagleSearch::Application );
break;
case Contacts:
show = ( result->tilegroup == BeagleSearch::Contact );
break;
case Documents:
show = ( result->tilegroup == BeagleSearch::Documents );
break;
case Conversations:
show = ( result->tilegroup == BeagleSearch::Conversations );
break;
case Images:
show = ( result->tilegroup == BeagleSearch::Image );
break;
case Media:
show = ( result->tilegroup == BeagleSearch::Audio || result->tilegroup == BeagleSearch::Video);
break;
case Website:
show = ( result->tilegroup == BeagleSearch::Website);
break;
case FilePathName:
show = current_query.matches(*(result->uri));
default:
break;
}
if (!show)
continue;
TQDateTime datetime;
datetime.setTime_t(result->last_index_time);
TQDate date = datetime.date();
show = false;
switch (dateRange)
{
case AnyDate:
show = true;
break;
case Today:
show = ( datetime.date()==TQDate::currentDate() );
break;
case SinceYesterday:
show = ( datetime.date()>TQDate::currentDate().addDays(-1) );
break;
case ThisWeek:
show = ( datetime.date().year()==TQDate::currentDate().year() &&
datetime.date().weekNumber()==TQDate::currentDate().weekNumber() );
break;
case ThisMonth:
show = ( datetime.date().year()==TQDate::currentDate().year() &&
datetime.date().month()==TQDate::currentDate().month() );
break;
case ThisYear:
show = ( datetime.date().year()==TQDate::currentDate().year() );
break;
default:
break;
}
if (!show)
continue;
int i = 0;
for (BeagleSearch::BeagleResultList::ConstIterator result_it = displayed_results.begin(); result_it != displayed_results.end(); ++result_it) {
bool foundplace = false;
switch (currentSortOrder)
{
case Type:
if ( result->tilegroup < (*result_it)->tilegroup ||
(result->tilegroup == (*result_it)->tilegroup && (*result->mime_type) < (*(*result_it)->mime_type)) ||
(result->tilegroup == (*result_it)->tilegroup && (*result->mime_type) == (*(*result_it)->mime_type) && result->last_index_time >= (*result_it)->last_index_time) )
foundplace = true;
break;
case Name:
if (KURL(*(result->uri)).fileName().lower() < KURL(*((*(result_it))->uri)).fileName().lower())
foundplace = true;
break;
case Modified:
if (result->last_index_time >= (*result_it)->last_index_time)
foundplace = true;
break;
default:
if (result->score >= (*result_it)->score)
foundplace = true;
break;
}
if (foundplace)
break;
++i;
}
if (displayed_results.count()==0)
tableHits->clear();
displayed_results.insert(i, result);
if (displayAmount==1)
insertResult(result,i);
else if (i<=displayOffset+displayAmount)
rebuildDisplay = true;
}
if (displayAmount==1)
tableHits->setUpdatesEnabled(true);
else if (rebuildDisplay) {
tableHits->setUpdatesEnabled(false);
fillTableHits();
tableHits->setUpdatesEnabled(true);
}
updateStatus();
}
void SearchDlg::slotOpen()
{
HitWidget* item = static_cast<HitWidget*>(TQT_TQWIDGET(TQT_TQOBJECT(const_cast<TQT_BASE_OBJECT_NAME*>(sender()))->parent()));
if (item) {
TQString mimetype = item->mimetype();
if (mimetype=="beagle/x-kopete-log" || mimetype=="beagle/x-gaim-log") {
TDEProcess *proc = new TDEProcess;
*proc << "beagle-imlogviewer";
KURL kuri = KURL(item->uri());
TQString uri = kuri.path();
if (mimetype=="beagle/x-kopete-log")
*proc << "--client" << "kopete" << "--highlight-search" << current_query.get() << uri;
else
*proc << "--client" << "gaim" << "--highlight-search" << current_query.get() << uri;
if (!proc->start()) {
// KMessageBox::error(0,i18n("Could not start instant message log viewer."));
if (mimetype=="beagle/x-kopete-log")
KRun::runURL(uri, "text/plain", false, true);
else
KRun::runURL(uri, "text/html", false, true);
return;
}
}
else if (item->uri().startsWith("calendar:/") || item->uri().startsWith("contacts:/")
|| item->uri().startsWith("email:/"))
{
slotOpenEvolution(item->uri());
}
else if (item->uri().startsWith("mailbox:/") && item->uri().find("thunderbird")>0)
{
slotOpenThunderbird(item->uri());
}
else if (item->uri().startsWith("tdeabc:/") )
{
slotOpenKAddressBook(item->uri().mid(8,10));
}
else if (item->uri().startsWith("knotes:/") )
{
slotOpenKNotes(item->uri().mid(10,21));
}
else if (item->uri().startsWith("note:/")) {
TDEProcess *proc = new TDEProcess;
*proc << "tomboy";
*proc << "--open-note" << item->uri() << "--highligh-search" << "\""+current_query.get()+"\"";
if (!proc->start()) {
KMessageBox::error(0,i18n("Could not start Tomboy."));
return;
}
}
else {
if (mimetype=="beagle/x-konq-cache")
mimetype = "text/html";
KRun::runURL(item->uri(), mimetype, false, true);
}
}
}
void SearchDlg::slotOpenDir()
{
HitWidget* item = static_cast<HitWidget*>(TQT_TQWIDGET(TQT_TQOBJECT(const_cast<TQT_BASE_OBJECT_NAME*>(sender()))->parent()));
if (item)
KRun::runURL(KURL(item->uri()).directory(), "inode/directory", false, true);
}
void SearchDlg::slotMailTo(const TQString &address)
{
kapp->invokeMailer(address, TQString());
}
void SearchDlg::slotOpenEvolution(const TQString &address)
{
TDEProcess *proc = new TDEProcess;
*proc << "evolution";
*proc << address;
if (!proc->start()) {
KMessageBox::error(0,i18n("Could not start Evolution."));
return;
}
}
void SearchDlg::slotOpenThunderbird(const TQString &address)
{
TDEProcess *proc = new TDEProcess;
*proc << "thunderbird";
*proc << "-mail";
*proc << address;
if (!proc->start()) {
KMessageBox::error(0,i18n("Could not start Thunderbird."));
return;
}
}
void SearchDlg::slotOpenKAddressBook(const TQString &uid)
{
TDEProcess *proc = new TDEProcess;
*proc << "kaddressbook";
*proc << "--uid" << uid;
if (!proc->start()) {
KMessageBox::error(0,i18n("Could not start KAddressBook."));
return;
}
}
void SearchDlg::slotOpenKNotes(const TQString& noteid)
{
if (ensureServiceRunning("knotes")) {
TQByteArray data;
TQDataStream arg(data, IO_WriteOnly);
arg << noteid;
kapp->dcopClient()->send("knotes","KNotesIface","showNote(TQString)", data);
}
}
void SearchDlg::slotOpenURL(const TQString& url)
{
(void) new KRun( url, parentWidget());
}
TQString SearchDlg::formatBytes(TQString& bytesStr) const
{
static double kilobyte = 1024.0;
static double megabyte = 1024.0*1024.0;
double bytes = TDEGlobal::locale()->readNumber(bytesStr);
if (bytes < megabyte)
return TDEGlobal::locale()->formatNumber(bytes/kilobyte, 2) + "K";
return TDEGlobal::locale()->formatNumber(bytes/megabyte, 2) + "M";
}
void SearchDlg::slotStartBeagle()
{
beagleJustStarted = true;
if (cb_beagleStart->isChecked()) {
TDEConfig *config = TDEGlobal::config();
config->setGroup("Beagle");
config->writeEntry("AutoStart",true);
config->sync();
}
TDEProcess *proc = new TDEProcess;
*proc << "beagled";
*proc << "--indexing-delay 2";
if (!proc->start()) {
KMessageBox::error(0,i18n("Could not start Beagle daemon."));
return;
}
slotClear();
TQTimer::singleShot(5000, this, TQT_SLOT(search()));
}
void SearchDlg::searchLostOutput(BeagleSearch::VanishedURIList &items)
{
bool rebuildDisplay = false;
for (BeagleSearch::VanishedURIList::ConstIterator it = items.begin(); it != items.end(); ++it) {
int i;
for(i = 0; i < (int)displayed_results.count(); ++i)
{
BeagleSearch::beagle_result_struct *result = displayed_results.at(i);
if (*(result->uri)==(*it)) {
displayed_results.remove(i);
if (displayed_results.count()==0)
searchFinished();
else if (displayAmount==1)
tableHits->removeItem(i);
else if (i<=displayOffset+displayAmount) {
rebuildDisplay = true;
if (displayOffset>=(int)displayed_results.count())
displayOffset-=displayAmount;
}
break;
}
}
for(i = 0; i < (int)results.count(); ++i)
{
BeagleSearch::beagle_result_struct *result = results.at(i);
if (*(result->uri)==(*it)) {
results.remove(i);
break;
}
}
}
if (rebuildDisplay) {
tableHits->setUpdatesEnabled(false);
fillTableHits();
tableHits->setUpdatesEnabled(true);
}
updateStatus();
}
void SearchDlg::searchFinished()
{
m_searchPixmap->setPixmap( BarIcon( "edit-find", 32 ) );
still_searching = false;
if (displayed_results.count()) {
updateStatus();
return;
}
if (editSearch->lineEdit()->text().isEmpty()) {
showQuickTips();
return;
}
tableHits->clear();
HitWidget* item = new HitWidget(TQString(), TQString());
TQLabel *headerLabel = new TQLabel(item);
headerLabel->setText(i18n("No results for \"%1\" were found.").arg(current_query.get()));
item->insertHeaderWidget(0,headerLabel);
item->setIcon("messagebox_warning");
TQString text = "<qt>";
if (showMode)
text += i18n("- A broader search scope might produce more results.")+"<br>";
text += i18n("- You should check the spelling of your search words.");
if (beagleJustStarted) {
text += "<br>"+i18n("- The Beagle daemon was just started. Please be patient until it finished its indexing.");
beagleJustStarted = false;
}
item->setDescriptionText(text+"</qt>");
labelStatus->setText("");
tableHits->insertItem(item);
}
void SearchDlg::searchError(const TQString& error)
{
kdDebug() << "SearchDlg::searchError() " << error << endl;
}
bool SearchDlg::canPreview( KFileItem* item )
{
if ( !TDEGlobalSettings::showFilePreview( item->url() ) )
return false;
if ( pPreviewMimeTypes == 0L )
updatePreviewMimeTypes();
return mimeTypeMatch( item->mimetype(), *( pPreviewMimeTypes ) );
}
void SearchDlg::updatePreviewMimeTypes()
{
if ( pPreviewMimeTypes == 0L )
pPreviewMimeTypes = new TQStringList;
else
pPreviewMimeTypes->clear();
// Load the list of plugins to determine which mimetypes are supported
TDETrader::OfferList plugins = TDETrader::self()->query("ThumbCreator");
TDETrader::OfferList::ConstIterator it;
for ( it = plugins.begin(); it != plugins.end(); ++it ) {
TQStringList mimeTypes = (*it)->property("MimeTypes").toStringList();
for (TQStringList::ConstIterator mt = mimeTypes.begin(); mt != mimeTypes.end(); ++mt)
pPreviewMimeTypes->append(*mt);
}
}
bool SearchDlg::mimeTypeMatch( const TQString& mimeType, const TQStringList& mimeList ) const
{
for (TQStringList::ConstIterator mt = mimeList.begin(); mt != mimeList.end(); ++mt)
{
if ( mimeType == *mt )
return true;
// Support for *mt == "image/*"
TQString tmp( mimeType );
if ( (*mt).endsWith("*") && tmp.replace(TQRegExp("/.*"), "/*") == (*mt) )
return true;
}
return false;
}
void SearchDlg::startPreview( const KFileItemList& items )
{
stopPreview(); // just in case
int iconSize = TDEGlobal::iconLoader()->currentSize( TDEIcon::Desktop );
pPreviewJob = TDEIO::filePreview( items, TDEIcon::SizeHuge, TDEIcon::SizeHuge, iconSize,
true /*m_pSettings->textPreviewIconTransparency()*/, true /* scale */,
true /* save */, 0); //&(d->previewSettings) );
connect( pPreviewJob, TQT_SIGNAL( gotPreview( const KFileItem *, const TQPixmap & ) ),
this, TQT_SLOT( slotPreview( const KFileItem *, const TQPixmap & ) ) );
connect( pPreviewJob, TQT_SIGNAL( result( TDEIO::Job * ) ),
this, TQT_SLOT( slotPreviewResult() ) );
}
void SearchDlg::stopPreview()
{
if (pPreviewJob)
{
pPreviewJob->kill();
pPreviewJob = 0;
}
}
void SearchDlg::slotPreview(const KFileItem *item, const TQPixmap &pix)
{
for(uint i=0; i < tableHits->count(); ++i)
{
HitWidget* w = static_cast<HitWidget*>(tableHits->item(i));
if (w && KURL(w->uri()).prettyURL() == item->url().prettyURL() ) {
w->icon->setPixmap(pix);
break;
}
}
}
void SearchDlg::slotPreviewResult()
{
pPreviewJob = 0;
previewItems.clear();
}
void SearchDlg::keyPressEvent(TQKeyEvent *e)
{
if (e->key()==Key_PageDown && displayAmount!=1) {
if (e->state()==ControlButton) {
if (displayOffset+displayAmount>=(int)displayed_results.count())
return;
displayOffset=((displayed_results.count() -1) / displayAmount) * displayAmount;
tableHits->setUpdatesEnabled(false);
fillTableHits();
tableHits->setUpdatesEnabled(true);
updateStatus();
}
else
slotNext();
}
else if (e->key()==Key_PageUp && displayAmount!=1) {
if (e->state()==ControlButton) {
if (displayOffset==0)
return;
displayOffset=0;
tableHits->setUpdatesEnabled(false);
fillTableHits();
tableHits->setUpdatesEnabled(true);
updateStatus();
}
else
slotPrevious();
}
else
HitsLayout::keyPressEvent(e);
}
void SearchDlg::showEvent(TQShowEvent *e )
{
HitsLayout::showEvent( e );
if (pending_showQuickTips) {
showQuickTips();
pending_showQuickTips=false;
}
}
void SearchDlg::slotContextMenu( int /*row*/, int /*col*/, const TQPoint & pos )
{
TDEPopupMenu *popup = new TDEPopupMenu(this);
popup->insertTitle(i18n("Collapse") + " / " + i18n("Expand"));
popup->insertItem(i18n("Collapse All"), 1);
popup->insertItem(i18n("Expand All"), 2);
int selected = popup->exec(pos);
if (selected==1 || selected==2)
for(uint i=0; i < tableHits->count(); ++i) {
HitWidget* w = static_cast<HitWidget*>(tableHits->item(i));
w->setCollapsed(selected==1);
}
delete popup;
}
void SearchDlg::showSearchDialog()
{
show();
KWin::setOnDesktop( winId(), KWin::currentDesktop() );
kapp->updateUserTimestamp();
KWin::forceActiveWindow( winId() );
editSearch->setFocus();
editSearch->lineEdit()->selectAll();
}
void SearchDlg::configChanged()
{
TDEConfig *config = TDEGlobal::config();
config->reparseConfiguration();
config->setGroup("General");
showBigTiles=config->readBoolEntry("ShowBigTiles",false);
setDisplayAmount(config->readNumEntry("DisplayAmount", 20));
setSortOrder(config->readNumEntry("DefaultSortOrder",0));
}
void SearchDlg::searchProgramList(TQString relPath)
{
KServiceGroup::Ptr group = KServiceGroup::group(relPath);
if (!group || !group->isValid())
return;
KServiceGroup::List list = group->entries();
if (list.isEmpty())
return;
KServiceGroup::List::ConstIterator it = list.begin();
for(; it != list.end(); ++it) {
KSycocaEntry *e = *it;
if(e != 0) {
if(e->isType(KST_KServiceGroup)) {
KServiceGroup::Ptr g(static_cast<KServiceGroup *>(e));
if(!g->noDisplay())
searchProgramList(g->relPath());
} else if(e->isType(KST_KService)) {
KService::Ptr s(static_cast<KService *>(e));
if(s->type() == "Application" && !s->noDisplay() && !checkUriInResults(locate("apps", s->desktopEntryPath()))) {
if (!current_query.matches(s->name().lower()+' '+s->genericName()+' '+
s->exec()+' '+s->keywords().join(",")+' '+s->comment()+' ' +
group->caption()+' '+s->categories().join(",")))
continue;
BeagleSearch::beagle_result_struct *result = new BeagleSearch::beagle_result_struct;
result->mime_type=new TQString("application/x-desktop");
result->tilegroup = BeagleSearch::Application;
result->uri=new TQString("file://"+locate("apps", s->desktopEntryPath()));
*(result->properties).append("fixme:Name="+s->name());
result->tilegroup = BeagleSearch::Application;
result->score = 0.0;
result->show_expanded=showBigTiles;
results.append(result);
new_results.append(result);
}
}
}
}
}
bool SearchDlg::checkUriInResults(const TQString& path) const
{
for (BeagleSearch::BeagleResultList::ConstIterator it = results.begin(); it != results.end(); ++it) {
BeagleSearch::beagle_result_struct *result = *it;
if (*(result->uri) == path)
return true;
}
return false;
}
void SearchDlg::searchBookmarks(KBookmarkGroup group)
{
KBookmark bookmark = group.first();
while(!bookmark.isNull()) {
if (bookmark.isGroup()) {
searchBookmarks(bookmark.toGroup());
} else if (!bookmark.isSeparator() && !bookmark.isNull()) {
if (!current_query.matches(bookmark.fullText()+' '+bookmark.url().url())) {
bookmark = group.next(bookmark);
continue;
}
if (checkUriInResults(bookmark.url().prettyURL())) {
bookmark = group.next(bookmark);
continue;
}
BeagleSearch::beagle_result_struct *result = new BeagleSearch::beagle_result_struct;
result->mime_type=new TQString("text/html");
result->uri=new TQString(bookmark.url().prettyURL());
*(result->properties).append("dc:title="+bookmark.fullText());
result->tilegroup = BeagleSearch::Website;
result->score = 0.0;
result->show_expanded=showBigTiles;
results.append(result);
new_results.append(result);
}
bookmark = group.next(bookmark);
}
}
void SearchDlg::searchAddressbook()
{
if (!m_addressBook)
m_addressBook = TDEABC::StdAddressBook::self( false );
TDEABC::AddressBook::ConstIterator it = m_addressBook->begin();
while (it!=m_addressBook->end()) {
if (!current_query.matches((*it).assembledName()+' '+(*it).fullEmail())) {
it++;
continue;
}
if (checkUriInResults("tdeabc:///"+(*it).uid())) {
it++;
continue;
}
TQString realName = (*it).realName();
if (realName.isEmpty())
realName=(*it).preferredEmail();
BeagleSearch::beagle_result_struct *result = new BeagleSearch::beagle_result_struct;
result->mime_type=new TQString("text/html");
result->uri=new TQString("tdeabc:///"+(*it).uid());
*(result->properties).append("vCard:FN="+realName);
*(result->properties).append("vCard:EMAIL="+(*it).preferredEmail());
result->tilegroup = BeagleSearch::Contact;
result->score = 0.0;
result->show_expanded=showBigTiles;
results.append(result);
new_results.append(result);
it++;
}
}
bool SearchDlg::eventFilter(TQObject *obj, TQEvent *e)
{
#define showSwitchesCount 9
static TQLabel* showSwitches[showSwitchesCount] = {showEverything, showApplications, showContacts, showDocuments,
showConversations, showImages, showMedia, showWebPages, showFilePathName};
#define sortSwitchesCount 4
static TQLabel* sortSwitches[sortSwitchesCount] = {sortByType, sortByDate, sortByName, sortByRelevance};
#define dateSwitchesCount 6
static TQLabel* dateSwitches[dateSwitchesCount] = {showAnyDate, showToday, showSinceYesterday, showThisWeek,
showThisMonth, showThisYear};
if (e->type()==TQEvent::Enter) {
TQApplication::setOverrideCursor( TQCursor(TQt::PointingHandCursor) );
} else if (e->type()==TQEvent::Leave) {
TQApplication::restoreOverrideCursor();
} else if (e->type()==TQEvent::MouseButtonPress) {
for (int i=0; i<showSwitchesCount; ++i)
if (TQT_BASE_OBJECT(obj) ==TQT_BASE_OBJECT(showSwitches[i])) {
if (i!=showMode) {
TQFont f= showSwitches[showMode]->font();
f.setBold(false);
showSwitches[showMode]->setFont(f);
showMode = (ScopeType)i;
f.setBold(true);
showSwitches[showMode]->setFont(f);
sortFilterResults();
}
return true;
}
for (int i=0; i<sortSwitchesCount; ++i)
if (TQT_BASE_OBJECT(obj) ==TQT_BASE_OBJECT(sortSwitches[i])) {
setSortOrder(i);
return true;
}
for (int i=0; i<dateSwitchesCount; ++i)
if (TQT_BASE_OBJECT(obj) ==TQT_BASE_OBJECT(dateSwitches[i])) {
if (i!=dateRange) {
TQFont f= dateSwitches[dateRange]->font();
f.setBold(false);
dateSwitches[dateRange]->setFont(f);
dateRange = (DateRange)i;
f.setBold(true);
dateSwitches[dateRange]->setFont(f);
sortFilterResults();
}
return true;
}
}
return false;
}
bool SearchDlg::ensureServiceRunning(const TQString& name)
{
TQCString appname = name.utf8();
if (kapp->dcopClient()->isApplicationRegistered(appname)) {
return true;
}
else {
TQStringList URLs;
TQByteArray data, replyData;
TQCString replyType;
TQDataStream arg(data, IO_WriteOnly);
arg << name << URLs;
if ( !kapp->dcopClient()->call( "tdelauncher", "tdelauncher", "start_service_by_desktop_name(TQString,TQStringList)",
data, replyType, replyData) ) {
tqWarning( "call to tdelauncher failed.");
return false;
}
TQDataStream reply(replyData, IO_ReadOnly);
if ( replyType != "serviceResult" )
{
tqWarning( "unexpected result '%s' from tdelauncher.", replyType.data());
return false;
}
int result;
TQCString dcopName;
TQString error;
reply >> result >> dcopName >> error;
if (result != 0)
{
tqWarning("Error starting: %s", error.local8Bit().data());
return false;
}
return true;
}
}
#include "searchdlg.moc"