Beispiel #1
0
void KURLCompletion::customEvent(QCustomEvent *e)
{
    if(e->type() == CompletionMatchEvent::uniqueType())
    {

        CompletionMatchEvent *event = static_cast< CompletionMatchEvent * >(e);

        event->completionThread()->wait();

        if(!isListedURL(CTUser))
        {
            stop();
            clear();
            addMatches(event->completionThread()->matches());
        }

        setListedURL(CTUser);

        if(d->userListThread == event->completionThread())
            d->userListThread = 0;

        if(d->dirListThread == event->completionThread())
            d->dirListThread = 0;

        delete event->completionThread();
    }
}
Beispiel #2
0
bool KURLCompletion::userCompletion(const MyURL &url, QString *match)
{
    if(url.protocol() != "file" || !url.dir().isEmpty() || url.file().at(0) != '~')
        return false;

    if(!isListedURL(CTUser))
    {
        stop();
        clear();

        if(!d->userListThread)
        {
            d->userListThread = new UserListThread(this);
            d->userListThread->start();

            // If the thread finishes quickly make sure that the results
            // are added to the first matching case.

            d->userListThread->wait(200);
            QStringList l = d->userListThread->matches();
            addMatches(l);
        }
    }
    *match = finished();
    return true;
}
bool Matches::addMatches( char *s, int32_t slen, mf_t flags ) {
	// . do not breach
	// . happens a lot with a lot of link info text
	if ( m_numMatchGroups >= MAX_MATCHGROUPS ) {
		return true;
	}

	// get some new ptrs for this match group
	Words    *wp = &m_wordsArray    [ m_numMatchGroups ];
	Bits     *bp = &m_bitsArray     [ m_numMatchGroups ];
	Pos      *pb = &m_posArray      [ m_numMatchGroups ];

	// set the words class for this match group
	if ( !wp->set( s, slen, true ) ) {
		return false;
	}

	// bits vector
	if ( ! bp->setForSummary ( wp ) ) {
		return false;
	}

	// position vector
	if ( ! pb->set ( wp ) ) {
		return false;
	}

	// record the start
	int32_t startNumMatches = m_numMatches;
	// sometimes it returns true w/o incrementing this
	int32_t n = m_numMatchGroups;
	// . add all the Match classes from this match group
	// . this increments m_numMatchGroups on success
	bool status = addMatches( wp, NULL, NULL, bp, pb, flags );

	// if this matchgroup had some, matches, then keep it
	if ( m_numMatches > startNumMatches ) {
		return status;
	}

	// otherwise, reset it, useless
	wp->reset();
	bp->reset();
	pb->reset();

	// do not decrement the counter if we never incremented it
	if ( n == m_numMatchGroups ) {
		return status;
	}

	// ok, remove it
	m_numMatchGroups--;

	return status;
}
Beispiel #4
0
/*
 * listDirectories
 *
 * List files starting with 'filter' in the given directories,
 * either using DirLister or listURLs()
 *
 * In either case, addMatches() is called with the listed
 * files, and eventually finished() when the listing is done
 *
 * Returns the match if available, or QString::null if
 * DirLister timed out or using kio
 */
