Exemplo n.º 1
0
int Menu(const char *title,MenuList& lst,int sel,int flags=MF_LABELS,const void* param=NULL)
{
  Vector<FarMenuItem> menu;
  menu.Init(lst.Count());
  static const char labels[]="1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  static const int labelsCount=sizeof(labels)-1;
  int i=0;
  int j=0;
  char buf[16];
  ZeroMemory(&menu[0],sizeof(FarMenuItem)*lst.Count());
  if(!(flags&MF_FILTER))
  {
    for(i=0;i<lst.Count();i++)
    {
      if((flags&MF_LABELS))
      {
        if(i<labelsCount)
        {
          sprintf(buf,"&%c ",labels[i]);
          strcpy(menu[i].Text,buf);
        }else
        {
          strcpy(menu[i].Text,"  ");
        }
        strcat(menu[i].Text,lst[i].item.Substr(0,120));
      }else
      {
        strcpy(menu[i].Text,lst[i].item.Substr(0,120));
      }
      if(sel==i)menu[i].Selected=1;
    }
    String cnt;
    cnt.Sprintf(" %s%d ",GetMsg(MItemsCount),lst.Count());
    int res=I.Menu(I.ModuleNumber,-1,-1,0,FMENU_WRAPMODE,title,flags&MF_SHOWCOUNT?cnt.Str():NULL,
                   "content",NULL,NULL,&menu[0],lst.Count());
    return res!=-1?lst[res].data:res;
  }else
  {
    String filter=param?(char*)param:"";
    Vector<int> idx;
    Vector<int> fk;
    static const char *filterkeys="1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_$\\\x08-_=|;':\",./<>? []*&^%#@!~";
    int shift;
    for(i=0;filterkeys[i];i++)
    {
      DWORD k=VkKeyScan(filterkeys[i]);
      if(k==0xffff)
      {
        fk.Push(0);
        continue;
      }
      shift=(k&0xff00)>>8;
      if(shift==1)shift=4;
      else if (shift==2)shift=1;
      else if (shift==4)shift=2;
      k=(k&0xff)|(shift<<16);
      fk.Push(k);
    }
    fk.Push(0);
#ifdef DEBUG
    //DebugBreak();
#endif
    int mode=0;
    for(;;)
    {
      int oldj=j;
      j=0;
      String match="";
      int minit=0;
      int fnd=-1,oldfnd=-1;
      idx.Clean();
      for(i=0;i<lst.Count();i++)
      {
        lst[i].item.SetNoCase(!config.casesens);
        if(filter.Length() && (fnd=lst[i].item.Index(filter))==-1)continue;
        if(!minit && fnd!=-1)
        {
          match=lst[i].item.Substr(fnd);
          minit=1;
        }
        if(oldfnd!=-1 && oldfnd!=fnd)
        {
          oldj=-1;
        }
        if(fnd!=-1 && filter.Length())
        {
          int xfnd=-1;
          while((xfnd=lst[i].item.Index(filter,xfnd+1))!=-1)
          {
            for(int k=0;k<match.Length();k++)
            {
              if(xfnd+k>=lst[i].item.Length() ||
                  (config.casesens && match[k]!=lst[i].item[xfnd+k]) ||
                  (!config.casesens && tolower(match[k])!=tolower(lst[i].item[xfnd+k]))
                )
              {
                match.Delete(k);
                break;
              }
            }
          }
        }
        idx.Push(i);
        strcpy(menu[j].Text,lst[i].item.Substr(0,120));
        if(sel==j)menu[j].Selected=1;
        j++;
        if(fnd!=-1)oldfnd=fnd;
      }
      if((mode==0 && j==0) || (mode==1 && j==oldj))
      {
        if(filter.Length())
        {
          //DebugBreak();
          filter.Delete(-1);
          continue;
        }
      }
      if(sel>j)
      {
        menu[j-1].Selected=1;
      }
      if(match.Length()>filter.Length() && j>1 && mode!=1)
      {
        filter=match;
      }
      String cnt;
      cnt.Sprintf(" %s%d ",GetMsg(MItemsCount),j);
      int bkey;
      String ftitle=title;
      ftitle+=" ["+filter+"]";
      int res=I.Menu(I.ModuleNumber,-1,-1,0,FMENU_WRAPMODE|FMENU_SHOWAMPERSAND,ftitle,
                     flags&MF_SHOWCOUNT?cnt.Str():NULL,"content",&fk[0],&bkey,&menu[0],j);
      if(res==-1 && bkey==-1)return -1;
      if(bkey==-1)
      {
        return lst[idx[res]].data;
      }
      int key=filterkeys[bkey];
      if(key==8)
      {
        filter.Delete(-1);
        mode=1;
        continue;
      }
      filter+=(char)key;
      mode=0;
      sel=res;
    }
  }
}