Ticket #1247: periodic_update_poses.diff
File periodic_update_poses.diff, 14.0 KB (added by , 17 years ago) |
---|
-
src/kits/tracker/PoseList.h
64 64 BPose *DeepFindPose(const node_ref *node, int32 *index = NULL) const; 65 65 // same as FindPose, node can be a target of the actual 66 66 // pose if the pose is a symlink 67 BPose *FindVolumePose(const dev_t device, int32 *index = NULL) const;68 67 }; 69 68 70 69 // iteration glue, add permutations as needed -
src/kits/tracker/SettingsViews.cpp
1072 1072 { 1073 1073 settings.SetShowVolumeSpaceBar(fSpaceBarShowCheckBox->Value() == 1); 1074 1074 Window()->PostMessage(kSettingsContentsModified); 1075 BMessage notificationMessage; 1076 notificationMessage.AddBool("ShowVolumeSpaceBar", settings.ShowVolumeSpaceBar()); 1077 tracker->SendNotices(kShowVolumeSpaceBar, ¬ificationMessage); 1075 tracker->PostMessage(kShowVolumeSpaceBar); 1078 1076 break; 1079 1077 } 1080 1078 … … 1094 1092 } 1095 1093 break; 1096 1094 } 1095 1097 1096 case kSpaceBarColorChanged: 1098 1097 { 1099 1098 switch (fCurrentColor) { … … 1109 1108 } 1110 1109 1111 1110 Window()->PostMessage(kSettingsContentsModified); 1112 BMessage notificationMessage; 1113 tracker->SendNotices(kSpaceBarColorChanged, ¬ificationMessage); 1111 tracker->PostMessage(kSpaceBarColorChanged); 1114 1112 break; 1115 1113 } 1116 1114 -
src/kits/tracker/PoseView.cpp
803 803 app->StopWatching(this, kShowSelectionWhenInactiveChanged); 804 804 app->StopWatching(this, kTransparentSelectionChanged); 805 805 app->StopWatching(this, kSortFolderNamesFirstChanged); 806 app->StopWatching(this, kShowVolumeSpaceBar);807 app->StopWatching(this, kSpaceBarColorChanged);808 app->StopWatching(this, kUpdateVolumeSpaceBar);809 806 app->Unlock(); 810 807 } 811 808 … … 890 887 app->StartWatching(this, kShowSelectionWhenInactiveChanged); 891 888 app->StartWatching(this, kTransparentSelectionChanged); 892 889 app->StartWatching(this, kSortFolderNamesFirstChanged); 893 app->StartWatching(this, kShowVolumeSpaceBar);894 app->StartWatching(this, kSpaceBarColorChanged);895 app->StartWatching(this, kUpdateVolumeSpaceBar);896 890 app->Unlock(); 897 891 } 898 892 … … 2331 2325 Invalidate(); 2332 2326 } 2333 2327 break; 2334 2335 case kShowVolumeSpaceBar:2336 bool enabled;2337 if (message->FindBool("ShowVolumeSpaceBar", &enabled) == B_OK)2338 TrackerSettings().SetShowVolumeSpaceBar(enabled);2339 // supposed to fall through2340 case kSpaceBarColorChanged:2341 UpdateVolumeIcons();2342 break;2343 case kUpdateVolumeSpaceBar:2344 dev_t device;2345 message->FindInt32("device", (int32 *)&device);2346 UpdateVolumeIcon(device);2347 break;2348 2328 } 2349 2329 } 2350 2330 break; … … 5214 5194 5215 5195 5216 5196 void 5217 BPoseView::Update VolumeIcon(dev_t device, bool forceUpdate)5197 BPoseView::UpdateIcon(BPose *pose) 5218 5198 { 5219 int32 index; 5220 BPose *pose = fPoseList->FindVolumePose(device,&index); 5221 if (pose == NULL) 5222 return; 5223 5224 if (pose->UpdateVolumeSpaceBar(TrackerSettings().ShowVolumeSpaceBar()) || forceUpdate) { 5225 BPoint loc(0, index * fListElemHeight); 5226 pose->UpdateIcon(loc, this); 5199 BPoint location; 5200 if (ViewMode() == kListMode) { 5201 // need to find the index of the pose in the pose list 5202 int32 count = fPoseList->CountItems(); 5203 for (int32 index = 0; index < count; index++) { 5204 if (fPoseList->ItemAt(index) == pose) { 5205 location.Set(0, index * fListElemHeight); 5206 break; 5207 } 5208 } 5227 5209 } 5228 }5229 5210 5230 5231 void 5232 BPoseView::UpdateVolumeIcons() 5233 { 5234 BVolumeRoster roster; 5235 5236 BVolume volume; 5237 while(roster.GetNextVolume(&volume) == B_NO_ERROR) { 5238 BDirectory dir; 5239 volume.GetRootDirectory(&dir); 5240 node_ref nodeRef; 5241 dir.GetNodeRef(&nodeRef); 5242 5243 UpdateVolumeIcon(nodeRef.device, true); 5244 } 5211 pose->UpdateIcon(location, this); 5245 5212 } 5246 5213 5247 5214 -
src/kits/tracker/Tracker.cpp
483 483 break; 484 484 } 485 485 486 case kShowVolumeSpaceBar: 487 case kSpaceBarColorChanged: { 488 gPeriodicUpdatePoses.DoPeriodicUpdate(true); 489 break; 490 } 491 486 492 default: 487 493 _inherited::MessageReceived(message); 488 494 break; … … 497 503 return; 498 504 499 505 // update the volume icon's free space bars 500 BVolumeRoster roster; 501 502 BVolume volume; 503 while (roster.GetNextVolume(&volume) == B_OK) { 504 BDirectory dir; 505 volume.GetRootDirectory(&dir); 506 node_ref nodeRef; 507 dir.GetNodeRef(&nodeRef); 508 509 BMessage notificationMessage; 510 notificationMessage.AddInt32("device", *(int32 *)&nodeRef.device); 511 512 SendNotices(kUpdateVolumeSpaceBar, ¬ificationMessage); 513 } 506 gPeriodicUpdatePoses.DoPeriodicUpdate(false); 514 507 } 515 508 516 509 -
src/kits/tracker/Pose.cpp
49 49 50 50 51 51 int32 52 CalcFreeSpace( dev_t device)52 CalcFreeSpace(BVolume *volume) 53 53 { 54 BVolume volume(device); 55 fs_info info; 56 if (volume.InitCheck() == B_OK && fs_stat_dev(device,&info) == B_OK) { 57 // Philosophy here: 58 // Bars go on all drives with read/write capabilities 59 // Exceptions: Not on CDDA, but on NTFS/Ext2 60 // Also note that some volumes may return 0 when 61 // BVolume::Capacity() is called (believe-me... That *DOES* 62 // happen) so we also check for that. 63 off_t capacity = volume.Capacity(); 64 if (((!volume.IsReadOnly() && strcmp(info.fsh_name,"cdda")) 65 || !strcmp(info.fsh_name,"ntfs") 66 || !strcmp(info.fsh_name,"ext2")) 67 && (capacity > 0)) { 68 int32 percent = static_cast<int32>(volume.FreeBytes() / (capacity / 100)); 54 off_t capacity = volume->Capacity(); 55 int32 percent = static_cast<int32>(volume->FreeBytes() / (capacity / 100)); 69 56 70 // warn below 20 MB of free space (if this is less than 10% of free space) 71 if (volume.FreeBytes() < 20 * 1024 * 1024 && percent < 10) 72 return -2 - percent; 73 74 return percent; 75 } 76 } 77 return -1; 57 // warn below 20 MB of free space (if this is less than 10% of free space) 58 if (volume->FreeBytes() < 20 * 1024 * 1024 && percent < 10) 59 return -2 - percent; 60 return percent; 78 61 } 79 62 80 63 … … 98 81 { 99 82 CreateWidgets(view); 100 83 101 if (model->IsVolume() && TrackerSettings().ShowVolumeSpaceBar()) { 84 if (model->IsVolume()) { 85 fs_info info; 102 86 dev_t device = model->NodeRef()->device; 103 fPercent = CalcFreeSpace(device); 87 BVolume *volume = new BVolume(device); 88 if (volume->InitCheck() == B_OK 89 && fs_stat_dev(device, &info) == B_OK) { 90 // Philosophy here: 91 // Bars go on all drives with read/write capabilities 92 // Exceptions: Not on CDDA, but on NTFS/Ext2 93 // Also note that some volumes may return 0 when 94 // BVolume::Capacity() is called (believe-me... That *DOES* 95 // happen) so we also check for that. 96 off_t capacity = volume->Capacity(); 97 if (((!volume->IsReadOnly() && strcmp(info.fsh_name,"cdda")) 98 || !strcmp(info.fsh_name,"ntfs") 99 || !strcmp(info.fsh_name,"ext2")) 100 && capacity > 0) { 101 // The volume is ok and we want space bars on it 102 gPeriodicUpdatePoses.AddPose(this, view, 103 _PeriodicUpdateCallback, volume); 104 if (TrackerSettings().ShowVolumeSpaceBar()) 105 fPercent = CalcFreeSpace(volume); 106 } else 107 delete volume; 108 } else 109 delete volume; 104 110 } 105 111 106 112 if ((fClipboardMode = FSClipboardFindNodeMode(model,true)) != 0 … … 112 118 113 119 BPose::~BPose() 114 120 { 121 if (fModel->IsVolume()) { 122 // we might be registered for periodic updates 123 BVolume *volume = NULL; 124 if (gPeriodicUpdatePoses.RemovePose(this, (void **)&volume)) 125 delete volume; 126 } 127 115 128 delete fModel; 116 129 } 117 130 … … 285 298 286 299 287 300 bool 288 BPose:: UpdateVolumeSpaceBar(bool enabled)301 BPose::_PeriodicUpdateCallback(BPose *pose, void *cookie) 289 302 { 303 return pose->UpdateVolumeSpaceBar((BVolume *)cookie); 304 } 305 306 307 bool 308 BPose::UpdateVolumeSpaceBar(BVolume *volume) 309 { 310 bool enabled = TrackerSettings().ShowVolumeSpaceBar(); 290 311 if (!enabled) { 291 312 if (fPercent == -1) 292 313 return false; … … 295 316 return true; 296 317 } 297 318 298 dev_t device = TargetModel()->NodeRef()->device; 299 int32 percent = CalcFreeSpace(device); 300 319 int32 percent = CalcFreeSpace(volume); 301 320 if (fPercent != percent) { 302 321 if (percent > 100) 303 322 fPercent = 100; -
src/kits/tracker/Utilities.h
46 46 #include <MenuItem.h> 47 47 #include <MessageFilter.h> 48 48 #include <Mime.h> 49 #include <ObjectList.h> 49 50 #include <Point.h> 50 51 #include <Path.h> 51 52 #include <String.h> … … 62 63 namespace BPrivate { 63 64 64 65 class Benaphore; 66 class BPose; 67 class BPoseView; 65 68 66 69 // global variables 67 70 extern const rgb_color kBlack; … … 83 86 84 87 // misc typedefs, constants and structs 85 88 89 // Periodically updated poses (ones with a volume space bar) register 90 // themselfs in this global list. This way they can be iterated over instead 91 // of sending around update messages. 92 93 class PeriodicUpdatePoses { 94 public: 95 PeriodicUpdatePoses(); 96 ~PeriodicUpdatePoses(); 97 98 typedef bool (*PeriodicUpdateCallback)(BPose *pose, void *cookie); 99 100 void AddPose(BPose *pose, BPoseView *poseView, 101 PeriodicUpdateCallback callback, void *cookie); 102 bool RemovePose(BPose *pose, void **cookie); 103 104 void DoPeriodicUpdate(bool forceRedraw); 105 106 private: 107 struct periodic_pose { 108 BPose *pose; 109 BPoseView *pose_view; 110 PeriodicUpdateCallback callback; 111 void *cookie; 112 }; 113 114 Benaphore *fLock; 115 BObjectList<periodic_pose> fPoseList; 116 }; 117 118 extern PeriodicUpdatePoses gPeriodicUpdatePoses; 119 120 86 121 // PoseInfo is the structure that gets saved as attributes for every node on 87 122 // disk, defining the node's position and visibility 88 123 class PoseInfo { -
src/kits/tracker/PoseView.h
159 159 void SetAutoScroll(bool); 160 160 void SetPoseEditing(bool); 161 161 162 void UpdateVolumeIcon(dev_t device, bool forceUpdate = false); 163 void UpdateVolumeIcons(); 162 void UpdateIcon(BPose *pose); 164 163 165 164 // file change notification handler 166 165 virtual bool FSNotification(const BMessage *); -
src/kits/tracker/Utilities.cpp
35 35 #include "Attributes.h" 36 36 #include "MimeTypes.h" 37 37 #include "Model.h" 38 #include "PoseView.h" 38 39 #include "Utilities.h" 39 40 #include "ContainerWindow.h" 40 41 … … 158 159 textView->DisallowChar(B_PAGE_DOWN); 159 160 textView->DisallowChar(B_FUNCTION_KEY); 160 161 } 161 162 163 164 PeriodicUpdatePoses::PeriodicUpdatePoses() 165 : fPoseList(20, true) 166 { 167 fLock = new Benaphore("PeriodicUpdatePoses"); 168 } 169 170 171 PeriodicUpdatePoses::~PeriodicUpdatePoses() 172 { 173 fLock->Lock(); 174 fPoseList.MakeEmpty(); 175 delete fLock; 176 } 177 178 179 void 180 PeriodicUpdatePoses::AddPose(BPose *pose, BPoseView *poseView, 181 PeriodicUpdateCallback callback, void *cookie) 182 { 183 periodic_pose *periodic = new periodic_pose; 184 periodic->pose = pose; 185 periodic->pose_view = poseView; 186 periodic->callback = callback; 187 periodic->cookie = cookie; 188 fPoseList.AddItem(periodic); 189 } 190 191 192 bool 193 PeriodicUpdatePoses::RemovePose(BPose *pose, void **cookie) 194 { 195 int32 count = fPoseList.CountItems(); 196 for (int32 index = 0; index < count; index++) { 197 if (fPoseList.ItemAt(index)->pose == pose) { 198 if (!fLock->Lock()) 199 return false; 200 201 periodic_pose *periodic = fPoseList.RemoveItemAt(index); 202 if (cookie) 203 *cookie = periodic->cookie; 204 delete periodic; 205 fLock->Unlock(); 206 return true; 207 } 208 } 209 210 return false; 211 } 212 213 214 void 215 PeriodicUpdatePoses::DoPeriodicUpdate(bool forceRedraw) 216 { 217 if (!fLock->Lock()) 218 return; 219 220 int32 count = fPoseList.CountItems(); 221 for (int32 index = 0; index < count; index++) { 222 periodic_pose *periodic = fPoseList.ItemAt(index); 223 if (periodic->callback(periodic->pose, periodic->cookie) 224 || forceRedraw) { 225 periodic->pose_view->LockLooper(); 226 periodic->pose_view->UpdateIcon(periodic->pose); 227 periodic->pose_view->UnlockLooper(); 228 } 229 } 230 231 fLock->Unlock(); 232 } 233 234 235 static PeriodicUpdatePoses gPeriodicUpdatePoses; 236 162 237 } // namespace BPrivate 163 238 164 239 -
src/kits/tracker/Pose.h
96 96 void UpdateAllWidgets(int32 poseIndex, BPoint poseLoc, BPoseView *); 97 97 void UpdateWidgetAndModel(Model *resolvedModel, const char *attrName, 98 98 uint32 attrType, int32 poseIndex, BPoint poseLoc, BPoseView *view); 99 bool UpdateVolumeSpaceBar( bool enabled);99 bool UpdateVolumeSpaceBar(BVolume *volume); 100 100 void UpdateIcon(BPoint poseLoc, BPoseView *); 101 101 102 102 //void UpdateFixedSymlink(BPoint poseLoc, BPoseView *); … … 126 126 #endif 127 127 128 128 private: 129 static bool _PeriodicUpdateCallback(BPose *pose, void *cookie); 129 130 void EditPreviousNextWidgetCommon(BPoseView *poseView, bool next); 130 131 void CreateWidgets(BPoseView *); 131 132 bool TestLargeIconPixel(BPoint) const; -
src/kits/tracker/PoseList.cpp
105 105 106 106 return NULL; 107 107 } 108 109 BPose *110 PoseList::FindVolumePose(const dev_t device, int32 *resultingIndex) const111 {112 int32 count = CountItems();113 for (int32 index = 0; index < count; index++) {114 BPose *pose = ItemAt(index);115 Model *model = pose->TargetModel();116 ASSERT(model);117 if (model->IsVolume() && model->NodeRef()->device == device) {118 if (resultingIndex)119 *resultingIndex = index;120 return pose;121 }122 }123 return NULL;124 }