TeasyGG - sortowanie

0

Witam. Chcę zrobić sortowanie listy kontaktów komponentu EasyGG. Robię to następująco:


```delphi
procedure TForm1.SortByStatus(iLow, iHigh : Integer);
var
 Temp: TUser;
  i, j, x: Integer;
begin
  for i := iHigh downto iLow do
    if im.users.Items[i].Status in [usGGWithMe, usAvailable, usBusy, usDND] then
    begin
      for j := i - 1 downto iLow do
        if im.users[j].Status = usNotAvailable then
        begin
          Temp := im.Users[i];
          im.users[i] := im.users[j];
          im.users[j] := Temp;
        end;
    end;
  x := 0;
  for i := iHigh downto iLow do
    if im.users[i].Status in [usGGWithMe, usAvailable, usBusy, usDND] then
    begin
      x := i - iLow + 1;
      Break;
    end;
  if (x = 0) or (x = iHigh - iLow + 1) then
    SortByName(iLow, iHigh)
  else
  begin
    SortByName(iLow, x - 1);
    SortByName(x, iHigh);
  end;
end;

procedure TForm1.SortByName(iLow, iHigh : Integer);
var
  Temp : TUser;
  x: string;
  iLo, iHi : Integer;
begin
  iLo := iLow;
  iHi := iHigh;
  x := im.users[(iLow + iHigh) div 2].Name;
  repeat
    while AnsiLowerCase(im.users[iLo].Name) < AnsiLowerCase(x) do
      Inc(iLo);
    while AnsiLowerCase(im.users[iHi].Name) > AnsiLowerCase(x) do
      Dec(iHi);
    if iLo <= iHi then
    begin
      Temp := im.users[iLo];
      im.users[iLo] := im.users[iHi];
      im.users[iHi] := Temp;
      Inc(iLo);
      Dec(iHi);
    end;
  until iLo > iHi;
  if iHi > iLow then
    SortByName(iLow, iHi);
  if iLo < iHigh then
    SortByName(iLo, iHigh);
end;            

jednak przy kompilacji wyskakuje mi błąd:
[ERROR] main.pas(175): Cannot assign to read-only property.

Co robię źle ? Jaki moze być inny sposób na sortowanie listy według statusów i imion ?
0

Witam.
Problem polega na tym, że właściwość Users jest tylko do odczytu.
Nie możesz więc zrobić czegoś takiego:

im.users[iLo] := im.users[iHi];
im.users[iHi] := Temp;
0

Czy planujesz dodanie sortowania do następnej wersji ? Jeśli nie to co zmienić by właściwość users była zapisywalna ?

0

Sortowanie jest oczywiście planowane. Możliwie jak najszybciej. Co to zapisywalności właściwości users - jest tylko do odczytu bo nie chciało mi się testować co się stanie jak będzie do zapisu :).

Na własną odpowiedzialność:
W module EGG.pas znajdź

property Users: TUsers read FUsers;

i zamień na

property Users: TUsers read FUsers write FUsers;

Jednak nie obiecuję, że wszystko będzie poprawnie działać po tej zmianie. Jeżeli będzie wszystko ok to daj znać.

EDIT:
Zamiast przypisywania całej klasy możesz skorzystać z faktu, że TUsers dziedziczy po TList. Masz więc do dyspozycji funkcje takie jak Exchange czy Move.

0

Wciąż ten sam komunikat że Users jest tylko do odczytu... Nie rozumiem tego...

EDIT: Mam wrażenie że sortowanie jest lepszym wyjściem od EXCHANGE i MOVE.
Czy gdzieś jeszcze klasa TUsers jest zadeklarowana jako read only ? Po zmianie na
property Users: TUsers read FUsers write FUsers; nic się nie zmienia. Ten sam błąd podczas kompilacji.

0

A zrobiłeś Builda paczki po tej zmianie?

0

Używam D7 więc tylko odinstalowałem i ponownie zainstalowałem komponent.

0

@wala: Za pewne chodzi Tobie o posortowanie listy kontaktów według statusu. Najpierw dostępni, później
Ci co mając "zaraz wracam", później niedostępni tak jak w GG jest to chyba nadal. Nie wiem jak jest teraz,
bo z przyzwyczajenie, ponieważ rzadko korzystam używam wersji 7.6 jeszcze. Ja napisałem sobie (jeszcze
nieskończony wprawdzie) klienta opertego na TEasyGG i użyłęm do tego celu TGGList, źródło którego jest
na tym forum, a do tego dynamicznie tworzonego ListView o nazwie ContactsLV "podczepionego" do tejże
również dynamicznie tworzonej TGGList, zresztą TrayIkonę jak i TEasyGG również mam tworzone w sposób
dynamiczny, tak aby nie trzeba było przenosząć źródło na inne Delphi instalować komponentów. Zrobiłem w
sumie sortowanie tak jak poniżej. Wywołuje je tylko przez ContactsLV.AlphaSort. W zerowej kolumnie ów
ListView mam nazwe usera, w 1: numer, w 2: opis a w 3 (subitem 2) mam status cyferką, ktory ustawia mi
funkcja StateID. Userzy dodani są do ListView poprzez taki kod. A ciut niżej kod sortowania od ContactsLV.

//...
    User := EGG.Users.Items[EGG.Users.Add(StrToInt64(GGNumEdit.Text))];
    User.Name := UserNameEdit.Text;
    S := IntToStr(StateID(User.Status));
    ContactsLV.AddItem(User.Name, User);
    ListItem := ContactsLV.Items[ContactsLV.Items.Count - 1];
    ListItem.SubItems.Add(IntToStr(User.UID));
    ListItem.SubItems.Add(User.Description);
    ListItem.SubItems.Add(S);
//...

Funkcja StateID oraz sortowanie ContactsLV rosnąco według kolumny z numerem statusu.

//...
function StateID(Status : TUserStatus) : Byte;
begin
  case Status of
    usAvailable : Result := 0; // Dostępny
    usBusy : Result := 1; // Zaraz wracam
    usNotAvailable : Result := 2; // Niedostępny
    usInvisible : Result := 3; //Niewidoczny
    usBlocked : Result := 4; //Zablokowany
  else
    Result := 1; // Niedostępny
  end;
end;
//...
procedure TMainForm.ContactsLVCompare(Sender : TObject; Item1,
  Item2 : TListItem; Data : Integer; var Compare : Integer);
const
  StatusCol = 2;
var
  StatusNum1, StatusNum2 : integer;
begin
  StatusNum1 := StrToInt(Item1.SubItems[StatusCol]);
  StatusNum2 := StrToInt(Item2.SubItems[StatusCol]);
  if StatusNum1 > StatusNum2 then
    Compare := 1
  else if StatusNum1 < StatusNum2 then
    Compare := -1
  else
    Compare := CompareText(Item1.Caption, Item2.Caption);
end;
0

@olesio: Tak, chodzi mi o posortowanie wg statusów. Wcześniej używałem sposobu podobnego jak Ty ale działało to cholernie powoli... tzn rysowanie listy kontaktów na lb powodowało miganie a to nie wyglądało ciekawie ;). Postanowiłem zrobic więc sortowanie podobnie jak to jest w komponencie THgg ale napotkałem na ten mały problem z read-only. Gdyby nie to, podejrzewam, ze działałoby to całkiem szybko.

0

Ja dlatego mam nadzieję, że w wersji 0.3 TEasyGG oprócz użycia zewnętrzbego parsera XML ktorego to już
poleciłem autorowi zamaist modułó TXMLDocument niedostępnych na przykład w wersji Delphi 7 Personal,
doda także zdarzenie OnUpdateContactsDone albo coś w tym stylu. Wtedy kiedy kontakty skończył by się
dodawać można by było je posortować i odświeżyć itemy w TGGList oraz zrobić GGList.Viisible := True, po
tym jak w zdarzeniu update'u zrobiło by się GGList.Visible := False; Póki co też mam z miganiem i tak w
obecnej wersji zostawiłem. A może jak chcesz posortowac userow to dodawaj ich do obiektu typu TList, w
takiej lisćie możes przechowywać wskażniki na obiekt typu TUser czy tam komponenty. Czy co Tobie jest
wygodnie. Później możesz użyć funkcji StateID ktorą podałem i posortować elementy według statusów, w
taki sposób jak opisano na: http://delphi.about.com/od/adptips2003/a/bltip1103_3.htm - tylko zamiast
jak tam użyć typu TMyListItem używasz po prostu TUser. Ale nie wiem, czy Tobie to będzie odpowiadać.

0

@olesio: Coś jeszcze wykombinuję... mam nadzieję, ze w 0.3 będzie sortowanie.

0

Odświeżam temat bo być może ktoś wpadł na ciekawe rozwiązanie ? Nowej wersji Teasygg jak nie było tak nie ma i nie wiadomo kiedy będzie...

0

Ja też miałem z tym problem. Rozwiązałem go nieelegancko, brzydko i niezgodnie ze standartami, ale działa:) W żródle TEasyGG upubliczniłem wszystkie pola UsreGG i potem nie było problemu z zamianą 2 userów miejscami. po prostu zamieniałem wszystkie pola danych 2 userów miejscami. Działa w miare szybko i nie zauważyłem, żeby to miało jakiś negatywny wpływ na program.

0

Czy mógłbyś mi przesłać na maila źródełka ?

0

misiakufal wiem, że temat jest dość stary, ale może pamiętasz co dokładnie zmieniłeś, że mogłeś zamieniać miejscami userów?
Pozdrawiam i przepraszam za odkopanie starego tematu.

1 użytkowników online, w tym zalogowanych: 0, gości: 1