123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563 |
- /*
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is Vision.
- *
- * The Initial Developer of the Original Code is The Vision Team.
- * Portions created by The Vision Team are
- * Copyright (C) 1999, 2000, 2001 The Vision Team. All Rights
- * Reserved.
- *
- * Contributor(s): Wade Majors <wade@ezri.org>
- * Rene Gollent
- * Todd Lair
- */
- #include <MenuBar.h>
- #include <MenuItem.h>
- #include <ScrollView.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include "ColumnTypes.h"
- #include "ColumnListView.h"
- #include "Prompt.h"
- #include "StatusView.h"
- #include "Vision.h"
- #include "Utilities.h"
- #include "ListAgent.h"
- #include "WindowList.h"
- #include "ClientWindow.h"
- #include "Theme.h"
- /*
- -- #beos was here --
- <kurros> regurg, fondle my buttocks
- <regurg> Your?
- <kurros> regurg, yes. mine
- <regurg> I understand.
- <kurros> regurg, no. i don't think you do
- <regurg> Does this make you feel unhappy?
- <Brazilian> hmm, eliza is just broke
- <kurros> regurg, i just want my buttocks fondled
- <regurg> Why do you say your?
- <Brazilian> the whole string ("fondle by buttocks") is getting passed
- <kurros> regurg, repair thyself
- <regurg> Earlier you said your .
- <kurros> regurg, get off it. don't worry about it anymore
- <regurg> But your .
- */
- const int32 LIST_BATCH_SIZE = 75;
- ListAgent::ListAgent (
- BRect frame,
- const char *title,
- BMessenger *sMsgr_)
- : BView (
- frame,
- title,
- B_FOLLOW_ALL_SIDES,
- B_WILL_DRAW | B_FRAME_EVENTS),
- activeTheme (vision_app->ActiveTheme()),
- fSMsgr (sMsgr_),
- listUpdateTrigger (NULL),
- filter (""),
- find (""),
- processing (false)
- {
- frame = Bounds();
-
- listMenu = new BMenu (S_LIST_MENU);
- listMenu->AddItem (mFind = new BMenuItem (
- S_LIST_MENU_FIND B_UTF8_ELLIPSIS,
- new BMessage (M_LIST_FIND)));
- listMenu->AddItem (mFindAgain = new BMenuItem (
- S_LIST_MENU_FINDNEXT,
- new BMessage (M_LIST_FAGAIN)));
- listMenu->AddItem (mFilter = new BMenuItem (
- S_LIST_MENU_FILTER B_UTF8_ELLIPSIS,
- new BMessage (M_LIST_FILTER)));
-
- mFind->SetEnabled (false);
- mFindAgain->SetEnabled (false);
- mFilter->SetEnabled (false);
-
- BView *bgView (new BView (
- frame,
- "background",
- B_FOLLOW_ALL_SIDES,
- B_WILL_DRAW));
- bgView->SetViewColor (activeTheme->ForegroundAt (C_BACKGROUND));
- AddChild (bgView);
- frame = bgView->Bounds().InsetByCopy (1, 1);
-
- listView = new BColumnListView (
- frame,
- "list",
- B_FOLLOW_ALL_SIDES,
- B_WILL_DRAW | B_NAVIGABLE | B_FULL_UPDATE_ON_RESIZE);
- listView->SetInvocationMessage (new BMessage (M_LIST_INVOKE));
- bgView->AddChild (listView);
- listView->MakeFocus (true);
- listView->SetTarget(this);
- channelColumn = new BStringColumn (S_LIST_COLUMN_CHAN, be_plain_font->StringWidth (S_LIST_COLUMN_CHAN) * 2,
- 0, frame.Width(), 0);
- listView->AddColumn (channelColumn, 0);
- usersColumn = new BIntegerColumn (S_LIST_COLUMN_USER, be_plain_font->StringWidth (S_LIST_COLUMN_USER) * 2, 0, frame.Width(), B_ALIGN_CENTER);
- listView->AddColumn (usersColumn, 1);
- topicColumn = new BStringColumn (S_LIST_COLUMN_TOPIC, frame.Width() / 2,
- 0, frame.Width(), 0);
- listView->AddColumn (topicColumn, 2);
- listView->SetSelectionMode (B_SINGLE_SELECTION_LIST);
- activeTheme->ReadLock();
- listView->SetColor (B_COLOR_BACKGROUND, activeTheme->ForegroundAt (C_BACKGROUND));
- listView->SetColor (B_COLOR_TEXT, activeTheme->ForegroundAt (C_TEXT));
- listView->SetColor (B_COLOR_SELECTION, activeTheme->ForegroundAt (C_SELECTION));
- listView->SetFont (B_FONT_ROW, &activeTheme->FontAt (F_LISTAGENT));
- activeTheme->ReadUnlock();
- #ifdef __INTEL__
- memset (&re, 0, sizeof (re));
- memset (&fre, 0, sizeof (fre));
- #endif
- }
- ListAgent::~ListAgent (void)
- {
- BRow *row (NULL);
- if (listUpdateTrigger)
- delete listUpdateTrigger;
- while (listView->CountRows() > 0)
- {
- row = listView->RowAt (0);
- listView->RemoveRow (row);
- delete row;
- }
-
- while (hiddenItems.CountItems() > 0)
- delete hiddenItems.RemoveItemAt (0L);
-
- delete fSMsgr;
- delete fAgentWinItem;
- #ifdef __INTEL__
- regfree (&re);
- regfree (&fre);
- #endif
- }
- void
- ListAgent::AttachedToWindow (void)
- {
- fMsgr = BMessenger (this);
- listView->SetTarget(this);
- }
- void
- ListAgent::Show (void)
- {
- Window()->PostMessage (M_STATUS_CLEAR);
- this->fMsgr.SendMessage (M_STATUS_ADDITEMS);
- #ifdef __INTEL__
- vision_app->pClientWin()->AddMenu (listMenu);
- listMenu->SetTargetForItems (this);
- #endif
- const BRect *agentRect (dynamic_cast<ClientWindow *>(Window())->AgentRect());
-
- if (*agentRect != Frame())
- {
- ResizeTo (agentRect->Width(), agentRect->Height());
- MoveTo (agentRect->left, agentRect->top);
- }
- BView::Show();
- }
- void
- ListAgent::Hide (void)
- {
- vision_app->pClientWin()->RemoveMenu (listMenu);
- BView::Hide();
- }
- void
- ListAgent::AddBatch (void)
- {
- // make sure you call this from a locked looper
- BRow *row (NULL);
- Window()->DisableUpdates();
- while ((row = fBuildList.RemoveItemAt (0L)) != NULL)
- listView->AddRow (row);
- Window()->EnableUpdates();
-
- BString cString;
- cString << listView->CountRows();
- if (!IsHidden())
- vision_app->pClientWin()->pStatusView()->SetItemValue (0, cString.String(), true);
- }
- void
- ListAgent::MessageReceived (BMessage *msg)
- {
- switch (msg->what)
- {
- case M_THEME_FONT_CHANGE:
- {
- int32 which (msg->FindInt16 ("which"));
- if (which == F_LISTAGENT)
- {
- activeTheme->ReadLock();
- listView->SetFont (B_FONT_ROW, &activeTheme->FontAt (F_LISTAGENT));
- activeTheme->ReadUnlock();
- listView->Invalidate();
- }
- }
- break;
-
- case M_THEME_FOREGROUND_CHANGE:
- {
- int32 which (msg->FindInt16 ("which"));
- bool refresh (false);
- switch (which)
- {
- case C_BACKGROUND:
- activeTheme->ReadLock();
- listView->SetColor (B_COLOR_BACKGROUND, activeTheme->ForegroundAt (C_BACKGROUND));
- activeTheme->ReadUnlock();
- refresh = true;
- break;
-
- case C_TEXT:
- activeTheme->ReadLock();
- listView->SetColor (B_COLOR_TEXT, activeTheme->ForegroundAt (C_TEXT));
- activeTheme->ReadUnlock();
- refresh = true;
- break;
- case C_SELECTION:
- activeTheme->ReadLock();
- listView->SetColor (B_COLOR_SELECTION, activeTheme->ForegroundAt (C_SELECTION));
- activeTheme->ReadUnlock();
- refresh = true;
- break;
-
- default:
- break;
- }
- if (refresh)
- Invalidate();
- }
- break;
-
- case M_STATUS_ADDITEMS:
- {
- vision_app->pClientWin()->pStatusView()->AddItem (new StatusItem (S_STATUS_LISTCOUNT, ""), true);
- vision_app->pClientWin()->pStatusView()->AddItem (new StatusItem (S_STATUS_LISTSTAT, ""), true);
- vision_app->pClientWin()->pStatusView()->AddItem (new StatusItem (S_STATUS_LISTFILTER, "", STATUS_ALIGN_LEFT), true);
-
- BString cString;
- cString << listView->CountRows();
- vision_app->pClientWin()->pStatusView()->SetItemValue (0, cString.String(), false);
- vision_app->pClientWin()->pStatusView()->SetItemValue (1, statusStr.String(), false);
- vision_app->pClientWin()->pStatusView()->SetItemValue (2, filter.String(), true);
- }
- break;
- case M_LIST_COMMAND:
- {
- if (!processing)
- {
- BMessage sMsg (M_SERVER_SEND);
-
- BString command ("LIST");
-
- BString params (msg->FindString ("cmd"));
- if (params != "-9z99")
- {
- command.Append (" ");
- command.Append (params);
- }
- sMsg.AddString ("data", command.String());
- fSMsgr->SendMessage (&sMsg);
- processing = true;
- if (!IsHidden())
- vision_app->pClientWin()->pStatusView()->SetItemValue (0, "0", true);
- }
- }
- break;
- case M_LIST_BEGIN:
- {
- BMessage msg (M_LIST_UPDATE);
- listUpdateTrigger = new BMessageRunner (BMessenger(this), &msg, 3000000);
- statusStr = S_LIST_STATUS_LOADING;
- if (!IsHidden())
- vision_app->pClientWin()->pStatusView()->SetItemValue (1, statusStr.String(), true);
- }
- break;
-
- case M_LIST_DONE:
- {
- if (listUpdateTrigger)
- {
- delete listUpdateTrigger;
- listUpdateTrigger = 0;
- }
- statusStr = S_LIST_STATUS_DONE;
- listView->SetSortingEnabled (true);
- listView->SetSortColumn (channelColumn, true, true);
-
- if (!IsHidden())
- vision_app->pClientWin()->pStatusView()->SetItemValue (1, statusStr.String(), true);
- mFind->SetEnabled (true);
- mFindAgain->SetEnabled (true);
- mFilter->SetEnabled (true);
- processing = false;
-
- // empty out any remaining channels that fell below the batch cut off
- AddBatch();
- BString cString;
- cString << listView->CountRows();
- if (!IsHidden())
- vision_app->pClientWin()->pStatusView()->SetItemValue (0, cString.String(), true);
- }
- break;
- case M_LIST_EVENT:
- {
- const char *channel, *users, *topic;
- msg->FindString ("channel", &channel);
- msg->FindString ("users", &users);
- msg->FindString ("topic", &topic);
-
- BRow *row (new BRow ());
-
-
- BStringField *channelField (new BStringField (channel));
- BIntegerField *userField (new BIntegerField (atoi(users)));
- BStringField *topicField (new BStringField (topic));
-
- row->SetField (channelField, channelColumn->LogicalFieldNum());
- row->SetField (userField, usersColumn->LogicalFieldNum());
- row->SetField (topicField, topicColumn->LogicalFieldNum());
- fBuildList.AddItem (row);
-
- if (fBuildList.CountItems() == LIST_BATCH_SIZE)
- AddBatch();
- }
- break;
- #ifdef __INTEL__
- case M_LIST_FILTER:
- if (msg->HasString ("text"))
- {
- const char *buffer;
- msg->FindString ("text", &buffer);
- if (filter != buffer)
- {
- filter = buffer;
- if (!IsHidden())
- vision_app->pClientWin()->pStatusView()->SetItemValue (2, filter.String(), true);
- regfree (&re);
- memset (&re, 0, sizeof (re));
- regcomp (
- &re,
- filter.String(),
- REG_EXTENDED | REG_ICASE | REG_NOSUB);
-
- BRow *currentRow;
- BStringField *channel,
- *topic;
- while (hiddenItems.CountItems() != 0)
- {
- currentRow = hiddenItems.RemoveItemAt (0L);
- listView->AddRow (currentRow);
- }
- if (filter != NULL)
- {
- int32 k (0);
-
- while (k < listView->CountRows())
- {
- currentRow = listView->RowAt (k);
- channel = (BStringField *)currentRow->GetField (0);
- topic = (BStringField *)currentRow->GetField (2);
- if ((regexec (&re, channel->String(), 0, 0, 0) != REG_NOMATCH)
- || (regexec (&re, topic->String(), 0, 0, 0) != REG_NOMATCH))
- {
- k++;
- continue;
- }
- else
- {
- listView->RemoveRow (currentRow);
- hiddenItems.AddItem (currentRow);
- }
- }
- }
- fMsgr.SendMessage (M_LIST_DONE);
- processing = true;
- }
- }
- else
- {
- PromptWindow *prompt (new PromptWindow (
- BPoint ((Window()->Frame().right/2) - 100, (Window()->Frame().bottom/2) - 50),
- " Filter:",
- "List Filter",
- filter.String(),
- this,
- new BMessage (M_LIST_FILTER),
- new RegExValidate ("Filter"),
- true));
- prompt->Show();
- }
- break;
- case M_LIST_FIND:
- if (msg->HasString ("text"))
- {
- int32 selection (listView->IndexOf(listView->CurrentSelection()));
- const char *buffer;
- msg->FindString ("text", &buffer);
- if (strlen (buffer) == 0)
- {
- find = buffer;
- break;
- }
- if (selection < 0)
- {
- selection = 0;
- }
- else
- {
- ++selection;
- }
- if (find != buffer)
- {
- regfree (&fre);
- memset (&fre, 0, sizeof (fre));
- regcomp (
- &fre,
- buffer,
- REG_EXTENDED | REG_ICASE | REG_NOSUB);
- find = buffer;
- }
- BStringField *field;
- int32 i;
- for (i = selection; i < listView->CountRows(); ++i)
- {
- field = (BStringField *)listView->RowAt (i)->GetField (0);
- if (regexec (&fre, field->String(), 0, 0, 0) != REG_NOMATCH)
- break;
- }
- if (i < listView->CountRows())
- {
- BRow* row = listView->RowAt (i);
- listView->DeselectAll();
- listView->AddToSelection (row);
- listView->ScrollTo(row);
- listView->Refresh();
- }
- else
- {
- listView->DeselectAll();
- }
- }
- else
- {
- PromptWindow *prompt (new PromptWindow (
- BPoint ((Window()->Frame().right / 2) - 100, (Window()->Frame().bottom/2) - 50),
- S_LIST_PROMPT_LABEL,
- S_LIST_PROMPT_TITLE,
- find.String(),
- this,
- new BMessage (M_LIST_FIND),
- new RegExValidate ("Find:"),
- true));
- prompt->Show();
- }
- break;
- case M_LIST_FAGAIN:
- if (find.Length())
- {
- msg->AddString ("text", find.String());
- msg->what = M_LIST_FIND;
- fMsgr.SendMessage (msg);
- }
- break;
- #endif
- case M_LIST_INVOKE:
- {
- BMessage msg (M_SUBMIT);
- BString buffer;
-
- BRow *row (listView->CurrentSelection());
-
- if (row)
- {
- buffer = "/JOIN ";
- buffer += ((BStringField *)row->GetField(0))->String();
- msg.AddBool ("history", false);
- msg.AddBool ("clear", false);
- msg.AddString ("input", buffer.String());
- fSMsgr->SendMessage (&msg);
- }
- }
- break;
-
- case M_CLIENT_QUIT:
- {
- fSMsgr->SendMessage(M_LIST_SHUTDOWN);
- BMessage deathchant (M_OBITUARY);
- deathchant.AddPointer ("agent", this);
- deathchant.AddPointer ("item", fAgentWinItem);
- vision_app->pClientWin()->PostMessage (&deathchant);
- }
- break;
-
- default:
- BView::MessageReceived (msg);
- }
- }
|