Ticket #1247: periodic_update_poses.diff

File periodic_update_poses.diff, 14.0 KB (added by mmlr, 17 years ago)
  • src/kits/tracker/PoseList.h

     
    6464    BPose *DeepFindPose(const node_ref *node, int32 *index = NULL) const;
    6565        // same as FindPose, node can be a target of the actual
    6666        // pose if the pose is a symlink
    67     BPose *FindVolumePose(const dev_t device, int32 *index = NULL) const;
    6867};
    6968
    7069// iteration glue, add permutations as needed
  • src/kits/tracker/SettingsViews.cpp

     
    10721072        {
    10731073            settings.SetShowVolumeSpaceBar(fSpaceBarShowCheckBox->Value() == 1);
    10741074            Window()->PostMessage(kSettingsContentsModified);
    1075             BMessage notificationMessage;
    1076             notificationMessage.AddBool("ShowVolumeSpaceBar", settings.ShowVolumeSpaceBar());
    1077             tracker->SendNotices(kShowVolumeSpaceBar, &notificationMessage);
     1075            tracker->PostMessage(kShowVolumeSpaceBar);
    10781076            break;
    10791077        }
    10801078
     
    10941092            }
    10951093            break;
    10961094        }
     1095
    10971096        case kSpaceBarColorChanged:
    10981097        {
    10991098            switch (fCurrentColor) {
     
    11091108            }
    11101109
    11111110            Window()->PostMessage(kSettingsContentsModified);
    1112             BMessage notificationMessage;
    1113             tracker->SendNotices(kSpaceBarColorChanged, &notificationMessage);
     1111            tracker->PostMessage(kSpaceBarColorChanged);
    11141112            break;
    11151113        }
    11161114
  • src/kits/tracker/PoseView.cpp

     
    803803        app->StopWatching(this, kShowSelectionWhenInactiveChanged);
    804804        app->StopWatching(this, kTransparentSelectionChanged);
    805805        app->StopWatching(this, kSortFolderNamesFirstChanged);
    806         app->StopWatching(this, kShowVolumeSpaceBar);
    807         app->StopWatching(this, kSpaceBarColorChanged);
    808         app->StopWatching(this, kUpdateVolumeSpaceBar);
    809806        app->Unlock();
    810807    }
    811808
     
    890887        app->StartWatching(this, kShowSelectionWhenInactiveChanged);
    891888        app->StartWatching(this, kTransparentSelectionChanged);
    892889        app->StartWatching(this, kSortFolderNamesFirstChanged);
    893         app->StartWatching(this, kShowVolumeSpaceBar);
    894         app->StartWatching(this, kSpaceBarColorChanged);
    895         app->StartWatching(this, kUpdateVolumeSpaceBar);
    896890        app->Unlock();
    897891    }
    898892
     
    23312325                            Invalidate();
    23322326                        }
    23332327                        break;
    2334 
    2335                     case kShowVolumeSpaceBar:
    2336                         bool enabled;
    2337                         if (message->FindBool("ShowVolumeSpaceBar", &enabled) == B_OK)
    2338                             TrackerSettings().SetShowVolumeSpaceBar(enabled);
    2339                         // supposed to fall through
    2340                     case kSpaceBarColorChanged:
    2341                         UpdateVolumeIcons();
    2342                         break;
    2343                     case kUpdateVolumeSpaceBar:
    2344                         dev_t device;
    2345                         message->FindInt32("device", (int32 *)&device);
    2346                         UpdateVolumeIcon(device);   
    2347                         break;
    23482328                }
    23492329            }
    23502330            break;
     
    52145194
    52155195
    52165196void
    5217 BPoseView::UpdateVolumeIcon(dev_t device, bool forceUpdate)
     5197BPoseView::UpdateIcon(BPose *pose)
    52185198{
    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        }
    52275209    }
    5228 }
    52295210
    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);
    52455212}
    52465213
    52475214
  • src/kits/tracker/Tracker.cpp

     
    483483            break;
    484484        }
    485485
     486        case kShowVolumeSpaceBar:
     487        case kSpaceBarColorChanged: {
     488            gPeriodicUpdatePoses.DoPeriodicUpdate(true);
     489            break;
     490        }
     491
    486492        default:
    487493            _inherited::MessageReceived(message);
    488494            break;
     
    497503        return;
    498504
    499505    // 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, &notificationMessage);
    513     }
     506    gPeriodicUpdatePoses.DoPeriodicUpdate(false);
    514507}
    515508
    516509
  • src/kits/tracker/Pose.cpp

     
    4949
    5050
    5151int32
    52 CalcFreeSpace(dev_t device)
     52CalcFreeSpace(BVolume *volume)
    5353{
    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));
    6956
    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;
    7861}
    7962
    8063
     
    9881{
    9982    CreateWidgets(view);
    10083
    101     if (model->IsVolume() && TrackerSettings().ShowVolumeSpaceBar()) {
     84    if (model->IsVolume()) {
     85        fs_info info;
    10286        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;
    104110    }
    105111
    106112    if ((fClipboardMode = FSClipboardFindNodeMode(model,true)) != 0
     
    112118
    113119BPose::~BPose()
    114120{
     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
    115128    delete fModel;
    116129}
    117130
     
    285298
    286299
    287300bool
    288 BPose::UpdateVolumeSpaceBar(bool enabled)
     301BPose::_PeriodicUpdateCallback(BPose *pose, void *cookie)
    289302{
     303    return pose->UpdateVolumeSpaceBar((BVolume *)cookie);
     304}
     305
     306
     307bool
     308BPose::UpdateVolumeSpaceBar(BVolume *volume)
     309{
     310    bool enabled = TrackerSettings().ShowVolumeSpaceBar();
    290311    if (!enabled) {
    291312        if (fPercent == -1)
    292313            return false;
     
    295316        return true;
    296317    }
    297318
    298     dev_t device = TargetModel()->NodeRef()->device;
    299     int32 percent = CalcFreeSpace(device);
    300 
     319    int32 percent = CalcFreeSpace(volume);
    301320    if (fPercent != percent) {
    302321        if (percent > 100)
    303322            fPercent = 100;
  • src/kits/tracker/Utilities.h

     
    4646#include <MenuItem.h>
    4747#include <MessageFilter.h>
    4848#include <Mime.h>
     49#include <ObjectList.h>
    4950#include <Point.h>
    5051#include <Path.h>
    5152#include <String.h>
     
    6263namespace BPrivate {
    6364
    6465class Benaphore;
     66class BPose;
     67class BPoseView;
    6568
    6669// global variables
    6770extern const rgb_color kBlack;
     
    8386
    8487// misc typedefs, constants and structs
    8588
     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
     93class 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
     118extern PeriodicUpdatePoses gPeriodicUpdatePoses;
     119
     120
    86121// PoseInfo is the structure that gets saved as attributes for every node on
    87122// disk, defining the node's position and visibility
    88123class PoseInfo {
  • src/kits/tracker/PoseView.h

     
    159159        void SetAutoScroll(bool);
    160160        void SetPoseEditing(bool);
    161161
    162         void UpdateVolumeIcon(dev_t device, bool forceUpdate = false);
    163         void UpdateVolumeIcons();
     162        void UpdateIcon(BPose *pose);
    164163
    165164        // file change notification handler
    166165        virtual bool FSNotification(const BMessage *);
  • src/kits/tracker/Utilities.cpp

     
    3535#include "Attributes.h"
    3636#include "MimeTypes.h"
    3737#include "Model.h"
     38#include "PoseView.h"
    3839#include "Utilities.h"
    3940#include "ContainerWindow.h"
    4041
     
    158159    textView->DisallowChar(B_PAGE_DOWN);
    159160    textView->DisallowChar(B_FUNCTION_KEY);
    160161}
    161  
     162
     163
     164PeriodicUpdatePoses::PeriodicUpdatePoses()
     165    :   fPoseList(20, true)
     166{
     167    fLock = new Benaphore("PeriodicUpdatePoses");
     168}
     169
     170
     171PeriodicUpdatePoses::~PeriodicUpdatePoses()
     172{
     173    fLock->Lock();
     174    fPoseList.MakeEmpty();
     175    delete fLock;
     176}
     177
     178
     179void
     180PeriodicUpdatePoses::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
     192bool
     193PeriodicUpdatePoses::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
     214void
     215PeriodicUpdatePoses::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
     235static PeriodicUpdatePoses gPeriodicUpdatePoses;
     236
    162237}   // namespace BPrivate
    163238
    164239
  • src/kits/tracker/Pose.h

     
    9696        void UpdateAllWidgets(int32 poseIndex, BPoint poseLoc, BPoseView *);
    9797        void UpdateWidgetAndModel(Model *resolvedModel, const char *attrName,
    9898                uint32 attrType, int32 poseIndex, BPoint poseLoc, BPoseView *view);
    99         bool UpdateVolumeSpaceBar(bool enabled);
     99        bool UpdateVolumeSpaceBar(BVolume *volume);
    100100        void UpdateIcon(BPoint poseLoc, BPoseView *);
    101101
    102102        //void UpdateFixedSymlink(BPoint poseLoc, BPoseView *);
     
    126126#endif
    127127
    128128    private:
     129        static bool _PeriodicUpdateCallback(BPose *pose, void *cookie);
    129130        void EditPreviousNextWidgetCommon(BPoseView *poseView, bool next);
    130131        void CreateWidgets(BPoseView *);
    131132        bool TestLargeIconPixel(BPoint) const;
  • src/kits/tracker/PoseList.cpp

     
    105105
    106106    return NULL;
    107107}
    108 
    109 BPose *
    110 PoseList::FindVolumePose(const dev_t device, int32 *resultingIndex) const
    111 {
    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 }