QString KURLCompletion::listDirectories(const QStringList &dirList, const QString &filter, bool only_exe, bool only_dir, bool no_hidden,
                                        bool append_slash_to_dir)
{
    assert(!isRunning());

    if(!::getenv("KURLCOMPLETION_LOCAL_KIO"))
    {

        // kdDebug() << "Listing (listDirectories): " << dirList << " filter=" << filter << " without KIO" << endl;

        // Don't use KIO

        if(d->dirListThread)
            d->dirListThread->requestTermination();

        QStringList dirs;

        for(QStringList::ConstIterator it = dirList.begin(); it != dirList.end(); ++it)
        {
            KURL url;
            url.setPath(*it);
            if(kapp->authorizeURLAction("list", KURL(), url))
                dirs.append(*it);
        }

        d->dirListThread = new DirectoryListThread(this, dirs, filter, only_exe, only_dir, no_hidden, append_slash_to_dir);
        d->dirListThread->start();
        d->dirListThread->wait(200);
        addMatches(d->dirListThread->matches());

        return finished();
    }
    else
    {

        // Use KIO
        // kdDebug() << "Listing (listDirectories): " << dirList << " with KIO" << endl;

        QValueList< KURL * > url_list;

        QStringList::ConstIterator it = dirList.begin();

        for(; it != dirList.end(); it++)
            url_list.append(new KURL(*it));

        listURLs(url_list, filter, only_exe, no_hidden);
        // Will call addMatches() and finished()

        return QString::null;
    }
}
Beispiel #5
0
void Desk::addMatches (const QString &dirPath, const QString &match,
               bool subdirs, Operation *op)
   {
   int upto = 0;

   QDir dir (dirPath);

   // don't write back the maxdesk.ini file if we are just selecting some
   if (match.length () > 0 || subdirs)
      _do_writeDesk = false;

//   printf ("dir = %s\n", dirPath.latin1 ());
   dir.setFilter( (QDir::Filter)((subdirs ? QDir::Dirs : 0) | QDir::Files | QDir::NoSymLinks ));
   dir.setSorting( QDir::Name);

   const QFileInfoList list = dir.entryInfoList();
   if (!list.size ())
      {
      printf ("dir not found\n");
      return;
      }

   if (op)
      op->setCount (list.size ());
   for (int i = 0; i < list.size (); i++)
      {
      QFileInfo fi = list.at (i);
      if (op)
         op->setProgress (upto++);

      if (fi.isDir ())
         {
         if (fi.fileName () != "." && fi.fileName () != "..")
            addMatches (dirPath + fi.fileName () + "/", match, subdirs, 0);
         }
      else if (match == QString::null || fi.fileName ().contains (match, false))
         addFile (fi, dirPath);
      }
   updateRowCount ();
   }
Beispiel #6
0
bool KURLCompletion::envCompletion(const MyURL &url, QString *match)
{
    if(url.file().at(0) != '$')
        return false;

    if(!isListedURL(CTEnv))
    {
        stop();
        clear();

        char **env = environ;

        QString dollar = QString("$");

        QStringList l;

        while(*env)
        {
            QString s = QString::fromLocal8Bit(*env);

            int pos = s.find('=');

            if(pos == -1)
                pos = s.length();

            if(pos > 0)
                l.append(dollar + s.left(pos));

            env++;
        }

        addMatches(l);
    }

    setListedURL(CTEnv);

    *match = finished();
    return true;
}
Beispiel #7
0
/*
 * slotEntries
 *
 * Receive files listed by KIO and call addMatches()
 */
