void MimeTypeListView::ShowIcons(bool showIcons) { if (showIcons == fShowIcons) return; fShowIcons = showIcons; if (Window() == NULL) return; // update items BFont font; GetFont(&font); for (int32 i = FullListCountItems(); i-- > 0;) { MimeTypeItem* item = dynamic_cast<MimeTypeItem*>(FullListItemAt(i)); if (item == NULL) continue; if (!item->IsSupertypeOnly()) item->ShowIcon(showIcons); item->Update(this, &font); } FrameResized(Bounds().Width(), Bounds().Height()); // update scroller Invalidate(); }
void MimeTypeListView::_CollectSubtypes(const char* supertype, MimeTypeItem* supertypeItem) { BMessage types; if (BMimeType::GetInstalledTypes(supertype, &types) != B_OK) return; const char* type; int32 index = 0; while (types.FindString("types", index++, &type) == B_OK) { BMimeType mimeType(type); bool isApp = mimetype_is_application_signature(mimeType); if (fApplicationMode ^ isApp) continue; MimeTypeItem* typeItem = new MimeTypeItem(mimeType, fShowIcons, supertypeItem == NULL); typeItem->SetApplicationMode(isApp); if (supertypeItem != NULL) AddUnder(typeItem, supertypeItem); else AddItem(typeItem); } }
void TypeListWindow::MessageReceived(BMessage* message) { switch (message->what) { case kMsgTypeSelected: fSelectButton->SetEnabled(fListView->CurrentSelection() >= 0); break; case kMsgSelected: { MimeTypeItem* item = dynamic_cast<MimeTypeItem*>(fListView->ItemAt( fListView->CurrentSelection())); if (item != NULL) { BMessage select(fWhat); select.AddString("type", item->Type()); fTarget.SendMessage(&select); } // supposed to fall through } case B_CANCEL: PostMessage(B_QUIT_REQUESTED); break; default: BWindow::MessageReceived(message); break; } }
MimeTypeItem* MimeTypeListView::FindItem(const char* type) { if (type == NULL) return NULL; for (int32 i = FullListCountItems(); i-- > 0;) { MimeTypeItem* item = dynamic_cast<MimeTypeItem*>(FullListItemAt(i)); if (item == NULL) continue; if (!strcasecmp(item->Type(), type)) return item; } return NULL; }
void MimeTypeListView::_AddNewType(const char* type) { MimeTypeItem* item = FindItem(type); BMimeType mimeType(type); bool isApp = mimetype_is_application_signature(mimeType); if (fApplicationMode ^ isApp || !mimeType.IsInstalled()) { if (item != NULL) { // type doesn't belong here RemoveItem(item); delete item; } return; } if (item != NULL) { // for some reason, the type already exists return; } BMimeType superType; MimeTypeItem* superItem = NULL; if (mimeType.GetSupertype(&superType) == B_OK) superItem = FindItem(superType.Type()); item = new MimeTypeItem(mimeType, fShowIcons, fSupertype.Type() != NULL); if (item->IsSupertypeOnly()) item->ShowIcon(false); item->SetApplicationMode(isApp); if (superItem != NULL) { AddUnder(item, superItem); InvalidateItem(IndexOf(superItem)); // the super item is not picked up from the class (ie. bug) } else AddItem(item); UpdateItem(item); if (!fSelectNewType.ICompare(mimeType.Type())) { SelectItem(item); fSelectNewType = ""; } }
void MimeTypeListView::_MakeTypesUnique(MimeTypeItem* underItem) { SortItemsUnder(underItem, underItem != NULL, &MimeTypeItem::Compare); bool lastItemSame = false; MimeTypeItem* last = NULL; int32 index = 0; uint32 level = 0; if (underItem != NULL) { index = FullListIndexOf(underItem) + 1; level = underItem->OutlineLevel() + 1; } for (; index < FullListCountItems(); index++) { MimeTypeItem* item = dynamic_cast<MimeTypeItem*>(FullListItemAt(index)); if (item == NULL) continue; if (item->OutlineLevel() < level) { // left sub-tree break; } item->SetText(item->Description()); if (last == NULL || MimeTypeItem::CompareLabels(last, item)) { if (lastItemSame) { last->AddSubtype(); if (Window()) InvalidateItem(IndexOf(last)); } lastItemSame = false; last = item; continue; } lastItemSame = true; last->AddSubtype(); if (Window()) InvalidateItem(IndexOf(last)); last = item; } if (lastItemSame) { last->AddSubtype(); if (Window()) InvalidateItem(IndexOf(last)); } }
void ApplicationTypesWindow::MessageReceived(BMessage* message) { switch (message->what) { case kMsgTypeSelected: { int32 index; if (message->FindInt32("index", &index) == B_OK) { MimeTypeItem* item = (MimeTypeItem*)fTypeListView->ItemAt(index); if (item != NULL) { BMimeType type(item->Type()); _SetType(&type); } else _SetType(NULL); } break; } case kMsgTypeInvoked: { int32 index; if (message->FindInt32("index", &index) == B_OK) { MimeTypeItem* item = (MimeTypeItem*)fTypeListView->ItemAt(index); if (item != NULL) { BMimeType type(item->Type()); entry_ref ref; if (type.GetAppHint(&ref) == B_OK) { BMessage refs(B_REFS_RECEIVED); refs.AddRef("refs", &ref); be_app->PostMessage(&refs); } } } break; } case kMsgEdit: fTypeListView->Invoke(); break; case kMsgRemoveUninstalled: _RemoveUninstalled(); break; case B_META_MIME_CHANGED: { const char* type; int32 which; if (message->FindString("be:type", &type) != B_OK || message->FindInt32("be:which", &which) != B_OK) { break; } if (fCurrentType.Type() == NULL) break; if (!strcasecmp(fCurrentType.Type(), type)) { if (which != B_MIME_TYPE_DELETED) _SetType(&fCurrentType, which); else _SetType(NULL); } break; } default: BWindow::MessageReceived(message); } }
void ApplicationTypesWindow::_RemoveUninstalled() { // Note: this runs in the looper's thread, which isn't that nice int32 removed = 0; volatile bool quit = false; BWindow* progressWindow = new ProgressWindow( B_TRANSLATE("Removing uninstalled application types"), fTypeListView->FullListCountItems(), &quit); progressWindow->AddToSubset(this); progressWindow->Show(); for (int32 i = fTypeListView->FullListCountItems(); i-- > 0 && !quit;) { MimeTypeItem* item = dynamic_cast<MimeTypeItem*> (fTypeListView->FullListItemAt(i)); progressWindow->PostMessage(B_UPDATE_STATUS_BAR); if (item == NULL) continue; // search for application on all volumes bool found = false; BVolumeRoster volumeRoster; BVolume volume; while (volumeRoster.GetNextVolume(&volume) == B_OK) { if (!volume.KnowsQuery()) continue; BQuery query; query.PushAttr("BEOS:APP_SIG"); query.PushString(item->Type()); query.PushOp(B_EQ); query.SetVolume(&volume); query.Fetch(); entry_ref ref; if (query.GetNextRef(&ref) == B_OK) { found = true; break; } } if (!found) { BMimeType mimeType(item->Type()); mimeType.Delete(); removed++; // We're blocking the message loop that received the MIME changes, // so we dequeue all waiting messages from time to time if (removed % 10 == 0) UpdateIfNeeded(); } } progressWindow->PostMessage(B_QUIT_REQUESTED); static BMessageFormat format(B_TRANSLATE("{0, plural, " "one{# Application type could be removed} " "other{# Application types could be removed}}")); BString message; format.Format(message, removed); error_alert(message, B_OK, B_INFO_ALERT); }
void FileTypesWindow::MessageReceived(BMessage* message) { switch (message->what) { case B_SIMPLE_DATA: type_code type; if (message->GetInfo("refs", &type) == B_OK && type == B_REF_TYPE) { be_app->PostMessage(message); } break; case kMsgToggleIcons: { BMenuItem* item; if (message->FindPointer("source", (void **)&item) != B_OK) break; item->SetMarked(!fTypeListView->IsShowingIcons()); fTypeListView->ShowIcons(item->IsMarked()); // update settings BMessage update(kMsgSettingsChanged); update.AddBool("show_icons", item->IsMarked()); be_app_messenger.SendMessage(&update); break; } case kMsgToggleRule: { BMenuItem* item; if (message->FindPointer("source", (void **)&item) != B_OK) break; item->SetMarked(fRuleControl->IsHidden()); _ShowSnifferRule(item->IsMarked()); // update settings BMessage update(kMsgSettingsChanged); update.AddBool("show_rule", item->IsMarked()); be_app_messenger.SendMessage(&update); break; } case kMsgTypeSelected: { int32 index; if (message->FindInt32("index", &index) == B_OK) { MimeTypeItem* item = (MimeTypeItem*)fTypeListView->ItemAt(index); if (item != NULL) { BMimeType type(item->Type()); _SetType(&type); } else _SetType(NULL); } break; } case kMsgAddType: { if (fNewTypeWindow == NULL) { fNewTypeWindow = new NewFileTypeWindow(this, fCurrentType.Type()); fNewTypeWindow->Show(); } else fNewTypeWindow->Activate(); break; } case kMsgNewTypeWindowClosed: fNewTypeWindow = NULL; break; case kMsgRemoveType: { if (fCurrentType.Type() == NULL) break; BAlert* alert; if (fCurrentType.IsSupertypeOnly()) { alert = new BPrivate::OverrideAlert("FileTypes Request", "Removing a super type cannot be reverted.\n" "All file types that belong to this super type " "will be lost!\n\n" "Are you sure you want to do this? To remove the whole " "group, hold down the Shift key and press \"Remove\".", "Remove", B_SHIFT_KEY, "Cancel", 0, NULL, 0, B_WIDTH_AS_USUAL, B_STOP_ALERT); } else { alert = new BAlert("FileTypes Request", "Removing a file type cannot be reverted.\n" "Are you sure you want to remove it?", "Remove", "Cancel", NULL, B_WIDTH_AS_USUAL, B_WARNING_ALERT); } if (alert->Go()) break; status_t status = fCurrentType.Delete(); if (status != B_OK) fprintf(stderr, "Could not remove file type: %s\n", strerror(status)); break; } case kMsgSelectNewType: { const char* type; if (message->FindString("type", &type) == B_OK) fTypeListView->SelectNewType(type); break; } // File Recognition group case kMsgExtensionSelected: { int32 index; if (message->FindInt32("index", &index) == B_OK) { BStringItem* item = (BStringItem*)fExtensionListView->ItemAt(index); fRemoveExtensionButton->SetEnabled(item != NULL); } break; } case kMsgExtensionInvoked: { if (fCurrentType.Type() == NULL) break; int32 index; if (message->FindInt32("index", &index) == B_OK) { BStringItem* item = (BStringItem*)fExtensionListView->ItemAt(index); if (item == NULL) break; BWindow* window = new ExtensionWindow(this, fCurrentType, item->Text()); window->Show(); } break; } case kMsgAddExtension: { if (fCurrentType.Type() == NULL) break; BWindow* window = new ExtensionWindow(this, fCurrentType, NULL); window->Show(); break; } case kMsgRemoveExtension: { int32 index = fExtensionListView->CurrentSelection(); if (index < 0 || fCurrentType.Type() == NULL) break; BMessage extensions; if (fCurrentType.GetFileExtensions(&extensions) == B_OK) { extensions.RemoveData("extensions", index); fCurrentType.SetFileExtensions(&extensions); } break; } case kMsgRuleEntered: { // check rule BString parseError; if (BMimeType::CheckSnifferRule(fRuleControl->Text(), &parseError) != B_OK) { parseError.Prepend("Recognition rule is not valid:\n\n"); error_alert(parseError.String()); } else fCurrentType.SetSnifferRule(fRuleControl->Text()); break; } // Description group case kMsgTypeEntered: { fCurrentType.SetShortDescription(fTypeNameControl->Text()); break; } case kMsgDescriptionEntered: { fCurrentType.SetLongDescription(fDescriptionControl->Text()); break; } // Preferred Application group case kMsgPreferredAppChosen: { const char* signature; if (message->FindString("signature", &signature) != B_OK) signature = NULL; fCurrentType.SetPreferredApp(signature); break; } case kMsgSelectPreferredApp: { BMessage panel(kMsgOpenFilePanel); panel.AddString("title", "Select preferred application"); panel.AddInt32("message", kMsgPreferredAppOpened); panel.AddMessenger("target", this); be_app_messenger.SendMessage(&panel); break; } case kMsgPreferredAppOpened: _AdoptPreferredApplication(message, false); break; case kMsgSamePreferredAppAs: { BMessage panel(kMsgOpenFilePanel); panel.AddString("title", "Select same preferred application as"); panel.AddInt32("message", kMsgSamePreferredAppAsOpened); panel.AddMessenger("target", this); be_app_messenger.SendMessage(&panel); break; } case kMsgSamePreferredAppAsOpened: _AdoptPreferredApplication(message, true); break; // Extra Attributes group case kMsgAttributeSelected: { int32 index; if (message->FindInt32("index", &index) == B_OK) { AttributeItem* item = (AttributeItem*)fAttributeListView->ItemAt(index); fRemoveAttributeButton->SetEnabled(item != NULL); } break; } case kMsgAttributeInvoked: { if (fCurrentType.Type() == NULL) break; int32 index; if (message->FindInt32("index", &index) == B_OK) { AttributeItem* item = (AttributeItem*)fAttributeListView->ItemAt(index); if (item == NULL) break; BWindow* window = new AttributeWindow(this, fCurrentType, item); window->Show(); } break; } case kMsgAddAttribute: { if (fCurrentType.Type() == NULL) break; BWindow* window = new AttributeWindow(this, fCurrentType, NULL); window->Show(); break; } case kMsgRemoveAttribute: { int32 index = fAttributeListView->CurrentSelection(); if (index < 0 || fCurrentType.Type() == NULL) break; BMessage attributes; if (fCurrentType.GetAttrInfo(&attributes) == B_OK) { const char* kAttributeNames[] = { "attr:public_name", "attr:name", "attr:type", "attr:editable", "attr:viewable", "attr:extra", "attr:alignment", "attr:width", "attr:display_as" }; for (uint32 i = 0; i < sizeof(kAttributeNames) / sizeof(kAttributeNames[0]); i++) { attributes.RemoveData(kAttributeNames[i], index); } fCurrentType.SetAttrInfo(&attributes); } break; } case B_META_MIME_CHANGED: { const char* type; int32 which; if (message->FindString("be:type", &type) != B_OK || message->FindInt32("be:which", &which) != B_OK) break; if (fCurrentType.Type() == NULL) break; if (!strcasecmp(fCurrentType.Type(), type)) { if (which != B_MIME_TYPE_DELETED) _SetType(&fCurrentType, which); else _SetType(NULL); } else { // this change could still affect our current type if (which == B_MIME_TYPE_DELETED #ifdef __ANTARES__ || which == B_SUPPORTED_TYPES_CHANGED #endif || which == B_PREFERRED_APP_CHANGED) _UpdatePreferredApps(&fCurrentType); } break; } default: BWindow::MessageReceived(message); } }