Logo Search packages:      
Sourcecode: wxwindows2.4 version File versions

AutoComplete.cxx

Go to the documentation of this file.
// Scintilla source code edit control
/** @file AutoComplete.cxx
 ** Defines the auto completion list box.
 **/
// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#include "Platform.h"

#include "PropSet.h"
#include "AutoComplete.h"

AutoComplete::AutoComplete() :
      active(false),
      separator(' '),
      typesep('?'),
      ignoreCase(false),
      chooseSingle(false),
      lb(0),
      posStart(0),
      startLen(0),
      cancelAtStartPos(true),
      autoHide(true),
      dropRestOfWord(false)   {
      lb = ListBox::Allocate();
      stopChars[0] = '\0';
      fillUpChars[0] = '\0';
}

AutoComplete::~AutoComplete() {
      if (lb) {
            lb->Destroy();
            delete lb;
            lb = 0;
      }
}

bool AutoComplete::Active() {
      return active;
}

void AutoComplete::Start(Window &parent, int ctrlID, int position,
      int startLen_, int lineHeight, bool unicodeMode) {
      if (active) {
            Cancel();
      }
      lb->Create(parent, ctrlID, lineHeight, unicodeMode);
      lb->Clear();
      active = true;
      startLen = startLen_;
      posStart = position;
}

void AutoComplete::SetStopChars(const char *stopChars_) {
      strncpy(stopChars, stopChars_, sizeof(stopChars));
      stopChars[sizeof(stopChars) - 1] = '\0';
}

bool AutoComplete::IsStopChar(char ch) {
      return ch && strchr(stopChars, ch);
}

void AutoComplete::SetFillUpChars(const char *fillUpChars_) {
      strncpy(fillUpChars, fillUpChars_, sizeof(fillUpChars));
      fillUpChars[sizeof(fillUpChars) - 1] = '\0';
}

bool AutoComplete::IsFillUpChar(char ch) {
      return ch && strchr(fillUpChars, ch);
}

void AutoComplete::SetSeparator(char separator_) {
      separator = separator_;
}

char AutoComplete::GetSeparator() {
      return separator;
}

void AutoComplete::SetTypesep(char separator_) {
      typesep = separator_;
}

char AutoComplete::GetTypesep() {
      return typesep;
}

void AutoComplete::SetList(const char *list) {
      lb->Clear();
      char *words = new char[strlen(list) + 1];
      if (words) {
            strcpy(words, list);
            char *startword = words;
            char *numword = NULL;
            int i = 0;
            for (; words && words[i]; i++) {
                  if (words[i] == separator) {
                        words[i] = '\0';
                        if (numword)
                              *numword = '\0';
                        lb->Append(startword, numword?atoi(numword + 1):-1);
                        startword = words + i + 1;
                        numword = NULL;
                  } else if (words[i] == typesep) {
                        numword = words + i;
                  }
            }
            if (startword) {
                  if (numword)
                        *numword = '\0';
                  lb->Append(startword, numword?atoi(numword + 1):-1);
            }
            delete []words;
      }
}

void AutoComplete::Show() {
      lb->Show();
      lb->Select(0);
}

void AutoComplete::Cancel() {
      if (lb->Created()) {
            lb->Destroy();
            active = false;
      }
}


void AutoComplete::Move(int delta) {
      int count = lb->Length();
      int current = lb->GetSelection();
      current += delta;
      if (current >= count)
            current = count - 1;
      if (current < 0)
            current = 0;
      lb->Select(current);
}

void AutoComplete::Select(const char *word) {
      size_t lenWord = strlen(word);
      int location = -1;
      const int maxItemLen=1000;
      char item[maxItemLen];
      int start = 0; // lower bound of the api array block to search
      int end = lb->Length() - 1; // upper bound of the api array block to search
      while ((start <= end) && (location == -1)) { // Binary searching loop
            int pivot = (start + end) / 2;
            lb->GetValue(pivot, item, maxItemLen);
            int cond;
            if (ignoreCase)
                  cond = CompareNCaseInsensitive(word, item, lenWord);
            else
                  cond = strncmp(word, item, lenWord);
            if (!cond) {
                  // Find first match
                  while (pivot > start) {
                        lb->GetValue(pivot-1, item, maxItemLen);
                        if (ignoreCase)
                              cond = CompareNCaseInsensitive(word, item, lenWord);
                        else
                              cond = strncmp(word, item, lenWord);
                        if (0 != cond)
                              break;
                        --pivot;
                  }
                  location = pivot;
            } else if (cond < 0) {
                  end = pivot - 1;
            } else if (cond > 0) {
                  start = pivot + 1;
            }
      }
      if (location == -1 && autoHide)
            Cancel();
      else
            lb->Select(location);
}


Generated by  Doxygen 1.6.0   Back to index