void MainWindow::MessageReceived(BMessage* message) { switch (message->what) { case MSG_MODEL_WORKER_DONE: { fModelWorker = B_BAD_THREAD_ID; _AdoptModel(); fFilterView->AdoptModel(fModel); break; } case B_SIMPLE_DATA: case B_REFS_RECEIVED: // TODO: ? break; case B_PACKAGE_UPDATE: // TODO: We should do a more selective update depending on the // "event", "location", and "change count" fields! _StartRefreshWorker(false); break; case MSG_REFRESH_DEPOTS: _StartRefreshWorker(true); break; case MSG_LOG_IN: _OpenLoginWindow(BMessage()); break; case MSG_LOG_OUT: fModel.SetUsername(""); break; case MSG_AUTHORIZATION_CHANGED: _UpdateAuthorization(); break; case MSG_SHOW_FEATURED_PACKAGES: { BAutolock locker(fModel.Lock()); fModel.SetShowFeaturedPackages( !fModel.ShowFeaturedPackages()); } _AdoptModel(); break; case MSG_SHOW_AVAILABLE_PACKAGES: { BAutolock locker(fModel.Lock()); fModel.SetShowAvailablePackages( !fModel.ShowAvailablePackages()); } _AdoptModel(); break; case MSG_SHOW_INSTALLED_PACKAGES: { BAutolock locker(fModel.Lock()); fModel.SetShowInstalledPackages( !fModel.ShowInstalledPackages()); } _AdoptModel(); break; case MSG_SHOW_SOURCE_PACKAGES: { BAutolock locker(fModel.Lock()); fModel.SetShowSourcePackages(!fModel.ShowSourcePackages()); } _AdoptModel(); break; case MSG_SHOW_DEVELOP_PACKAGES: { BAutolock locker(fModel.Lock()); fModel.SetShowDevelopPackages(!fModel.ShowDevelopPackages()); } _AdoptModel(); break; case MSG_PACKAGE_SELECTED: { BString name; if (message->FindString("name", &name) == B_OK) { BAutolock locker(fModel.Lock()); int count = fVisiblePackages.CountItems(); for (int i = 0; i < count; i++) { const PackageInfoRef& package = fVisiblePackages.ItemAtFast(i); if (package.Get() != NULL && package->Name() == name) { locker.Unlock(); _AdoptPackage(package); break; } } } else { _ClearPackage(); } break; } case MSG_CATEGORY_SELECTED: { BString name; if (message->FindString("name", &name) != B_OK) name = ""; { BAutolock locker(fModel.Lock()); fModel.SetCategory(name); } _AdoptModel(); break; } case MSG_DEPOT_SELECTED: { BString name; if (message->FindString("name", &name) != B_OK) name = ""; { BAutolock locker(fModel.Lock()); fModel.SetDepot(name); } _AdoptModel(); break; } case MSG_SEARCH_TERMS_MODIFIED: { // TODO: Do this with a delay! BString searchTerms; if (message->FindString("search terms", &searchTerms) != B_OK) searchTerms = ""; { BAutolock locker(fModel.Lock()); fModel.SetSearchTerms(searchTerms); } _AdoptModel(); break; } case MSG_PACKAGE_CHANGED: { PackageInfo* info; if (message->FindPointer("package", (void**)&info) == B_OK) { PackageInfoRef ref(info, true); uint32 changes; if (message->FindUInt32("changes", &changes) != B_OK) changes = 0; if ((changes & PKG_CHANGED_STATE) != 0) { BAutolock locker(fModel.Lock()); fModel.SetPackageState(ref, ref->State()); } // Asynchronous updates to the package information // can mean that the package needs to be added or // removed to/from the visible packages when the current // filter parameters are re-evaluated on this package. bool wasVisible = fVisiblePackages.Contains(ref); bool isVisible; { BAutolock locker(fModel.Lock()); // The package didn't get a chance yet to be in the // visible package list PackageList visiblePackages = fModel.CreatePackageList(); isVisible = visiblePackages.Contains(ref); // Transfer this single package, otherwise we miss // other packages if they appear or disappear along // with this one before receive a notification for // them. if (isVisible) { fVisiblePackages.Add(ref); } else if (wasVisible) fVisiblePackages.Remove(ref); } if (wasVisible != isVisible) { if (!isVisible) { fPackageListView->RemovePackage(ref); fFeaturedPackagesView->RemovePackage(ref); } else { fPackageListView->AddPackage(ref); if (ref->IsProminent()) fFeaturedPackagesView->AddPackage(ref); } } } break; } case MSG_RATE_PACKAGE: _RatePackage(); break; case MSG_SHOW_SCREENSHOT: _ShowScreenshot(); break; default: BWindow::MessageReceived(message); break; } }