status_t Model::OpenNode(bool writable) { if (IsNodeOpen() && (writable == IsNodeOpenForWriting())) return B_OK; OpenNodeCommon(writable); return fStatus; }
bool Model::StatChanged() { ASSERT(IsNodeOpen()); mode_t oldMode = fStatBuf.st_mode; fStatus = fNode->GetStat(&fStatBuf); if (oldMode != fStatBuf.st_mode) { bool forWriting = IsNodeOpenForWriting(); CloseNode(); //SetupBaseType(); // the node type can't change with a stat update... OpenNodeCommon(forWriting); return true; } return false; }
bool Model::AttrChanged(const char* attrName) { // called on an attribute changed node monitor // sync up cached values of mime type and preferred app and // return true if icon needs updating ASSERT(IsNodeOpen()); if (attrName != NULL && (strcmp(attrName, kAttrIcon) == 0 || strcmp(attrName, kAttrMiniIcon) == 0 || strcmp(attrName, kAttrLargeIcon) == 0)) { return true; } if (attrName == NULL || strcmp(attrName, kAttrMIMEType) == 0 || strcmp(attrName, kAttrPreferredApp) == 0) { char mimeString[B_MIME_TYPE_LENGTH]; BNodeInfo info(fNode); if (info.GetType(mimeString) != B_OK) fMimeType = ""; else { // node has a specific mime type fMimeType = mimeString; if (!IsVolume() && !IsSymLink() && info.GetPreferredApp(mimeString) == B_OK) { SetPreferredAppSignature(mimeString); } } #if xDEBUG if (fIconFrom != kNode) { PRINT(("%s, %s:updating icon because file type changed\n", Name(), attrName != NULL ? attrName : "")); } else { PRINT(("Not updating icon even though type changed " "because icon is from node.\n")); } #endif return fIconFrom != kNode; // update icon unless it is coming from a node } return attrName == NULL; }
status_t Model::UpdateStatAndOpenNode(bool writable) { if (IsNodeOpen() && (writable == IsNodeOpenForWriting())) return B_OK; // try reading the stat structure again BEntry tmpEntry(&fEntryRef); fStatus = tmpEntry.InitCheck(); if (fStatus != B_OK) return fStatus; fStatus = tmpEntry.GetStat(&fStatBuf); if (fStatus != B_OK) return fStatus; OpenNodeCommon(writable); return fStatus; }
void Model::FinishSettingUpType() { char mimeString[B_MIME_TYPE_LENGTH]; // while we are reading the node, do a little // snooping to see if it even makes sense to look for a node-based // icon // This serves as a hint to the icon cache, allowing it to not hit the // disk again for models that do not have an icon defined by the node if (IsNodeOpen() && fBaseType != kLinkNode && !CheckNodeIconHintPrivate(fNode, dynamic_cast<TTracker *>(be_app) == NULL)) { // when checking for the node icon hint, if we are libtracker, only check // for small icons - checking for the large icons is a little more // work for the filesystem and this will speed up the test. // This makes node icons only work if there is a small and a large node // icon on a file - for libtracker that is not a problem though fIconFrom = kUnknownNotFromNode; } if (fBaseType != kDirectoryNode && fBaseType != kVolumeNode && fBaseType != kLinkNode && IsNodeOpen()) { BNodeInfo info(fNode); // check if a specific mime type is set if (info.GetType(mimeString) == B_OK) { // node has a specific mime type fMimeType = mimeString; if (strcmp(mimeString, B_QUERY_MIMETYPE) == 0) fBaseType = kQueryNode; else if (strcmp(mimeString, B_QUERY_TEMPLATE_MIMETYPE) == 0) fBaseType = kQueryTemplateNode; if (info.GetPreferredApp(mimeString) == B_OK) { if (fPreferredAppName) DeletePreferredAppVolumeNameLinkTo(); if (mimeString[0]) fPreferredAppName = strdup(mimeString); } } } switch (fBaseType) { case kDirectoryNode: fMimeType = B_DIR_MIMETYPE; // should use a shared string here if (IsNodeOpen()) { BNodeInfo info(fNode); if (info.GetType(mimeString) == B_OK) fMimeType = mimeString; if (fIconFrom == kUnknownNotFromNode && WellKnowEntryList::Match(NodeRef()) > (directory_which)-1) // one of home, beos, system, boot, etc. fIconFrom = kTrackerSupplied; } break; case kVolumeNode: { if (NodeRef()->node == fEntryRef.directory && NodeRef()->device == fEntryRef.device) { // promote from volume to file system root fBaseType = kRootNode; fMimeType = B_ROOT_MIMETYPE; break; } // volumes have to have a B_VOLUME_MIMETYPE type fMimeType = B_VOLUME_MIMETYPE; if (fIconFrom == kUnknownNotFromNode) { if (WellKnowEntryList::Match(NodeRef()) > (directory_which)-1) fIconFrom = kTrackerSupplied; else fIconFrom = kVolume; } char name[B_FILE_NAME_LENGTH]; BVolume volume(NodeRef()->device); if (volume.InitCheck() == B_OK && volume.GetName(name) == B_OK) { if (fVolumeName) DeletePreferredAppVolumeNameLinkTo(); fVolumeName = strdup(name); } #if DEBUG else PRINT(("get volume name failed for %s\n", fEntryRef.name)); #endif break; } case kLinkNode: fMimeType = B_LINK_MIMETYPE; // should use a shared string here break; case kExecutableNode: if (IsNodeOpen()) { char signature[B_MIME_TYPE_LENGTH]; if (GetAppSignatureFromAttr(dynamic_cast<BFile *>(fNode), signature) == B_OK) { if (fPreferredAppName) DeletePreferredAppVolumeNameLinkTo(); if (signature[0]) fPreferredAppName = strdup(signature); } } if (!fMimeType.Length()) fMimeType = B_APP_MIME_TYPE; // should use a shared string here break; default: if (!fMimeType.Length()) fMimeType = B_FILE_MIMETYPE; break; } }
status_t Model::OpenNodeCommon(bool writable) { #if xDEBUG PRINT(("opening node for %s\n", Name())); #endif #ifdef CHECK_OPEN_MODEL_LEAKS if (writableOpenModelList) writableOpenModelList->RemoveItem(this); if (readOnlyOpenModelList) readOnlyOpenModelList->RemoveItem(this); #endif if (fBaseType == kUnknownNode) SetupBaseType(); switch (fBaseType) { case kPlainNode: case kExecutableNode: case kQueryNode: case kQueryTemplateNode: // open or reopen delete fNode; fNode = new BFile(&fEntryRef, (uint32)(writable ? O_RDWR : O_RDONLY)); break; case kDirectoryNode: case kVolumeNode: case kRootNode: if (!IsNodeOpen()) fNode = new BDirectory(&fEntryRef); if (fBaseType == kDirectoryNode && static_cast<BDirectory *>(fNode)->IsRootDirectory()) { // promote from directory to volume fBaseType = kVolumeNode; } break; case kLinkNode: if (!IsNodeOpen()) { BEntry entry(&fEntryRef); fNode = new BSymLink(&entry); } break; default: #if DEBUG PrintToStream(); #endif TRESPASS(); // this can only happen if GetStat failed before, in which case // we shouldn't be here // ToDo: Obviously, we can also be here if the type could not be determined, // for example for block devices (so the TRESPASS() macro shouldn't be // used here)! return fStatus = B_ERROR; } fStatus = fNode->InitCheck(); if (fStatus != B_OK) { delete fNode; fNode = NULL; // original code snoozed an error here and returned B_OK return fStatus; } fWritable = writable; if (!fMimeType.Length()) FinishSettingUpType(); #ifdef CHECK_OPEN_MODEL_LEAKS if (fWritable) { if (!writableOpenModelList) { TRACE(); writableOpenModelList = new BObjectList<Model>(100); } writableOpenModelList->AddItem(this); } else { if (!readOnlyOpenModelList) { TRACE(); readOnlyOpenModelList = new BObjectList<Model>(100); } readOnlyOpenModelList->AddItem(this); } #endif return fStatus; }
void Model::PrintToStream(int32 level, bool deep) { PRINT(("model name %s, entry name %s, inode %Lx, dev %x, directory inode %Lx\n", Name() ? Name() : "**empty name**", EntryRef()->name ? EntryRef()->name : "**empty ref name**", NodeRef()->node, NodeRef()->device, EntryRef()->directory)); PRINT(("type %s \n", MimeType())); PRINT(("model type: ")); switch (fBaseType) { case kPlainNode: PRINT(("plain\n")); break; case kQueryNode: PRINT(("query\n")); break; case kQueryTemplateNode: PRINT(("query template\n")); break; case kExecutableNode: PRINT(("exe\n")); break; case kDirectoryNode: PRINT(("dir\n")); break; case kLinkNode: PRINT(("link\n")); break; case kRootNode: PRINT(("root\n")); break; case kVolumeNode: PRINT(("volume, name %s\n", fVolumeName ? fVolumeName : "")); break; default: PRINT(("unknown\n")); break; } if (level < 1) return; if (!IsVolume()) PRINT(("preferred app %s\n", fPreferredAppName ? fPreferredAppName : "")); PRINT(("icon from: ")); switch (IconFrom()) { case kUnknownSource: PRINT(("unknown\n")); break; case kUnknownNotFromNode: PRINT(("unknown but not from a node\n")); break; case kTrackerDefault: PRINT(("tracker default\n")); break; case kTrackerSupplied: PRINT(("tracker supplied\n")); break; case kMetaMime: PRINT(("metamime\n")); break; case kPreferredAppForType: PRINT(("preferred app for type\n")); break; case kPreferredAppForNode: PRINT(("preferred app for node\n")); break; case kNode: PRINT(("node\n")); break; case kVolume: PRINT(("volume\n")); break; } PRINT(("model %s opened %s \n", !IsNodeOpen() ? "not " : "", IsNodeOpenForWriting() ? "for writing" : "")); if (IsNodeOpen()) { node_ref nodeRef; fNode->GetNodeRef(&nodeRef); PRINT(("node ref of open Node %Lx %x\n", nodeRef.node, nodeRef.device)); } if (deep && IsSymLink()) { BEntry tmpEntry(EntryRef(), true); Model tmp(&tmpEntry); PRINT(("symlink to:\n")); tmp.PrintToStream(); } TrackIconSource(B_MINI_ICON); TrackIconSource(B_LARGE_ICON); }
void Model::FinishSettingUpType() { char mimeString[B_MIME_TYPE_LENGTH]; BEntry entry; // While we are reading the node, do a little snooping to see if it even // makes sense to look for a node-based icon. This serves as a hint to the // icon cache, allowing it to not hit the disk again for models that do not // have an icon defined by the node. if (IsNodeOpen() && fBaseType != kLinkNode && !CheckNodeIconHint(fNode)) fIconFrom = kUnknownNotFromNode; if (fBaseType != kDirectoryNode && fBaseType != kVolumeNode && fBaseType != kLinkNode && IsNodeOpen()) { BNodeInfo info(fNode); // check if a specific mime type is set if (info.GetType(mimeString) == B_OK) { // node has a specific mime type fMimeType = mimeString; if (strcmp(mimeString, B_QUERY_MIMETYPE) == 0) fBaseType = kQueryNode; else if (strcmp(mimeString, B_QUERY_TEMPLATE_MIMETYPE) == 0) fBaseType = kQueryTemplateNode; else if (strcmp(mimeString, kVirtualDirectoryMimeType) == 0) fBaseType = kVirtualDirectoryNode; if (info.GetPreferredApp(mimeString) == B_OK) { if (fPreferredAppName) DeletePreferredAppVolumeNameLinkTo(); if (mimeString[0]) fPreferredAppName = strdup(mimeString); } } } switch (fBaseType) { case kDirectoryNode: entry.SetTo(&fEntryRef); if (entry.InitCheck() == B_OK) { if (FSIsTrashDir(&entry)) fBaseType = kTrashNode; else if (FSIsDeskDir(&entry)) fBaseType = kDesktopNode; } fMimeType = B_DIR_MIMETYPE; // should use a shared string here if (IsNodeOpen()) { BNodeInfo info(fNode); if (info.GetType(mimeString) == B_OK) fMimeType = mimeString; if (fIconFrom == kUnknownNotFromNode && WellKnowEntryList::Match(NodeRef()) > (directory_which)-1) { // one of home, beos, system, boot, etc. fIconFrom = kTrackerSupplied; } } break; case kVolumeNode: { if (NodeRef()->node == fEntryRef.directory && NodeRef()->device == fEntryRef.device) { // promote from volume to file system root fBaseType = kRootNode; fMimeType = B_ROOT_MIMETYPE; break; } // volumes have to have a B_VOLUME_MIMETYPE type fMimeType = B_VOLUME_MIMETYPE; if (fIconFrom == kUnknownNotFromNode) { if (WellKnowEntryList::Match(NodeRef()) > (directory_which)-1) fIconFrom = kTrackerSupplied; else fIconFrom = kVolume; } char name[B_FILE_NAME_LENGTH]; BVolume volume(NodeRef()->device); if (volume.InitCheck() == B_OK && volume.GetName(name) == B_OK) { if (fVolumeName != NULL) DeletePreferredAppVolumeNameLinkTo(); fVolumeName = strdup(name); } #if DEBUG else PRINT(("get volume name failed for %s\n", fEntryRef.name)); #endif break; } case kLinkNode: fMimeType = B_LINK_MIMETYPE; // should use a shared string here break; case kExecutableNode: if (IsNodeOpen()) { char signature[B_MIME_TYPE_LENGTH]; if (GetAppSignatureFromAttr(dynamic_cast<BFile*>(fNode), signature) == B_OK) { if (fPreferredAppName) DeletePreferredAppVolumeNameLinkTo(); if (signature[0]) fPreferredAppName = strdup(signature); } } if (fMimeType.Length() <= 0) fMimeType = B_APP_MIME_TYPE; // should use a shared string here break; default: if (fMimeType.Length() <= 0) fMimeType = B_FILE_MIMETYPE; break; } }