aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilippe Saint-Pierre <stpere@gmail.com>2012-07-22 22:04:28 -0400
committerPhilippe Saint-Pierre <stpere@gmail.com>2012-07-22 22:16:19 -0400
commit674ff0df2f2eb00cbc78b4384fcf5b148a2139ff (patch)
treee2cb0944877140e13a7131ae927cc0ade0540830
parent8cf6d28f996f132095d5f61c0b5622168c39ae91 (diff)
Tracker: Various sorting issues in Trackerhrev44384
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.
-rw-r--r--src/kits/tracker/ContainerWindow.cpp32
-rw-r--r--src/kits/tracker/ContainerWindow.h2
-rw-r--r--src/kits/tracker/Model.cpp11
-rw-r--r--src/kits/tracker/PoseView.cpp74
-rw-r--r--src/kits/tracker/PoseView.h3
5 files changed, 92 insertions, 30 deletions
diff --git a/src/kits/tracker/ContainerWindow.cpp b/src/kits/tracker/ContainerWindow.cpp
index bcbb092d4f..b48b683e77 100644
--- a/src/kits/tracker/ContainerWindow.cpp
+++ b/src/kits/tracker/ContainerWindow.cpp
@@ -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)
diff --git a/src/kits/tracker/ContainerWindow.h b/src/kits/tracker/ContainerWindow.h
index 5bee938731..373b81a7a1 100644
--- a/src/kits/tracker/ContainerWindow.h
+++ b/src/kits/tracker/ContainerWindow.h
@@ -303,6 +303,8 @@ class BContainerWindow : public BWindow {
friend int32 show_context_menu(void*);
friend class BackgroundView;
+
+ void _UpdateSelectionMIMEInfo();
};
class WindowStateNodeOpener {
diff --git a/src/kits/tracker/Model.cpp b/src/kits/tracker/Model.cpp
index 392b8e4d08..7f5ea56b7f 100644
--- a/src/kits/tracker/Model.cpp
+++ b/src/kits/tracker/Model.cpp
@@ -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());
diff --git a/src/kits/tracker/PoseView.cpp b/src/kits/tracker/PoseView.cpp
index 1bc5078d98..0a69b0eaf2 100644
--- a/src/kits/tracker/PoseView.cpp
+++ b/src/kits/tracker/PoseView.cpp
@@ -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,
diff --git a/src/kits/tracker/PoseView.h b/src/kits/tracker/PoseView.h
index 65a7f6a802..ce6fd0b728 100644
--- a/src/kits/tracker/PoseView.h
+++ b/src/kits/tracker/PoseView.h
@@ -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,