diff options
Diffstat (limited to 'src/kio_locate.cpp')
-rw-r--r-- | src/kio_locate.cpp | 1036 |
1 files changed, 0 insertions, 1036 deletions
diff --git a/src/kio_locate.cpp b/src/kio_locate.cpp deleted file mode 100644 index 9f39be8..0000000 --- a/src/kio_locate.cpp +++ /dev/null @@ -1,1036 +0,0 @@ -/*************************************************************************** - * kio-locate: KDE I/O Slave for the locate command * - * * - * Copyright (C) 2005 by Tobi Vollebregt * - * tobivollebregt@gmail.com * - * * - * Thanks to Google's Summer Of Code Program! * - * * - * Copyright (C) 2004 by Armin Straub * - * linux@arminstraub.de * - * * - * This program was initially written by Michael Schuerig. * - * Although I have completely rewritten it, most ideas are adopted * - * from his original work. * - * * - * Copyright (C) 2002 by Michael Schuerig * - * michael@schuerig.de * - * * - * * - * 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. * - ***************************************************************************/ - -#include <algorithm> -#include <stdlib.h> -#include <sys/stat.h> -#include <pwd.h> -#include <grp.h> - -#include <kapplication.h> -#include <tdeconfigdialog.h> -#include <kdebug.h> -#include <kde_file.h> -#include <kiconloader.h> -#include <klocale.h> -#include <kurl.h> -#include <kuser.h> -#include <tqfile.h> - -#include "kio_locate.h" -#include "klocateconfig.h" -#include "klocateconfigwidget.h" -#include "klocateconfigfilterwidget.h" -#include "klocateconfiglocatewidget.h" - -using namespace TDEIO; - - -static const TQString queryQuery = "q"; -static const TQString queryDirectory = "directory"; -static const TQString queryCase = "case"; -static const TQString queryRegExp = "regexp"; - -static const TQString iconToStringTable[] = { - "folder", "folder_green", "folder_grey", "folder_orange", - "folder_red", "folder_violet", "folder_yellow" -}; - - -///////////////////////////////////////////////////////////////////// -// HELPERS - -/** - * Determines if a string contains unescaped wildcard characters. - * Currently, wildcard characters are: * + ? [ ] - * For older versions of Konqueror: + behaves identical to * - * @param s the string to inspect - */ -static bool hasWildcards(const TQString& s) -{ - for (unsigned int i = 0; i < s.length(); ++i) { - if ((s[i] == '*' || s[i] == '+' || s[i] == '?' || s[i] == '[' || s[i] == ']') && (i < 1 || s[i-1] != '\\')) - return true; - } - return false; -} - - -/** - * Converts a string containing shell wildcard characters (globbing characters) - * to a regular expression. This function takes care of escaped wildcards and - * any regexp special characters which happen to be in the string. - * @param s the string to convert - * @return the converted string - */ -static TQString convertWildcardsToRegExp(TQString s) -{ - bool in_set = false; - - // No support for regexp searches. - // (Konqueror makes passing chars like "/" almost impossible anyway.) - // Note that this converts actual wildcards to escaped wildcards (\wildcard), - // and escaped wildcards to 'triple'-escaped wildcards (\\\wildcard). - s = TQRegExp::escape(s); - - // Walk through the string, converting \wildcard to regexp and - // \\\wildcard back to \wildcard. - for (unsigned i = 1; i < s.length(); ++i) { - //DEBUGSTR << s.left(i+1) << endl; - if (i < 3 || s[i-3] != '\\' || s[i-2] != '\\') { - // If it was an unescaped character (now possibly escaped once) - if (s[i-1] == '\\') { - // If it actually was escaped once - if (!in_set) { - // If it's NOT inside a character set, we need to convert *?[ - if (s[i] == '*' || s[i] == '+') { - s = s.left(i-1) + "[^/]*" + s.mid(i+1); - i += 3; // 3 == strlen("[^/]*")-strlen("\\*") - } else if (s[i] == '?') { - s = s.left(i-1) + "[^/]" + s.mid(i+1); - i += 2; // 2 == strlen("[^/]")-strlen("\\*") - } else if (s[i] == '[') { - s = s.left(i-1) + s.mid(i); - --i; - in_set = true; - } - } else { - // If it's inside a character set, we need to convert ]^ - // and to unescape everything else. - if (s[i] == ']') { - s = s.left(i-1) + s.mid(i); - --i; - in_set = false; - } else if (s[i] == '^' && i >= 2 && s[i-2] == '[') { - s = s.left(i-1) + s.mid(i); - --i; - } else { - s = s.left(i-1) + s.mid(i); - } - } - } - } else { - // If it's an escaped character, remove the extra escape characters. - s = s.left(i-3) + s.mid(i-1); - i -= 2; // 2 == strlen("\\\\")-strlen("") - } - } - return s; -} - - -/** - * Determines if path includes a trailing slash. - * @param path the path to inspect - */ -static bool hasTrailingSlash(const TQString& path) -{ - int n = path.length(); - return ((n > 0) && (path[n-1] == '/')); -} - - -/** - * Strips a trailing slash / from a path. - * @param path the path to strip the slash off - */ -static TQString stripTrailingSlash(const TQString& path) -{ - int n = path.length(); - if ((n > 0) && (path[n-1] == '/')) { - return path.left(n-1); - } - return path; -} - - -/** - * Add a trailing slash / to a path if there is none yet. - * @param path the path to append the slash to - */ -static TQString addTrailingSlash(const TQString& path) -{ - int n = path.length(); - if ((n > 0) && (path[n-1] == '/')) { - return path; - } - return path + '/'; -} - - -static void addAtom(UDSEntry& entry, unsigned int uds, const TQString& s) -{ - UDSAtom a; - a.m_uds = uds; - a.m_str = s; - entry.append(a); -} - - -static void addAtom(UDSEntry& entry, unsigned int uds, long long l) -{ - UDSAtom a; - a.m_uds = uds; - a.m_long = l; - entry.append(a); -} - - -static const UDSEntry pathToUDSEntry(const TQString& path, const TQString& display, - const TQString& url = TQString(), const TQString& icon = TQString()) -{ - UDSEntry entry; - addAtom(entry, TDEIO::UDS_NAME, display); - - if (!path.isEmpty()) { - KDE_struct_stat info; - KDE_lstat(path.local8Bit(), &info); - - addAtom(entry, TDEIO::UDS_SIZE, info.st_size); - addAtom(entry, TDEIO::UDS_ACCESS, info.st_mode); - addAtom(entry, TDEIO::UDS_MODIFICATION_TIME, info.st_mtime); - addAtom(entry, TDEIO::UDS_ACCESS_TIME, info.st_atime); - addAtom(entry, TDEIO::UDS_CREATION_TIME, info.st_ctime); - - struct passwd * user = getpwuid(info.st_uid); - struct group * group = getgrgid(info.st_gid); - addAtom(entry, TDEIO::UDS_USER, ((user != NULL) ? user->pw_name : "???" )); - addAtom(entry, TDEIO::UDS_GROUP, ((group != NULL) ? group->gr_name : "???" )); - - if (url.isEmpty()) { - // List an existing file. - addAtom(entry, TDEIO::UDS_URL, "file:" + path); - - mode_t type = info.st_mode; - if (S_ISLNK(type)) { - TQString slink = TQString(); - char buff[1000]; - int n = readlink(path.ascii(), buff, 1000); - if (n != -1) { - buff[n] = 0; - slink = buff; - } - addAtom(entry, TDEIO::UDS_LINK_DEST, slink); - } else { - type &= S_IFMT; - } - addAtom(entry, TDEIO::UDS_FILE_TYPE, type); - -#ifdef HAVE_UDS_HIDDEN - if (path.contains("/.")) { - addAtom(entry, TDEIO::UDS_HIDDEN, 1); - } -#endif - } else { - // List a locate link. - addAtom(entry, TDEIO::UDS_URL, url); - addAtom(entry, TDEIO::UDS_FILE_TYPE, S_IFDIR); - } - } else { - addAtom(entry, TDEIO::UDS_URL, url); - } - - if (!icon.isEmpty()) { - addAtom(entry, TDEIO::UDS_ICON_NAME, icon); - } - - return entry; -} - - -///////////////////////////////////////////////////////////////////// -// INITIALIZATION - -LocateProtocol::LocateProtocol(const TQCString &pool_socket, const TQCString &app_socket) - : SlaveBase("kio_locate", pool_socket, app_socket) -{ - DEBUGSTR << "LocateProtocol::LocateProtocol()" << endl; - - connect(&m_locater, TQT_SIGNAL(found(const TQStringList&)), - this, TQT_SLOT(processLocateOutput(const TQStringList&))); - connect(&m_locater, TQT_SIGNAL(finished()), - this, TQT_SLOT(locateFinished())); - - m_baseDir = NULL; - m_curDir = NULL; -} - - -LocateProtocol::~LocateProtocol() -{ - DEBUGSTR << "LocateProtocol::~LocateProtocol()" << endl; - - delete m_baseDir; -} - - -const LocateRegExp& LocateProtocol::getRegExp() const -{ - return m_locateRegExp; -} - - -int LocateProtocol::getCollapseDirectoryThreshold() const -{ - return m_config.m_collapseDirectoryThreshold; -} - - -///////////////////////////////////////////////////////////////////// -// KIO STUFF - -void LocateProtocol::setUrl(const KURL& url) -{ - if (url.protocol() != "locater") { - TQString pattern = KURL::decode_string(url.url()); - pattern = pattern.mid(url.protocol().length() + 1); - - KURL newUrl; - newUrl.setProtocol("locater"); - - if (pattern.isEmpty() || pattern == "/") { - // Give help. - newUrl.setPath("help"); - } else if (hasTrailingSlash(pattern)) { - // Detect auto-completion from within konqueror and "stop" - // this search. - newUrl.setPath("autosearch"); - newUrl.addQueryItem(queryQuery, pattern); - } else if (url.protocol() == "rlocate") { - // Standard regexp search. - newUrl.setPath("search"); - newUrl.addQueryItem(queryQuery, pattern); - newUrl.addQueryItem(queryRegExp, "1"); - } else { - // Standard wildcard search. - newUrl.setPath("search"); - newUrl.addQueryItem(queryQuery, pattern); - } - m_url = newUrl; - - DEBUGSTR << "Redirect: " << m_url << endl; - } else { - m_url = url; - } - // Perhaps this will be unneccessary most times, but who knows... - updateConfig(); -} - -void LocateProtocol::get(const KURL& url) -{ - DEBUGSTR << "LocateProtocol::get(" << url << ")" << endl; - - setUrl(url); - - if (isSearchRequest()) { - if (m_locater.binaryExists()) { - error(TDEIO::ERR_IS_DIRECTORY, TQString()); - } else { - TQString html = i18n("<h1>\"%1\" could not be started.</h1><p>Please note that kio-locate can't be used on its own. You need an additional program for doing searches. Typically this is the command line tool <i>locate</i> that can be found in many distributions by default. You can check if the correct tool is used by looking at the <a href=\"locater:config\">setting</a> \"Locate Binary\".<p>Besides the mentioned tool <i>locate</i>, kio-locate can use any tool that uses the same syntax. In particular, it was reported to work with <i>slocate</i> and <i>rlocate</i>.").arg(m_locater.binary()); - outputHtml(html); - } - } else if (isConfigRequest()) { - configRequest(); - } else if (isHelpRequest()) { - helpRequest(); - } else { - // What's this? - error(TDEIO::ERR_DOES_NOT_EXIST, TQString()); - } -} - - -void LocateProtocol::stat(const KURL& url) -{ - DEBUGSTR << "LocateProtocol::stat(" << url << ")" << endl ; - - setUrl(url); - - if (isSearchRequest() || isConfigRequest() || isHelpRequest()) { - bool isDir = isSearchRequest() && m_locater.binaryExists(); - /// \todo Is UDS_NAME used for anything in stat? If so we should - /// at least strip of the protocol part. - UDSEntry entry; - addAtom(entry, TDEIO::UDS_NAME, url.decode_string(url.url())); - addAtom(entry, TDEIO::UDS_FILE_TYPE, isDir ? S_IFDIR : S_IFREG); - statEntry(entry); - finished(); - /// \todo Somehow locate: and locate:/ is thought to be a directory - /// by konqueror anyway. How to change this? - } else { - // What's this? - error(TDEIO::ERR_DOES_NOT_EXIST, TQString()); - } -} - - -void LocateProtocol::listDir(const KURL& url) -{ - DEBUGSTR << "LocateProtocol::listDir(" << url << ")" << endl ; - - setUrl(url); - - if (isSearchRequest()) { - searchRequest(); - } else if (isConfigRequest() || isHelpRequest()) { - error(TDEIO::ERR_IS_FILE, TQString()); - } else { - // What's this? - error(TDEIO::ERR_DOES_NOT_EXIST, TQString()); - } -} - - -void LocateProtocol::mimetype(const KURL& url) -{ - DEBUGSTR << "LocateProtocol::mimetype(" << url << ")" << endl ; - - setUrl(url); - - if (isSearchRequest()) { - if (m_locater.binaryExists()) { - mimeType("inode/directory"); - } else { - mimeType("text/html"); - } - } else if (isConfigRequest() || isHelpRequest()) { - mimeType("text/html"); - } - finished(); -} - - -void LocateProtocol::outputHtml(const TQString& body) -{ - mimeType("text/html"); - - TQString theData = "<html><body>" + body + "</body></html>"; - data(theData.local8Bit()); - finished(); -} - - -///////////////////////////////////////////////////////////////////// -// SEARCHING - -bool LocateProtocol::isSearchRequest() -{ - return m_url.path() == "search"; -} - - -void LocateProtocol::searchRequest() -{ - // Reset old values. - m_caseSensitivity = caseAuto; - m_useRegExp = false; - m_locatePattern = TQString(); - m_locateDirectory = TQString(); - m_regExps.clear(); - m_pendingPath = TQString(); - - delete m_baseDir; - m_baseDir = NULL; - m_curDir = NULL; - - updateConfig(); - - TQString query = m_url.queryItem(queryQuery); - m_locateDirectory = addTrailingSlash(m_url.queryItem(queryDirectory)); - - TQString caseSensitivity = m_url.queryItem(queryCase); - if (caseSensitivity == "sensitive") { - m_caseSensitivity = caseSensitive; - } else if (caseSensitivity == "insensitive") { - m_caseSensitivity = caseInsensitive; - } - - TQString useRegExp = m_url.queryItem(queryRegExp); - if (!useRegExp.isEmpty() && useRegExp != "0") { - m_useRegExp = true; - } - - // Split query into components. The first component is the query - // for locate. The others are filtering regular expressions. They are - // delimited by (not escaped) whitespace. - // If the last component starts with two backslahes \\, then the search - // is only to be done within the directory following them. - query = query.simplifyWhiteSpace(); - int s = 0; - int n = query.length(); - bool regexp; - TQString display; - for (int i = 0; i <= n; i++) { - if ((i == n) || ((query[i] == ' ') && (i > 0) - && (query[i-1] != '\\') && (i-s > 0))) { - TQString temp = query.mid(s, i-s); - TQString part = partToPattern(temp, s==0); - if (s == 0) { - // We don't want to show the escaped regexpified string to - // the user, so we store the string we get in for later display. - display = temp; - // This is the same check as in partToPattern. - // ie. regexp is used if locate pattern contains wildcards, - // or regexp searching was enabled. - regexp = hasWildcards(temp); - m_locatePattern = part; - } else { - // For each regular expression determine if it should be - // case sensitive. - m_regExps += LocateRegExp(part, !isCaseSensitive(part)); - } - s = i+1; - } - } - - DEBUGSTR << "Pattern: " << m_locatePattern << endl; - DEBUGSTR << "Directory: " << m_locateDirectory << endl; - - // We set up the regexp used to see whether the match was in the - // directory part or the filename part of a path. - m_locateRegExp = LocateRegExp(convertWildcardsToRegExp(m_locatePattern), !isCaseSensitive(m_locatePattern)); - - // Now perform the search... - infoMessage(i18n("Locating %1 ...").arg(display)); - - bool started = m_locater.locate(m_locatePattern, !isCaseSensitive(m_locatePattern), regexp); - - if (!started) { - DEBUGSTR << "Locate could not be found." << endl; - finished(); - } -} - - -bool LocateProtocol::isCaseSensitive(const TQString& text) -{ - if (m_caseSensitivity == caseSensitive) { - return true; - } else if (m_caseSensitivity == caseInsensitive) { - return false; - } else if (m_config.m_caseSensitivity == caseSensitive) { - return true; - } else if (m_config.m_caseSensitivity == caseInsensitive) { - return false; - } else { - return text != text.lower(); - } -} - - -void LocateProtocol::addHit(const TQString& path, int subItems) -{ - // DEBUGSTR << "LocateProtocol::addHit( " << path << ", " << subItems << " )" << endl; - if (TQFile::exists(path)) { - if (subItems > 0) { - m_entries += pathToUDSEntry(path, pathToDisplay(path, subItems), makeLocaterUrl(path), iconToStringTable[m_config.m_collapsedIcon]); - } else { - m_entries += pathToUDSEntry(path, pathToDisplay(path)); - } - } -} - - -void LocateProtocol::addPreviousLocateOutput() -{ - if (m_baseDir == NULL) { - return; - } - // m_baseDir->debugTrace(); - if (m_locateDirectory == "/") { - // Allow toplevel directories to collapse (e.g. when locating "/usr/"). - m_baseDir->prepareListing(this, 0); - } else { - m_baseDir->prepareListing(this, m_locateDirectory.length()); - } - m_baseDir->listItems(this); - delete m_baseDir; - m_baseDir = NULL; - m_curDir = NULL; - - listEntries(m_entries); - m_entries.clear(); -} - - -void LocateProtocol::processPath(const TQString &path, const TQString &nextPath) -{ - if (!nextPath) { - // We need to know the next path, so we remember this path for later processing. - m_pendingPath = path; - } else if (!nextPath.startsWith(path + '/')) { - if (isMatching(path)) { - if ((m_baseDir != NULL) && !path.startsWith(m_baseDir->m_path)) { - addPreviousLocateOutput(); - } - // Add path to current directory. - if (m_baseDir == NULL) { - int p = path.find('/', 1); - TQString base = path; - if (p >= 0) { - base = path.left(p+1); - } - m_baseDir = new LocateDirectory(NULL, base); - m_curDir = m_baseDir; - } - m_curDir = m_curDir->addPath(path); - } - } -} - - -void LocateProtocol::processLocateOutput(const TQStringList& items) -{ - // I don't know if this really necessary, but if we were signaled, we'll - // better stop. - if (wasKilled()) { - m_locater.stop(); - return; - } - // Go through what we have found. - TQStringList::ConstIterator it = items.begin(); - if (!m_pendingPath.isNull()) { - processPath(m_pendingPath, *it); - m_pendingPath = TQString(); - } - for (; it != items.end();) { - TQString path = *it; - ++it; - processPath(path, it != items.end() ? *it : TQString()); - } -} - - -void LocateProtocol::locateFinished() -{ - // Add any pending items. - if (!m_pendingPath.isNull()) { - processPath(m_pendingPath, ""); - m_pendingPath = TQString(); - } - addPreviousLocateOutput(); - - DEBUGSTR << "LocateProtocol::locateFinished" << endl; - infoMessage(i18n("Finished.")); - finished(); -} - - -TQString LocateProtocol::partToPattern(const TQString& part, bool forLocate) -{ - DEBUGSTR << "BEG part: " << part << endl; - TQString pattern = part; - // Unescape whitespace. - pattern.replace("\\ ", " "); - // Unquote quoted pattern. - int n = pattern.length(), index; - if ((n > 1) && (pattern[0] == '"') && (pattern[n-1] == '"')) { - pattern = pattern.mid(1, n-2); - } - - // We can't do regular expression matching on the locate pattern, - // the regular expression format used by locate is incompatible - // with the format used by TQRegExp. - if (!m_useRegExp || forLocate) { - // Escape regexp characters for filtering pattern, and for locate, - // but the latter only if it is actually necessary to pass a regexp to locate. - // (ie. the pattern contains wildcards.) - if (!forLocate || hasWildcards(pattern)) { - pattern = convertWildcardsToRegExp(pattern); - } else { - // Special case for locate pattern without wildcards: - // Unescape all escaped wildcards. - pattern.replace("\\*", "*"); - pattern.replace("\\+", "+"); - pattern.replace("\\?", "?"); - pattern.replace("\\[", "["); - pattern.replace("\\]", "]"); - } - } - - // Special treatment for the pattern used for locate: - if (forLocate) { - // Replace ~/ and ~user/ at the beginning (as the shell does) - if ((pattern.length() > 0) && (pattern[0] == '~')) { - index = pattern.find('/'); - if (index >= 0) { - TQString name = pattern.mid(1, index-1); - TQString homeDir; - if (name.isEmpty()) { - homeDir = KUser(KUser::UseRealUserID).homeDir(); - } else { - homeDir = KUser(name).homeDir(); - } - if (!homeDir.isEmpty()) { - pattern.replace(0, index, homeDir); - } - } - } - pattern.replace("\\~", "~"); - } - DEBUGSTR << "END part: " << pattern << endl; - return pattern; -} - - -bool LocateProtocol::isMatching(const TQString& path) -{ - // The file has to belong to our directory. - if (!path.startsWith(m_locateDirectory)) { - return false; - } - // And it has to match at least one regular expression in the whitelist. - if (!m_config.m_whiteList.isMatchingOne(path)) { - return false; - } - // And it may not match any regular expression in the blacklist. - if (m_config.m_blackList.isMatchingOne(path)) { - return false; - } - // And it has to match against all regular expressions specified in the URL. - if (!m_regExps.isMatchingAll(path)) { - return false; - } - // And it must not solely match m_locateDirectory. - return m_locateRegExp.isMatching(path.mid(m_locateDirectory.length())); -} - - -TQString LocateProtocol::pathToDisplay(const TQString& path, int subItems) -{ - // Split off the directory part. If it is not just the minimal '/'. - TQString display = path; - if ((m_locateDirectory != "/") && display.startsWith(m_locateDirectory)) { - display = display.mid(m_locateDirectory.length()); - } - if (subItems > 0) { - // Can't use m_collapsedDisplay.arg(subItems).arg(display); here - // because user might forget to type %1 or %2, or type it twice. - // In both cases the result of arg() is undefined. - TQString output = m_config.m_collapsedDisplay, temp; - temp.setNum(subItems); - output.replace("%1", temp); - output.replace("%2", display); - display = output; - } - return display; -} - - -TQString LocateProtocol::makeLocaterUrl(const TQString& directory) -{ - KURL url(m_url); - url.removeQueryItem(queryDirectory); - url.addQueryItem(queryDirectory, directory); - return url.url(); -} - - -///////////////////////////////////////////////////////////////////// -// CONFIG - -bool LocateProtocol::isConfigRequest() -{ - return m_url.path() == "config"; -} - - -void LocateProtocol::configRequest() -{ - // This flag is used to show either a "succesful" or an "unchanged" message - // in configFinished(). - m_configUpdated = false; - - // Don't show it twice. During my tests I never got there however. - if(TDEConfigDialog::showDialog("settings")) - return; - - TDEConfigDialog *dialog = new TDEConfigDialog(0, "settings", KLocateConfig::self(), - KDialogBase::IconList, - KDialogBase::Default|KDialogBase::Ok|KDialogBase::Cancel|KDialogBase::Help, - KDialogBase::Ok, true); - dialog->setCaption(i18n("Configure - kio-locate")); - dialog->setIcon(SmallIcon("find")); - - dialog->addPage(new KLocateConfigWidget(), i18n("General"), "package_settings"); - dialog->addPage(new KLocateConfigFilterWidget(), i18n("Filters"), "filter"); - dialog->addPage(new KLocateConfigLocateWidget(), i18n("Locate"), "find"); - - // React on user's actions. - connect(dialog, TQT_SIGNAL(settingsChanged()), this, TQT_SLOT(updateConfig())); - connect(dialog, TQT_SIGNAL(finished()), this, TQT_SLOT(configFinished())); - - dialog->show(); - tqApp->enter_loop(); - delete dialog; -} - - -void LocateProtocol::configFinished() -{ - DEBUGSTR << "LocateProtocol::configFinished" << endl; - - tqApp->exit_loop(); - - TQString html; - if (m_configUpdated) { - html = i18n("Configuration succesfully updated."); - } else { - html = i18n("Configuration unchanged."); - } - outputHtml("<h1>" + html + "</h1>"); -} - - -void LocateProtocol::updateConfig() -{ - // It's not needed to update the config if it's still up to date. - DEBUGSTR << "LocateProtocol::updateConfig" << endl; - - KLocateConfig::self()->readConfig(); - m_config.m_caseSensitivity = (LocateCaseSensitivity) KLocateConfig::caseSensitivity(); - m_config.m_collapseDirectoryThreshold = KLocateConfig::collapseDirectoryThreshold(); - m_config.m_collapsedDisplay = KLocateConfig::collapsedDisplay(); - m_config.m_collapsedIcon = (LocateCollapsedIcon) KLocateConfig::collapsedIcon(); - m_config.m_whiteList = KLocateConfig::whiteList(); - m_config.m_blackList = KLocateConfig::blackList(); - - m_locater.setupLocate(KLocateConfig::locateBinary(), - KLocateConfig::locateAdditionalArguments()); - - m_configUpdated = true; -} - - -///////////////////////////////////////////////////////////////////// -// HELP - -bool LocateProtocol::isHelpRequest() -{ - return m_url.path() == "help"; -} - - -void LocateProtocol::helpRequest() -{ - // Redirect the user to our help documents. - redirection("help:/tdeio-locate/"); - finished(); -} - - -///////////////////////////////////////////////////////////////////// -// SEARCH STRUCTURES - -LocateDirectory::LocateDirectory(LocateDirectory *parent, const TQString& path) -{ - m_parent = parent; - m_path = path; - m_childs.setAutoDelete(true); - m_itemsCount = 0; -} - - -LocateDirectory *LocateDirectory::addPath(const TQString& path) -{ - if (path.startsWith(m_path)) { - TQString relPath = path.mid(m_path.length()); - int p = relPath.findRev('/'); - if (p >= 0) { - LocateDirectory *child = getSubDirectory(relPath.left(p)); - child->addItem(relPath.mid(p+1)); - return child; - } - addItem(relPath); - return this; - } - if (m_parent != NULL) { - return m_parent->addPath(path); - } - // This should not happen - return this; -} - - -LocateDirectory *LocateDirectory::getSubDirectory(const TQString& relPath) -{ - TQString base = relPath; - int p = relPath.find('/'); - if (p >= 0) { - base = relPath.left(p); - } - LocateDirectory *child = m_childs.find(base); - if (child == NULL) { - child = new LocateDirectory(this, addTrailingSlash(m_path + base)); - m_childs.insert(base, child); - } - if (p >= 0) { - return child->getSubDirectory(relPath.mid(p+1)); - } - return child; -} - - -void LocateDirectory::addItem(const TQString& path) -{ - m_items += LocateItem(m_path + path, 0); - m_itemsCount++; -} - - -int LocateDirectory::countMatchingItems(const LocateProtocol* protocol, int skip) -{ - int count = 0; - LocateItems::ConstIterator item = m_items.begin(); - for (; item != m_items.end(); ++item) { - if ((*item).m_subItems) { - count += (*item).m_subItems; - } else if (protocol->getRegExp().isMatching((*item).m_path.mid(skip))) { - ++count; - } - } - return count; -} - - -void LocateDirectory::prepareListing(const LocateProtocol* protocol, int skip) -{ - int n = m_path.length(), newSkip = n; - if (skip > newSkip) newSkip = skip; - - // Recursively walk through all childs. - LocateDirectoriesIterator child(m_childs); - for (; child.current(); ++child) { - child.current()->prepareListing(protocol, newSkip); - } - - // Set m_fullCount to the total number of childs matching the pattern. - m_fullCount = countMatchingItems(protocol, newSkip); - - // Collapse if directory part matches. - LocateDirectory* parent = m_parent; - if (parent == NULL) { - parent = this; - } - if (n > skip && protocol->getRegExp().isMatching(m_path.mid(skip))) { - // Directory part matches. - m_childs.clear(); - m_items.clear(); - m_itemsCount = 0; - parent->m_items += LocateItem(m_path, m_fullCount); - ++parent->m_itemsCount; - if (m_fullCount != 0) { - parent->m_items += LocateItem(m_path, 0); - ++parent->m_itemsCount; - } - } - - // Collapse if we got too many hits. - int maxHits = protocol->getCollapseDirectoryThreshold(); - if (n > skip && maxHits != 0 && m_itemsCount > maxHits) { - if (m_parent != NULL) { - m_parent->m_items += LocateItem(m_path, m_fullCount); - ++m_parent->m_itemsCount; - } else { - m_items.clear(); - m_items += LocateItem(m_path, m_fullCount); - ++m_itemsCount; - } - } else { - // Propagate items to parent. - // (only root LocateDirectory runs listItems) - if (m_parent != NULL) { - m_parent->m_items += m_items; - m_parent->m_itemsCount += m_itemsCount; - } - } -} - - -void LocateDirectory::listItems(LocateProtocol *protocol) -{ - LocateItems::ConstIterator item = m_items.begin(); - for (; item != m_items.end(); ++item) { - protocol->addHit(stripTrailingSlash((*item).m_path), (*item).m_subItems); - } -} - - -void LocateDirectory::debugTrace(int level) -{ - TQString ws; - ws.fill(' ', level); - DEBUGSTR << ws << m_path << endl; - LocateItems::ConstIterator item = m_items.begin(); - for (; item != m_items.end(); ++item) { - DEBUGSTR << ws << "+ " << (*item).m_path << endl; - } - LocateDirectoriesIterator child(m_childs); - for (; child.current(); ++child) { - child.current()->debugTrace(level+2); - } -} - - -LocateItem::LocateItem() -{ -} - - -LocateItem::LocateItem(const TQString& path, int subItems) -{ - m_path = path; - m_subItems = subItems; -} - - -///////////////////////////////////////////////////////////////////// -// INVOKATION - -extern "C" -{ - int kdemain(int argc, char **argv) - { - // We use TDEApplication instead of TDEInstance here, because we use a - // config dialog and such gui stuff. - TDEApplication app(argc, argv, "kio_locate", false, true); - - DEBUGSTR << "*** Starting kio_locate " << endl; - - if (argc != 4) { - DEBUGSTR << "Usage: kio_locate protocol domain-socket1 domain-socket2" << endl; - exit(-1); - } - - LocateProtocol slave(argv[2], argv[3]); - slave.dispatchLoop(); - - DEBUGSTR << "*** kio_locate Done" << endl; - return 0; - } -} - - -#include "kio_locate.moc" |