Tracker: Various sorting issues in Tracker
When sorting files by Modified dates, right clicking on a file was leading to a sorting issue where files were changing positions (without reason). 1. Any changes to stats (size, modification, creation, mode) was triggering the sorting. Now only stats fields currently used as a Sort criteria will trigger such event. 2. The Mimeset of file was set (in case of unknown file format) once per checked add-on when building AddOn Menu. Now it's checked once per file in selection. (so, once per file, rather then once per file, per add-on). 3. Now rely on registrar to force the mimeset (to trigger the sniffer in case the attribute already exist) rather than trying to duplicate the feature in Tracker. 4. When Sorting, if there is a old position known, check if it's working by looking if you should come after the previous item, and before the following item. Previously, the item would be pushed at the top if the group of item all fitting the criteria (same file size, same file kind, etc.. depending on the sorting criteria). Fixes #8478.
This commit is contained in:
parent
8cf6d28f99
commit
674ff0df2f
@ -318,12 +318,7 @@ static void
|
||||
AddMimeTypeString(BObjectList<BString> &list, Model *model)
|
||||
{
|
||||
BString *mimeType = new BString(model->MimeType());
|
||||
if (!mimeType->Length() || !mimeType->ICompare(B_FILE_MIMETYPE)) {
|
||||
// if model is of unknown type, try mimeseting it first
|
||||
model->Mimeset(true);
|
||||
mimeType->SetTo(model->MimeType());
|
||||
}
|
||||
|
||||
|
||||
if (mimeType->Length()) {
|
||||
// only add the type if it's not already there
|
||||
for (int32 i = list.CountItems(); i-- > 0;) {
|
||||
@ -2975,6 +2970,8 @@ BContainerWindow::BuildAddOnMenu(BMenu *menu)
|
||||
break;
|
||||
delete item;
|
||||
}
|
||||
|
||||
_UpdateSelectionMIMEInfo();
|
||||
|
||||
BObjectList<BMenuItem> primaryList;
|
||||
BObjectList<BMenuItem> secondaryList;
|
||||
@ -3141,6 +3138,29 @@ BContainerWindow::LoadAddOn(BMessage *message)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BContainerWindow::_UpdateSelectionMIMEInfo()
|
||||
{
|
||||
BPose* pose;
|
||||
int32 index = 0;
|
||||
while ((pose = PoseView()->SelectionList()->ItemAt(index++)) != NULL) {
|
||||
BString mimeType(pose->TargetModel()->MimeType());
|
||||
if (!mimeType.Length() || mimeType.ICompare(B_FILE_MIMETYPE) == 0) {
|
||||
pose->TargetModel()->Mimeset(true);
|
||||
if (pose->TargetModel()->IsSymLink()) {
|
||||
Model* resolved = new Model(pose->TargetModel()->EntryRef(), true, true);
|
||||
if (resolved->InitCheck() == B_OK) {
|
||||
mimeType.SetTo(resolved->MimeType());
|
||||
if (!mimeType.Length() || mimeType.ICompare(B_FILE_MIMETYPE) == 0)
|
||||
resolved->Mimeset(true);
|
||||
}
|
||||
delete resolved;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BMenuItem *
|
||||
BContainerWindow::NewAttributeMenuItem(const char *label, const char *name,
|
||||
int32 type, float width, int32 align, bool editable, bool statField)
|
||||
|
@ -303,6 +303,8 @@ class BContainerWindow : public BWindow {
|
||||
|
||||
friend int32 show_context_menu(void*);
|
||||
friend class BackgroundView;
|
||||
|
||||
void _UpdateSelectionMIMEInfo();
|
||||
};
|
||||
|
||||
class WindowStateNodeOpener {
|
||||
|
@ -1178,18 +1178,11 @@ bool
|
||||
Model::Mimeset(bool force)
|
||||
{
|
||||
BString oldType = MimeType();
|
||||
ModelNodeLazyOpener opener(this);
|
||||
BPath path;
|
||||
GetPath(&path);
|
||||
if (force) {
|
||||
if (opener.OpenNode(true) != B_OK)
|
||||
return false;
|
||||
|
||||
Node()->RemoveAttr(kAttrMIMEType);
|
||||
update_mime_info(path.Path(), 0, 1, 1);
|
||||
} else
|
||||
update_mime_info(path.Path(), 0, 1, 0);
|
||||
|
||||
update_mime_info(path.Path(), 0, 1, force ? 2 : 0);
|
||||
|
||||
AttrChanged(0);
|
||||
|
||||
return !oldType.ICompare(MimeType());
|
||||
|
@ -1674,7 +1674,7 @@ BPoseView::AddPoseToList(PoseList *list, bool visibleList, bool insertionSort,
|
||||
bool needToDraw = true;
|
||||
|
||||
if (insertionSort && list->CountItems()) {
|
||||
int32 orientation = BSearchList(list, pose, &poseIndex);
|
||||
int32 orientation = BSearchList(list, pose, &poseIndex, 0);
|
||||
|
||||
if (orientation == kInsertAfter)
|
||||
poseIndex++;
|
||||
@ -5359,6 +5359,12 @@ BPoseView::EntryMoved(const BMessage *message)
|
||||
}
|
||||
|
||||
|
||||
struct attrColumnRelation {
|
||||
uint32 attrHash;
|
||||
int32 fieldMask;
|
||||
};
|
||||
|
||||
|
||||
bool
|
||||
BPoseView::AttributeChanged(const BMessage *message)
|
||||
{
|
||||
@ -5430,7 +5436,6 @@ BPoseView::AttributeChanged(const BMessage *message)
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 attrHash;
|
||||
if (attrName) {
|
||||
// rebuild the MIME type list, if the MIME type has changed
|
||||
if (strcmp(attrName, kAttrMIMEType) == 0)
|
||||
@ -5438,14 +5443,41 @@ BPoseView::AttributeChanged(const BMessage *message)
|
||||
|
||||
// note: the following code is wrong, because this sort of hashing
|
||||
// may overlap and we get aliasing
|
||||
attrHash = AttrHashString(attrName, info.type);
|
||||
}
|
||||
uint32 attrHash = AttrHashString(attrName, info.type);
|
||||
if (attrHash == PrimarySort() || attrHash == SecondarySort()) {
|
||||
_CheckPoseSortOrder(fPoseList, pose, poseListIndex);
|
||||
if (fFiltering && visible)
|
||||
_CheckPoseSortOrder(fFilteredPoseList, pose, index);
|
||||
}
|
||||
} else {
|
||||
int32 fields;
|
||||
if (message->FindInt32("fields", &fields) != B_OK)
|
||||
return true;
|
||||
|
||||
if (!attrName || attrHash == PrimarySort()
|
||||
|| attrHash == SecondarySort()) {
|
||||
_CheckPoseSortOrder(fPoseList, pose, poseListIndex);
|
||||
if (fFiltering && visible)
|
||||
_CheckPoseSortOrder(fFilteredPoseList, pose, index);
|
||||
static struct attrColumnRelation attributs[] = {
|
||||
{ AttrHashString(kAttrStatModified, B_TIME_TYPE),
|
||||
B_STAT_MODIFICATION_TIME },
|
||||
{ AttrHashString(kAttrStatSize, B_OFF_T_TYPE),
|
||||
B_STAT_SIZE },
|
||||
{ AttrHashString(kAttrStatCreated, B_TIME_TYPE),
|
||||
B_STAT_CREATION_TIME },
|
||||
{ AttrHashString(kAttrStatMode, B_STRING_TYPE),
|
||||
B_STAT_MODE }
|
||||
};
|
||||
|
||||
for (int32 i = sizeof(attributs) / sizeof(attrColumnRelation);
|
||||
i--;) {
|
||||
if (attributs[i].attrHash == PrimarySort()
|
||||
|| attributs[i].attrHash == SecondarySort()) {
|
||||
|
||||
if (fields & attributs[i].fieldMask) {
|
||||
_CheckPoseSortOrder(fPoseList, pose, poseListIndex);
|
||||
if (fFiltering && visible)
|
||||
_CheckPoseSortOrder(fFilteredPoseList, pose, index);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// we received an attr changed notification for a zombie model, it means
|
||||
@ -8667,7 +8699,7 @@ BPoseView::_CheckPoseSortOrder(PoseList *poseList, BPose *pose, int32 oldIndex)
|
||||
// take pose out of list for BSearch
|
||||
poseList->RemoveItemAt(oldIndex);
|
||||
int32 afterIndex;
|
||||
int32 orientation = BSearchList(poseList, pose, &afterIndex);
|
||||
int32 orientation = BSearchList(poseList, pose, &afterIndex, oldIndex);
|
||||
|
||||
int32 newIndex;
|
||||
if (orientation == kInsertAtFront)
|
||||
@ -8777,19 +8809,33 @@ BSearch(PoseList *table, const BPose* key, BPoseView *view,
|
||||
|
||||
int32
|
||||
BPoseView::BSearchList(PoseList *poseList, const BPose *pose,
|
||||
int32 *resultingIndex)
|
||||
int32 *resultingIndex, int32 oldIndex)
|
||||
{
|
||||
// check to see if insertion should be at beginning of list
|
||||
const BPose *firstPose = poseList->FirstItem();
|
||||
if (!firstPose)
|
||||
return kInsertAtFront;
|
||||
|
||||
if (PoseCompareAddWidget(pose, firstPose, this) <= 0) {
|
||||
return kInsertAtFront;
|
||||
|
||||
if (PoseCompareAddWidget(pose, firstPose, this) < 0) {
|
||||
*resultingIndex = 0;
|
||||
return kInsertAtFront;
|
||||
}
|
||||
|
||||
int32 count = poseList->CountItems();
|
||||
|
||||
// look if old position is still ok, by comparing to siblings
|
||||
bool valid = oldIndex > 0 && oldIndex < count - 1;
|
||||
valid = valid && PoseCompareAddWidget(pose,
|
||||
poseList->ItemAt(oldIndex - 1), this) >= 0;
|
||||
// the current item is gone, so not oldIndex+1
|
||||
valid = valid && PoseCompareAddWidget(pose,
|
||||
poseList->ItemAt(oldIndex), this) <= 0;
|
||||
|
||||
if (valid) {
|
||||
*resultingIndex = oldIndex - 1;
|
||||
return kInsertAfter;
|
||||
}
|
||||
|
||||
*resultingIndex = count - 1;
|
||||
|
||||
const BPose *searchResult = BSearch(poseList, pose, this,
|
||||
|
@ -520,7 +520,8 @@ class BPoseView : public BView {
|
||||
void DrawViewCommon(const BRect &updateRect);
|
||||
|
||||
// pose list handling
|
||||
int32 BSearchList(PoseList *poseList, const BPose *, int32 *index);
|
||||
int32 BSearchList(PoseList *poseList, const BPose *, int32 *index,
|
||||
int32 oldIndex);
|
||||
void InsertPoseAfter(BPose *pose, int32 *index, int32 orientation,
|
||||
BRect *invalidRect);
|
||||
// does a CopyBits to scroll poses making room for a new pose,
|
||||
|
Loading…
Reference in New Issue
Block a user