void KURLCompletion::slotEntries(KIO::Job *, const KIO::UDSEntryList &entries)
{
    QStringList matches;

    KIO::UDSEntryListConstIterator it = entries.begin();
    KIO::UDSEntryListConstIterator end = entries.end();

    QString filter = d->list_urls_filter;

    int filter_len = filter.length();

    // Iterate over all files
    //
    for(; it != end; ++it)
    {
        QString name;
        QString url;
        bool is_exe = false;
        bool is_dir = false;

        KIO::UDSEntry e = *it;
        KIO::UDSEntry::ConstIterator it_2 = e.begin();

        for(; it_2 != e.end(); it_2++)
        {
            switch((*it_2).m_uds)
            {
                case KIO::UDS_NAME:
                    name = (*it_2).m_str;
                    break;
                case KIO::UDS_ACCESS:
                    is_exe = ((*it_2).m_long & MODE_EXE) != 0;
                    break;
                case KIO::UDS_FILE_TYPE:
                    is_dir = ((*it_2).m_long & S_IFDIR) != 0;
                    break;
                case KIO::UDS_URL:
                    url = (*it_2).m_str;
                    break;
            }
        }

        if(!url.isEmpty())
        {
            // kdDebug() << "KURLCompletion::slotEntries url: " << url << endl;
            name = KURL(url).fileName();
        }

        // kdDebug() << "KURLCompletion::slotEntries name: " << name << endl;

        if(name[0] == '.' && (d->list_urls_no_hidden || name.length() == 1 || (name.length() == 2 && name[1] == '.')))
            continue;

        if(d->mode == DirCompletion && !is_dir)
            continue;

        if(filter_len == 0 || name.left(filter_len) == filter)
        {
            if(is_dir)
                name.append('/');

            if(is_exe || !d->list_urls_only_exe)
                matches.append(name);
        }
    }

    addMatches(matches);
}
// . this was in Summary.cpp, but is more useful here
// . we can also use this to replace the proximity algo setup where it
//   fills in the matrix for title, link text, etc.
// . returns false and sets g_errno on error
bool Matches::set( Words *bodyWords, Phrases *bodyPhrases, Sections *bodySections, Bits *bodyBits,
				   Pos *bodyPos, Xml *bodyXml, Title *tt, Url *firstUrl, LinkInfo *linkInfo ) {
	// don't reset query info!
	reset2();

	// . first add all the matches in the body of the doc
	// . add it first since it will kick out early if too many matches
	//   and we get all the explicit bits matched
	if ( !addMatches( bodyWords, bodyPhrases, bodySections, bodyBits, bodyPos, MF_BODY ) ) {
		return false;
	}

	// add the title in
	if ( !addMatches( tt->getTitle(), tt->getTitleLen(), MF_TITLEGEN ) ) {
		return false;
	}

	// add in the url terms
	if ( !addMatches( firstUrl->getUrl(), firstUrl->getUrlLen(), MF_URL ) ) {
		return false;
	}

	// also use the title from the title tag, because sometimes it does not equal "tt->getTitle()"
	int32_t  a     = tt->getTitleTagStart();
	int32_t  b     = tt->getTitleTagEnd();

	char *start = NULL;
	char *end   = NULL;
	if ( a >= 0 && b >= 0 && b>a ) {
		start = bodyWords->getWord(a);
		end   = bodyWords->getWord(b-1) + bodyWords->getWordLen(b-1);
		if ( !addMatches( start, end - start, MF_TITLETAG ) ) {
			return false;
		}
	}

	// now add in the meta tags
	int32_t n = bodyXml->getNumNodes();
	XmlNode *nodes = bodyXml->getNodes();

	// find the first meta summary node
	for ( int32_t i = 0 ; i < n ; i++ ) {
		// continue if not a meta tag
		if ( nodes[i].m_nodeId != TAG_META ) continue;
		// only get content for <meta name=..> not <meta http-equiv=..>
		int32_t tagLen;
		char *tag = bodyXml->getString ( i , "name" , &tagLen );
		// is it an accepted meta tag?
		int32_t flag = 0;
		if (tagLen== 7&&strncasecmp(tag,"keyword"    , 7)== 0)
			flag = MF_METAKEYW;
		if (tagLen== 7&&strncasecmp(tag,"summary"    , 7)== 0)
			flag = MF_METASUMM;
		if (tagLen== 8&&strncasecmp(tag,"keywords"   , 8)== 0)
			flag = MF_METAKEYW;
		if (tagLen==11&&strncasecmp(tag,"description",11)== 0)
			flag = MF_METADESC;
		if ( ! flag ) continue;
		// get the content
		int32_t len;
		char *s = bodyXml->getString ( i , "content" , &len );
		if ( ! s || len <= 0 ) continue;
		// wordify
		if ( !addMatches( s, len, flag ) ) {
			return false;
		}
	}

	// . now the link text
	// . loop through each link text and it its matches

	// loop through the Inlinks
	Inlink *k = NULL;
	for ( ; (k = linkInfo->getNextInlink(k)) ; ) {
		// does it have link text? skip if not.
		if ( k->size_linkText <= 1 ) {
			continue;
		}

		// set the flag, the type of match
		mf_t flags = MF_LINK;

		// add it in
		if ( !addMatches( k->getLinkText(), k->size_linkText - 1, flags ) ) {
			return false;
		}

		// set flag for that
		flags = MF_HOOD;

		// add it in
		if ( !addMatches( k->getSurroundingText(), k->size_surroundingText - 1, flags ) ) {
			return false;
		}

		// parse the rss up into xml
		Xml rxml;
		if ( ! k->setXmlFromRSS ( &rxml ) ) {
			return false;
		}

		// add rss description
		bool isHtmlEncoded;
		int32_t rdlen;
		char *rd = rxml.getRSSDescription( &rdlen, &isHtmlEncoded );
		if ( !addMatches( rd, rdlen, MF_RSSDESC ) ) {
			return false;
		}

		// add rss title
		int32_t rtlen;
		char *rt = rxml.getRSSTitle( &rtlen, &isHtmlEncoded );
		if ( !addMatches( rt, rtlen, MF_RSSTITLE ) ) {
			return false;
		}
	}

	// that should be it
	return true;
}
bool
NavSearchHandler::handleSearch( UserItem* userItem, 
                                NavRequestPacket* req, 
                                NavReplyPacket* reply )
{
   if ( !checkExpectations( req->getParamBlock(), reply ) ) {
      return false;
   }
   bool ok = true;

   uint32 startTime = TimeUtility::getCurrentTime();
   uint32 now = TimeUtility::getRealTime();

   // The params
   const NParamBlock& params = req->getParamBlock();
   NParamBlock& rparams = reply->getParamBlock();
   // The user
   UserUser* user = userItem->getUser();

   const ClientSetting* clientSetting = 
      m_userHelp->getClientSetting( params, user );
   UserEnums::URType urmask = m_userHelp->getUrMask( clientSetting );

   // Start parameter printing
   mc2log << info << "handleSearch:";

   // Language
   StringTable::languageCode language = user->getLanguage();
   if ( params.getParam( 6 ) ) {
      language = NavUtil::mc2LanguageCode( 
         params.getParam( 6 )->getUint16() );
      mc2log << " Lang " << StringTable::getString( 
         StringTable::getLanguageAsStringCode( language ), 
         StringTable::ENGLISH );
   }

   SearchRequestParameters searchParams;
   searchParams.setTryHarder( true );
   searchParams.setLookupCoordinates( true  );
   searchParams.setAddStreetNamesToCompanies( true );
   searchParams.setSearchForTypes( user->getSearchForTypes() );
   searchParams.setSearchForLocationTypes( 
      user->getSearchForLocationTypes() );
   searchParams.setMatchType( SearchTypes::StringMatching( 
                                 user->getSearch_type() ) );
   searchParams.setStringPart( SearchTypes::StringPart( 
                                  user->getSearch_substring() ) );
   searchParams.setSortingType( SearchTypes::DistanceSort );
   searchParams.setRequestedLang( language );
   SearchRequestParameters areaSearchParams( searchParams );
   
   // Start index
   uint16 areaStartIndex = 0;
   uint16 itemStartIndex = 0;
   if ( params.getParam( 1200 ) ) {
      areaStartIndex = params.getParam( 1200 )->getUint16Array( 0 );
      itemStartIndex = params.getParam( 1200 )->getUint16Array( 1 );
      mc2log << " IN " << areaStartIndex << "," << itemStartIndex;
   }

   // Search area string
   MC2String areaStrStr;
   const char* areaStr = NULL;
   if ( params.getParam( 1201 ) ) {
      areaStrStr = params.getParam( 1201 )->getString(
         m_thread->clientUsesLatin1() );
      areaStr = areaStrStr.c_str();
      mc2log << " A " << areaStr;
   }

   // Search AreaID
   MC2String areaIDStr;
   const char* areaID = NULL;
   if ( params.getParam( 1202 ) ) {
      areaIDStr = params.getParam( 1202 )->getString(
         m_thread->clientUsesLatin1());
      areaID = areaIDStr.c_str();
      mc2log << " SA " << areaID;
   }

   // Search item string
   MC2String itemStr;
   if ( params.getParam( 1203 ) ) {
      itemStr = StringUtility::trimStartEnd( 
         params.getParam( 1203 )->getString(
            m_thread->clientUsesLatin1() ) );
      mc2log << " I " << itemStr;
   }

   // Search category
   MC2String categoryStr;
   if ( params.getParam( 1204 ) ) {
      categoryStr = params.getParam( 1204 )->getString(
         m_thread->clientUsesLatin1() );
      mc2log << " C " << categoryStr;
      SearchParserHandler::Category cat = 
         m_thread->getSearchHandler().
         findCategoryFromListLowerCase( categoryStr );
      if ( cat == SearchParserHandler::INVALID_CATEGORY ) {
         // do old style search
         searchParams.setMatchType( SearchTypes::FullMatch );
      } else {
         // set category id and do a faster new category search.
         set<SearchParserHandler::Category::CategoryID> categories;
         categories.insert( cat.getCategoryID() );
         searchParams.setCategories( categories );
         // must clear it to search all categories.
         categoryStr.clear();
         itemStr.clear();
      }

   }

   // TopRegionID
   uint32 topRegionID = MAX_UINT32;
   if ( params.getParam( 1205 ) ) {
      topRegionID = params.getParam( 1205 )->getUint32();
      mc2log << " TID " << MC2HEX( topRegionID );
   }

   // Search pos
   MC2Coordinate searchPos;
   if ( params.getParam( 1206 ) ) {
      searchPos = MC2Coordinate( 
         Nav2Coordinate( params.getParam( 1206 )->getInt32Array( 0 ),
                         params.getParam( 1206 )->getInt32Array( 1 ) ) );
      mc2log << " Pos " << searchPos;//.lat << ", " << searchPos.lon;
   }

   // Max Nbr Search Matches
   uint32 maxNbrMatches = 10;
   if ( params.getParam( 1207 ) ) {
      maxNbrMatches = params.getParam( 1207 )->getUint16();
      mc2log << " MAX " << maxNbrMatches;
   }

   // Sorting
   if ( params.getParam( 1208 ) ) {
      areaSearchParams.setSortingType( 
         mc2SortType( params.getParam( 1208 )->getByteArray()[ 0 ] ) );
      searchParams.setSortingType( 
         mc2SortType( params.getParam( 1208 )->getByteArray()[ 1 ] ) );
      mc2log << " AS " << SearchTypes::getSortingString( 
                areaSearchParams.getSortingType() ) << " IS " 
             << SearchTypes::getSortingString( 
                searchParams.getSortingType() );
   }

   // End parameter printing
   mc2log << endl;

   // AURA
   set< uint32 >* allowedMaps = NULL;
   if ( ok && !m_thread->getMapIdsForUserRegionAccess( user, allowedMaps,
                                                       now, urmask ) )
   {
      mc2log << warn << "handleSearch: getMapIdsForUserRegionAccess"
             << " failed. ";
      if ( TimeUtility::getCurrentTime() - startTime > 3000 ) {
         reply->setStatusCode( 
            NavReplyPacket::NAV_STATUS_REQUEST_TIMEOUT );
         mc2log << "Timeout";
      } else {
         reply->setStatusCode( NavReplyPacket::NAV_STATUS_NOT_OK );
         mc2log << "Error";
      }
      mc2log << endl;
      ok = false;
   }

   // Store user position
   if ( ok && searchPos.isValid() ) {
      m_userHelp->storeUserPosition( user->getUIN(), searchPos, "Search" );
   }


   // Do we have selected location?
   SearchMatch* selectedArea = NULL;
   if ( areaID != NULL ) {
      selectedArea = SearchMatch::createMatch( areaID );
      if ( selectedArea == NULL ) {
         mc2log << warn << "handleSearch: Bad areaID " 
                << MC2CITE( areaID ) << endl;
         ok = false;
         reply->setStatusCode( 
            NavReplyPacket::NAV_STATUS_PARAMETER_INVALID );
         reply->setStatusMessage( "Search AreaID" );
      } else {
         // Check if area is in allowed maps
         if ( allowedMaps != NULL && allowedMaps->find( 
                 selectedArea->getMapID() ) == allowedMaps->end() )
         {
            mc2log << warn << "handleSearch: selected area unallowed map "
                   << MC2CITE( areaID ) << endl;
            ok = false;
            reply->setStatusCode( 
               NavReplyPacket::NAV_STATUS_OUTSIDE_ALLOWED_AREA );
         }
      }
   }

   // Which item search string
   MC2String searchString;
   if ( categoryStr.length() > 0 ) {
      searchString = categoryStr;
   } else if ( itemStr.length() > 0 ) {
      searchString = itemStr;
   }
   bool searchForArea = true;

   // Search!
   if ( ok ) {
      SearchResultRequest* sr = NULL;
      RequestData reqID = m_thread->getNextRequestID();

      if ( selectedArea != NULL ) {
         vector < IDPair_t > selectedAreas;
         selectedAreas.push_back( selectedArea->getID() );

         SearchRequest* s = new SearchRequest( 
            reqID, searchParams, selectedAreas, searchString.c_str(),
            m_thread->getTopRegionRequest(),
            searchPos, &areaSearchParams );
         s->setAllowedMaps( allowedMaps );
         sr = s;
         searchForArea = false;
      } else {
         // Get topRegionID from position and check position if proximity
         if ( topRegionID == MAX_UINT32 || areaStr == NULL ) {
            if ( searchPos.isValid() ) {
               CoordinateRequest* navReq = new 
                  CoordinateRequest( m_thread->getNextRequestID(),
                                     m_thread->getTopRegionRequest());
               const byte itemType = ItemTypes::streetSegmentItem;
               navReq->addCoordinate( 
                  searchPos.lat, searchPos.lon,
                  ( COORDINATE_PACKET_RESULT_ANGLE |
                    COORDINATE_PACKET_RESULT_STRINGS |
                    COORDINATE_PACKET_RESULT_IDS ), 1, &itemType);
               m_thread->putRequest( navReq );
               CoordinateReplyPacket* crp = navReq->getCoordinateReply();
               if ( crp == NULL || crp->getStatus() != StringTable::OK ) {
                  // We have an error report it to the user!
                  mc2log << warn << "handleSearch: Lookup of pos falied ";
                  uint8 errorCode = NavReplyPacket::NAV_STATUS_NOT_OK;
                  if ( crp != NULL ) {
                     if ( crp->getStatus() == StringTable::MAPNOTFOUND ) {
                        mc2log << "OUTSIDE_MAP";
                        errorCode = NavReplyPacket::NAV_STATUS_OUTSIDE_MAP;
                     } else {
                        mc2log << "NOT_OK";
                        errorCode = NavReplyPacket::NAV_STATUS_NOT_OK;
                     }
                  } else {
                     if ( TimeUtility::getCurrentTime() - startTime > 3000 ) {
                        mc2log << "REQUEST_TIMEOUT";
                        errorCode = 
                           NavReplyPacket::NAV_STATUS_REQUEST_TIMEOUT;
                     } else {
                        mc2log << "Reply null NOT_OK";
                        errorCode = NavReplyPacket::NAV_STATUS_NOT_OK;
                     }
                  }
                  mc2log << endl;
                  reply->setStatusCode( errorCode );
                  ok = false;
               } else { // Reply is ok
                  const TopRegionRequest* topRegReq = 
                     m_group->getTopRegionRequest( &*m_thread );

                  // Note that the topRegionID is a topRegionID - not CC.
                  if ( topRegionID == MAX_UINT32 ) {
                     // Find the topRegionMatch of type country.
                     const TopRegionMatch* topReg =
                        topRegReq->getCountryForMapID( crp->getMapID() );
                     if ( topReg != NULL ) {
                        topRegionID = topReg->getID();
                     }
                  }
               }
               delete navReq;
            } else if ( topRegionID != MAX_UINT32 && areaStr == NULL ) {
               // Have topregion and proximity search but no pos is ok now
            } else {
               mc2log << warn << "handleSearch: not valid pos";
               if ( topRegionID == MAX_UINT32 ) {
                  mc2log << " for unknown topRegionID ";
               }
               if ( areaStr == NULL ) {
                  mc2log << " for proximity ";
               }
               mc2log << endl;
               ok = false;
               reply->setStatusCode( 
                  NavReplyPacket::NAV_STATUS_MISSING_PARAMETER );
               reply->setStatusMessage( "Search Position" );
            }
         } // End if needs to lookup pos


         if ( ok ) {
            if ( areaStr != NULL ) {
               // Check if topRegionID is in allowed regions
               if ( m_thread->checkUserRegionAccess( topRegionID, user,
                                                     urmask ) )
               {
                  sr = new SearchRequest( 
                     reqID, searchParams, topRegionID, areaStr,
                     searchString.c_str(), m_thread->getTopRegionRequest(),
                     searchPos, &areaSearchParams );
               } else {
                  mc2log << warn << "handleSearch: selected topRegionID "
                         << hex << topRegionID << dec << " not allowed."
                         << endl;
                  ok = false;
                  reply->setStatusCode( 
                     NavReplyPacket::NAV_STATUS_OUTSIDE_ALLOWED_AREA );
               }
            } else { // Search around position
               // Will search the whole country.
               if ( searchPos.isValid() ) {
                  sr = new ClosestSearchRequest( 
                     reqID, searchParams, searchPos, searchString,
                     m_thread->getTopRegionRequest(),
                     allowedMaps ? *allowedMaps : set<uint32>() );
               } else if ( topRegionID != MAX_UINT32 ) {
                  if ( m_thread->checkUserRegionAccess( topRegionID, 
                                                        user, urmask ) )
                  {
                     sr = new ClosestSearchRequest( 
                        reqID, searchParams, topRegionID, searchString,
                        m_thread->getTopRegionRequest(),
                        allowedMaps ? *allowedMaps : set<uint32>() );
                  } else {
                     mc2log << warn << "handleSearch: proximity: selected "
                            << "topRegionID " << hex << topRegionID << dec
                            << " not allowed." << endl;
                     ok = false;
                     reply->setStatusCode( 
                        NavReplyPacket::NAV_STATUS_OUTSIDE_ALLOWED_AREA );
                  }
               } else {
                  mc2log << warn << "handleSearch: not valid pos nor "
                         << "topRegion ";
                  mc2log << endl;
                  ok = false;
                  reply->setStatusCode( 
                     NavReplyPacket::NAV_STATUS_MISSING_PARAMETER );
                  reply->setStatusMessage( 
                     "Search Position or TopRegion" );
               }
               searchForArea = false;
            }
         }
         
      } // End else if have selected search area
      
      if ( ok ) {
         m_thread->putRequest( sr );

         // Check sr
         mc2log << info << "handleSearch: Reply:";
         if ( sr->getStatus() != StringTable::OK ) {
            if ( sr->getStatus() == StringTable::TIMEOUT_ERROR ) {
               mc2log << " REQUEST_TIMEOUT";
               reply->setStatusCode( 
                  NavReplyPacket::NAV_STATUS_REQUEST_TIMEOUT );
            } else if ( sr->getStatus() == 
                        StringTable::OUTSIDE_ALLOWED_AREA )
            {
               mc2log << " OUTSIDE_ALLOWED_AREA";
               reply->setStatusCode( 
                  NavReplyPacket::NAV_STATUS_OUTSIDE_ALLOWED_AREA );
            } else { 
               mc2log << " NOT_OK";
               reply->setStatusCode( NavReplyPacket::NAV_STATUS_NOT_OK );
            }
         } else {
            // Add the result
            addMatches( rparams, sr, searchForArea, maxNbrMatches, 
                        areaStartIndex, itemStartIndex, 1302, 
                        1303, 1300, 1304, 1301 );
         } // End else sr is ok
         mc2log << endl;
         
         PacketContainer* searchAnswer = sr->getAnswer();
         
         // Debit search
         MC2String extraInfo = m_userHelp->makeExtraUserInfoStr( params );
         if ( !m_thread->getDebitHandler()->makeSearchDebit( 
                 userItem, sr, searchAnswer, areaStr,
                 searchString.c_str(), extraInfo.c_str() ) )
         {
            mc2log << warn << "handleSearch: debit failed." << endl;
         }


         delete searchAnswer;
         delete sr->getAnswer();
         delete sr;
      } // End if ok
   } // End if ok


   delete allowedMaps;
   delete selectedArea;

   return ok;
}