Ticket #11563: bug#11563-haikudepot-contents-tab-3.patch

File bug#11563-haikudepot-contents-tab-3.patch, 28.9 KB (added by TigerKid001, 4 years ago)

Patch for contents tab using columnlist, but without icons.

  • src/apps/haikudepot/ui/PackageContentsView.cpp

    From fb0f892627e5e3999a81954865c7fba900aa34b8 Mon Sep 17 00:00:00 2001
    From: "Sidhant Sharma [:TigerKid001]" <tigerkid001@gmail.com>
    Date: Sat, 7 Feb 2015 20:42:26 +0530
    Subject: [PATCH] HaikuDepot-contents tab v2.1
    
    ---
     src/apps/haikudepot/ui/PackageContentsView.cpp | 761 ++++++++++++++++++++-----
     src/apps/haikudepot/ui/PackageContentsView.h   |  38 +-
     src/apps/haikudepot/ui/PackageInfoView.cpp     |   2 +-
     3 files changed, 634 insertions(+), 167 deletions(-)
    
    diff --git a/src/apps/haikudepot/ui/PackageContentsView.cpp b/src/apps/haikudepot/ui/PackageContentsView.cpp
    index 4e900ab..ea897e0 100644
    a b  
    11/*
    2  * Copyright 2015, TigerKid001.
     2 * Copyright 2015, Stephan Aßmus <superstippi@gmx.de>.
     3 * Copyright 2015, Sidhant Sharma <tigerkid001@gmail.com>.
    34 * All rights reserved. Distributed under the terms of the MIT License.
    45 */
    56
    67#include "PackageContentsView.h"
     8#include "MainWindow.h"
    79
    810#include <algorithm>
    911#include <stdio.h>
     
    1113#include <Autolock.h>
    1214#include <Catalog.h>
    1315#include <FindDirectory.h>
    14 #include <MessageFormat.h>
    1516#include <LayoutBuilder.h>
    1617#include <LayoutUtils.h>
    17 #include <OutlineListView.h>
     18#include <MessageFormat.h>
     19#include <Mime.h>
     20#include <NodeInfo.h>
    1821#include <Path.h>
    1922#include <ScrollBar.h>
    2023#include <ScrollView.h>
    2124#include <StringItem.h>
     25#include <StringForSize.h>
    2226
    2327#include <package/PackageDefs.h>
    2428#include <package/hpkg/NoErrorOutput.h>
    using BPackageKit::BHPKG::BPackageReader; 
    3943#define B_TRANSLATION_CONTEXT "PackageContentsView"
    4044
    4145
    42 //! Layouts the scrollbar so it looks nice with no border and the document
    43 // window look.
    44 class CustomScrollView : public BScrollView {
     46class PackageEntry : public BPackageEntry {
    4547public:
    46     CustomScrollView(const char* name, BView* target)
    47         :
    48         BScrollView(name, target, 0, false, true, B_NO_BORDER)
    49     {
    50     }
     48                                PackageEntry(const BPackageEntry* entry, const BString path);
     49        virtual             ~PackageEntry();
     50        BString             Path() const
     51                                    {return fPath;}
     52private:
     53        BString fPath;
     54};
    5155
    52     virtual void DoLayout()
    53     {
    54         BRect innerFrame = Bounds();
    55         innerFrame.right -= B_V_SCROLL_BAR_WIDTH + 1;
     56// A field type displaying both a bitmap and a string so that the
     57// tree display looks nicer (both text and bitmap are indented)
     58class BitmapStringField : public BStringField {
     59    typedef BStringField Inherited;
     60public:
     61                                        BitmapStringField(  const PackageEntry* entry);
     62    virtual                         ~BitmapStringField();
    5663
    57         BView* target = Target();
    58         if (target != NULL) {
    59             Target()->MoveTo(innerFrame.left, innerFrame.top);
    60             Target()->ResizeTo(innerFrame.Width(), innerFrame.Height());
    61         }
     64            void                        SetBitmap(const PackageEntry* entry);
     65            const BBitmap*  Bitmap() const
     66                                        {return NULL/*fIcon*/;}
     67private:
     68        const BBitmap* fIcon;
     69};
    6270
    63         BScrollBar* scrollBar = ScrollBar(B_VERTICAL);
    64         if (scrollBar != NULL) {
    65             BRect rect = innerFrame;
    66             rect.left = rect.right + 1;
    67             rect.right = rect.left + B_V_SCROLL_BAR_WIDTH;
    68             rect.bottom -= B_H_SCROLL_BAR_HEIGHT;
    6971
    70             scrollBar->MoveTo(rect.left, rect.top);
    71             scrollBar->ResizeTo(rect.Width(), rect.Height());
    72         }
    73     }
    74 };
     72// BColumn for PackageContentsView which knows how to render
     73// a BitmapStringField
     74class PackageEntryColumn : public BTitledColumn {
     75    typedef BTitledColumn Inherited;
     76public:
     77                                PackageEntryColumn(const char* title,
     78                                    float width, float minWidth,
     79                                    float maxWidth, uint32 truncateMode,
     80                                    alignment align = B_ALIGN_LEFT);
    7581
    76 // #pragma mark - PackageEntryItem
     82    virtual void                DrawField(BField* field, BRect rect,
     83                                    BView* parent);
     84    virtual int                 CompareFields(BField* field1, BField* field2);
     85    virtual float               GetPreferredWidth(BField* field,
     86                                    BView* parent) const;
    7787
     88    virtual bool                AcceptsField(const BField* field) const;
    7889
    79 class PackageEntryItem : public BStringItem {
     90    static  void                InitTextMargin(BView* parent);
     91
     92private:
     93            uint32              fTruncateMode;
     94    static  float               sTextMargin;
     95};
     96
     97
     98// BRow for the PartitionListView
     99class PackageEntryRow : public BRow {
     100    typedef BRow Inherited;
    80101public:
    81     PackageEntryItem(const BPackageEntry* entry, const BString& path)
    82         :
    83         BStringItem(entry->Name()),
    84         fPath(path)
    85     {
    86         if (fPath.Length() > 0)
    87             fPath.Append("/");
    88         fPath.Append(entry->Name());
    89     }
    90    
    91     inline const BString& EntryPath() const
    92     {
    93         return fPath;
    94     }
     102                                PackageEntryRow(const PackageEntry* entry);
     103                                PackageEntryRow(BString msg);
     104    virtual                     ~PackageEntryRow();
     105
     106            const PackageEntry* Entry()
     107                                    { return fPackageEntry; }
     108
     109            void                UpdateTitle();
     110            void                UpdateSize();
     111            void                UpdatePermissions();
     112            void                UpdateLinkTargets();
    95113
    96114private:
    97     BString fPath;
     115            const PackageEntry*     fPackageEntry;
    98116};
    99117
    100118
    101 // #pragma mark - PackageContentOutliner
     119// #pragma mark - PackageEntry
     120
     121PackageEntry::PackageEntry(const BPackageEntry* entry, const BString path)
     122    :
     123    BPackageEntry(*entry),
     124    fPath(path)
     125{
     126        //TODO: Something!
     127}
     128
     129
     130PackageEntry::~PackageEntry()
     131{
     132}
     133
     134
     135// #pragma mark - BitmapStringField
     136
     137BitmapStringField::BitmapStringField(   const PackageEntry* entry)
     138    :
     139    Inherited(entry->Name())
     140{
     141    //SetBitmap(entry);
     142}
     143
     144
     145BitmapStringField::~BitmapStringField()
     146{
     147}
    102148
    103149
    104 class PackageContentOutliner : public BPackageContentHandler {
     150void
     151BitmapStringField::SetBitmap(const PackageEntry* entry)
     152{
     153    //Get mimetype of package entry and set icon
     154    BMimeType mimeType;
     155    BNode node(entry->Path().String());
     156    BNodeInfo nodeInfo(&node);
     157    BBitmap* icon = new BBitmap(BRect(0,0,15,15), B_RGBA32);
     158//  char mimeTypeString[B_MIME_TYPE_LENGTH];
     159    if (nodeInfo.GetIcon(icon, B_MINI_ICON) != B_OK) {
     160            if(mimeType.GetIcon(icon, B_MINI_ICON) != B_OK) {
     161                printf("Failed to get icon for %s,%s!", entry->Name(),
     162                                                entry->Path().String());
     163                return;
     164        }
     165        nodeInfo.SetIcon(icon, B_MINI_ICON);   
     166    } else
     167        mimeType.SetIcon(icon, B_MINI_ICON);
     168   
     169    fIcon = icon;
     170    // TODO: cause a redraw?
     171}
     172
     173
     174// #pragma mark - PackageContentOutliner
     175
     176class PackageContentOutliner
     177            : public BPackageContentHandler {
    105178public:
    106     PackageContentOutliner(BOutlineListView* listView,
    107             const PackageInfo* packageInfo,
    108             BLocker& packageLock, PackageInfoRef& packageInfoRef)
     179    PackageContentOutliner(const PackageInfo* packageInfo,
     180            BLocker& packageLock, PackageInfoRef& packageInfoRef ,
     181            BPath packagePath, PackageContentsView* view)
    109182        :
    110         fListView(listView),
     183        fView(view),
    111184        fLastParentEntry(NULL),
    112         fLastParentItem(NULL),
     185        fLastParentRow(NULL),
    113186        fLastEntry(NULL),
    114         fLastItem(NULL),
    115 
     187        fLastRow(NULL),
    116188        fPackageInfoToPopulate(packageInfo),
    117189        fPackageLock(packageLock),
    118         fPackageInfoRef(packageInfoRef)
     190        fPackageInfoRef(packageInfoRef),
     191        fPackagePath(packagePath)
    119192    {
    120193    }
    121194
    122195    virtual status_t HandleEntry(BPackageEntry* entry)
    123196    {
    124 //      printf("HandleEntry(%s/%s)\n",
    125 //          entry->Parent() != NULL ? entry->Parent()->Name() : "NULL",
    126 //          entry->Name());
     197        printf("\n**HandleEntry(%s/%s)\n",
     198            entry->Parent() != NULL ? entry->Parent()->Name() : "NULL",
     199            entry->Name());
    127200
    128         if (!fListView->LockLooper())
     201    if (!fView->LockLooper())
    129202            return B_ERROR;
    130203
    131204        // Check if we are still supposed to popuplate the list
    132205        if (fPackageInfoRef.Get() != fPackageInfoToPopulate) {
    133 //          printf("stopping package content population\n");
    134             fListView->UnlockLooper();
     206            printf("stopping package content population\n");
     207            fView->UnlockLooper();
    135208            return B_ERROR;
    136209        }
    137210
    138211        BString path;
    139212        const BPackageEntry* parent = entry->Parent();
     213       
    140214        while (parent != NULL) {
    141215            if (path.Length() > 0)
    142216                path.Prepend("/");
    143217            path.Prepend(parent->Name());
    144218            parent = parent->Parent();
    145219        }
    146 
    147         PackageEntryItem* item = new PackageEntryItem(entry, path);
     220        path.Prepend("/");
     221        path.Prepend(fPackagePath.Path());
     222        BPath entryPath(path.String());
     223        printf("\npath: %s\n",path.String());
     224        printf("\\m/%s,\\m/%s\n", fPackagePath.Path(), entryPath.Path());
     225        // create the row for this package
     226        PackageEntryRow* packageRow = new PackageEntryRow(
     227                                        new PackageEntry(entry, path));
     228//      BitmapStringField* item = new BitmapStringField(entry/*, path*/);
    148229
    149230        if (entry->Parent() == NULL) {
    150 //          printf("  adding root entry\n");
    151             fListView->AddItem(item);
     231            // add the row, parent may be NULL (add at top level)
     232            fView->AddRow(packageRow);
    152233            fLastParentEntry = NULL;
    153             fLastParentItem = NULL;
     234            fLastParentRow = NULL;
    154235        } else if (entry->Parent() == fLastEntry) {
    155 //          printf("  adding to last entry %s\n", fLastEntry->Name());
    156             fListView->AddUnder(item, fLastItem);
     236            fView->AddRow(packageRow, fLastRow);
    157237            fLastParentEntry = fLastEntry;
    158             fLastParentItem = fLastItem;
     238            fLastParentRow = fLastRow;
    159239        } else if (entry->Parent() == fLastParentEntry) {
    160 //          printf("  adding to last parent %s\n", fLastParentEntry->Name());
    161             fListView->AddUnder(item, fLastParentItem);
     240            fView->AddRow(packageRow, fLastParentRow);
    162241        } else {
    163242            // Not the last parent entry, need to search for the parent
    164243            // among the already added list items.
    165244            bool foundParent = false;
    166             for (int32 i = 0; i < fListView->FullListCountItems(); i++) {
    167                 PackageEntryItem* listItem
    168                     = dynamic_cast<PackageEntryItem*>(
    169                         fListView->FullListItemAt(i));
    170                 if (listItem == NULL)
    171                     continue;
    172                 if (listItem->EntryPath() == path) {
    173                     fLastParentEntry = entry->Parent();
    174                     fLastParentItem = listItem;
    175 //                  printf("  found parent %s\n", listItem->Text());
    176                     fListView->AddUnder(item, listItem);
    177                     foundParent = true;
    178                     break;
    179                 }
     245            PackageEntryRow* row = (PackageEntryRow*) fView->_FindRow(
     246                                                entry->Parent()->Name());
     247            if(row == NULL) {
     248                foundParent = false;
     249            } else {
     250                fLastParentEntry = entry->Parent();
     251                fLastParentRow = row;
     252                fView->AddRow(packageRow, row);
     253                foundParent = true;
    180254            }
     255           
    181256            if (!foundParent) {
    182257                // NOTE: Should not happen. Just add this entry at the
    183258                // root level.
    184 //              printf("Did not find parent entry for %s (%s)!\n",
    185 //                  entry->Name(), entry->Parent()->Name());
    186                 fListView->AddItem(item);
     259                printf("Did not find parent entry for %s (%s)!\n",
     260                entry->Name(), entry->Parent()->Name());
     261                fView->AddRow(packageRow);
    187262                fLastParentEntry = NULL;
    188                 fLastParentItem = NULL;
     263                fLastParentRow = NULL;
    189264            }
    190265        }
    191 
     266        // make sure the row is initially expanded
     267        fView->ExpandOrCollapse(packageRow, true);
    192268        fLastEntry = entry;
    193         fLastItem = item;
     269        fLastRow = packageRow;
    194270
    195         fListView->UnlockLooper();
     271    fView->UnlockLooper();
    196272
    197         return B_OK;
     273    return B_OK;
    198274    }
    199275
    200276    virtual status_t HandleEntryAttribute(BPackageEntry* entry,
    public: 
    219295    }
    220296   
    221297private:
    222     BOutlineListView*       fListView;
    223298
     299    PackageContentsView* fView;
     300   
    224301    const BPackageEntry*    fLastParentEntry;
    225     PackageEntryItem*       fLastParentItem;
     302    PackageEntryRow*        fLastParentRow;
    226303
    227304    const BPackageEntry*    fLastEntry;
    228     PackageEntryItem*       fLastItem;
     305    PackageEntryRow*        fLastRow;
    229306
    230307    const PackageInfo*      fPackageInfoToPopulate;
    231308    BLocker&                fPackageLock;
    232     PackageInfoRef&         fPackageInfoRef;
     309    PackageInfoRef          fPackageInfoRef;
     310    BPath                   fPackagePath;
    233311};
    234312
    235313
    236 // #pragma mark - PackageContentView
     314// #pragma mark - PackageEntryColumn
     315
    237316
     317float PackageEntryColumn::sTextMargin = 0.0;
    238318
    239 PackageContentsView::PackageContentsView(const char* name)
     319PackageEntryColumn::PackageEntryColumn(const char* title, float width, float minWidth,
     320        float maxWidth, uint32 truncateMode, alignment align)
    240321    :
    241     BView("package_contents_view", B_WILL_DRAW),
    242     fPackageLock("package contents populator lock")
     322    Inherited(title, width, minWidth, maxWidth, align),
     323    fTruncateMode(truncateMode)
    243324{
    244     fContentListView = new BOutlineListView("content list view",
    245         B_SINGLE_SELECTION_LIST);
    246    
    247     BScrollView* scrollView = new CustomScrollView("contents scroll view",
    248         fContentListView);
    249                                                            
    250     BLayoutBuilder::Group<>(this)
    251         .Add(scrollView, 1.0f)
    252         .SetInsets(0.0f, -1.0f, -1.0f, -1.0f)
    253     ;
     325    SetWantsEvents(true);
     326}
    254327
    255     _InitContentPopulator();
     328
     329void
     330PackageEntryColumn::DrawField(BField* field, BRect rect, BView* parent)
     331{
     332    BitmapStringField* bitmapField
     333        = dynamic_cast<BitmapStringField*>(field);
     334    BStringField* stringField = dynamic_cast<BStringField*>(field);
     335
     336    if (bitmapField != NULL) {
     337        const BBitmap* bitmap = bitmapField->Bitmap();
     338
     339        // figure out the placement
     340        float x = 0.0;
     341        BRect r = bitmap ? bitmap->Bounds() : BRect(0, 0, 15, 15);
     342        float y = rect.top + ((rect.Height() - r.Height()) / 2);
     343        float width = 0.0;
     344
     345        switch (Alignment()) {
     346            default:
     347            case B_ALIGN_LEFT:
     348            case B_ALIGN_CENTER:
     349                x = rect.left + sTextMargin;
     350                width = rect.right - (x + r.Width()) - (2 * sTextMargin);
     351                r.Set(x + r.Width(), rect.top, rect.right - width, rect.bottom);
     352                break;
     353
     354            case B_ALIGN_RIGHT:
     355                x = rect.right - sTextMargin - r.Width();
     356                width = (x - rect.left - (2 * sTextMargin));
     357                r.Set(rect.left, rect.top, rect.left + width, rect.bottom);
     358                break;
     359        }
     360
     361        if (width != bitmapField->Width()) {
     362            BString truncatedString(bitmapField->String());
     363            parent->TruncateString(&truncatedString, fTruncateMode, width + 2);
     364            bitmapField->SetClippedString(truncatedString.String());
     365            bitmapField->SetWidth(width);
     366        }
     367
     368        // draw the bitmap
     369        if (bitmap != NULL) {
     370            parent->SetDrawingMode(B_OP_ALPHA);
     371            parent->DrawBitmap(bitmap, BPoint(x, y));
     372            parent->SetDrawingMode(B_OP_OVER);
     373        }
     374
     375        // draw the string
     376        DrawString(bitmapField->ClippedString(), parent, r);
     377
     378    } else if (stringField != NULL) {
     379
     380        float width = rect.Width() - (2 * sTextMargin);
     381
     382        if (width != stringField->Width()) {
     383            BString truncatedString(stringField->String());
     384
     385            parent->TruncateString(&truncatedString, fTruncateMode, width + 2);
     386            stringField->SetClippedString(truncatedString.String());
     387            stringField->SetWidth(width);
     388        }
     389
     390        DrawString(stringField->ClippedString(), parent, rect);
     391
     392    }
    256393}
    257394
    258395
    259 PackageContentsView::~PackageContentsView()
     396int
     397PackageEntryColumn::CompareFields(BField* field1, BField* field2)
    260398{
    261     Clear();
     399    BStringField* stringField1 = dynamic_cast<BStringField*>(field1);
     400    BStringField* stringField2 = dynamic_cast<BStringField*>(field2);
     401    if (stringField1 != NULL && stringField2 != NULL) {
     402        // TODO: Locale aware string compare... not too important if
     403        // package names are not translated.
     404        return strcmp(stringField1->String(), stringField2->String());
     405    }
     406    return Inherited::CompareFields(field1, field2);
     407}
    262408
    263     delete_sem(fContentPopulatorSem);
    264     if (fContentPopulator >= 0)
    265         wait_for_thread(fContentPopulator, NULL);
     409
     410float
     411PackageEntryColumn::GetPreferredWidth(BField *_field, BView* parent) const
     412{
     413    BitmapStringField* bitmapField
     414        = dynamic_cast<BitmapStringField*>(_field);
     415    BStringField* stringField = dynamic_cast<BStringField*>(_field);
     416
     417    float parentWidth = Inherited::GetPreferredWidth(_field, parent);
     418    float width = 0.0;
     419
     420    if (bitmapField) {
     421        const BBitmap* bitmap = bitmapField->Bitmap();
     422        BFont font;
     423        parent->GetFont(&font);
     424        width = font.StringWidth(bitmapField->String()) + 3 * sTextMargin;
     425        if (bitmap)
     426            width += bitmap->Bounds().Width();
     427        else
     428            width += 16;
     429    } else if (stringField) {
     430        BFont font;
     431        parent->GetFont(&font);
     432        width = font.StringWidth(stringField->String()) + 2 * sTextMargin;
     433    }
     434    return max_c(width, parentWidth);
     435}
     436
     437
     438bool
     439PackageEntryColumn::AcceptsField(const BField* field) const
     440{
     441    return dynamic_cast<const BStringField*>(field) != NULL;
    266442}
    267443
    268444
    269445void
    270 PackageContentsView::AttachedToWindow()
     446PackageEntryColumn::InitTextMargin(BView* parent)
     447{
     448    BFont font;
     449    parent->GetFont(&font);
     450    sTextMargin = ceilf(font.Size() * 0.8);
     451}
     452
     453
     454// #pragma mark - PackageEntryRow
     455
     456
     457enum {
     458    kTitleColumn,
     459    kSizeColumn,
     460    kPermissionsColumn,
     461    kLinkTargetsColumn,
     462};
     463
     464PackageEntryRow::PackageEntryRow(const PackageEntry* entry)
     465    :
     466    Inherited(ceilf(be_plain_font->Size() * 1.8f)),
     467    fPackageEntry(entry)
     468{
     469    // Package icon and title
     470    UpdateTitle();
     471
     472    // Size
     473    UpdateSize();
     474
     475    // Summary
     476    UpdatePermissions();
     477
     478    // Target Links
     479    UpdateLinkTargets();
     480}
     481
     482PackageEntryRow::PackageEntryRow(BString msg)
     483{
     484    SetField(new BStringField(msg), kTitleColumn);
     485}
     486
     487PackageEntryRow::~PackageEntryRow()
    271488{
    272     BView::AttachedToWindow();
    273489}
    274490
    275491
    276492void
    277 PackageContentsView::AllAttached()
     493PackageEntryRow::UpdateTitle()
    278494{
    279     BView::AllAttached();
     495        SetField(new BitmapStringField(Entry()), kTitleColumn);
    280496}
    281497
    282498
    283499void
    284 PackageContentsView::SetPackage(const PackageInfoRef& package)
     500PackageEntryRow::UpdateSize()
    285501{
    286     if (fPackage == package)
    287         return;
     502    PackageEntry* entry = (PackageEntry*) Entry();
     503    if(S_ISDIR(entry->Mode())) {
     504        SetField(new BStringField("-"), kSizeColumn);
     505    } else {
     506    char sizeBuffer[128];
     507    SetField(new BStringField(string_for_size(
     508                    (double) (entry->Data().Size()), sizeBuffer,
     509                                        sizeof(sizeBuffer))), kSizeColumn);
     510    }
     511}
    288512
    289 //  printf("PackageContentsView::SetPackage(%s)\n",
    290 //      package.Get() != NULL ? package->Title().String() : "NULL");
    291513
    292     Clear();
     514void
     515PackageEntryRow::UpdatePermissions()
     516{
     517    PackageEntry* entry = (PackageEntry*) Entry();
     518    if (entry == NULL)
     519        return;
     520    mode_t mode = entry->Mode();
     521    BString perms;
     522   
     523    perms += (S_ISDIR(mode) ? "d" : "-");
     524    perms += ((mode & S_IRUSR) ? "r" : "-");
     525    perms += ((mode & S_IWUSR) ? "w" : "-");
     526    perms += ((mode & S_IXUSR) ? "x" : "-");
     527    perms += ((mode & S_IRGRP) ? "r" : "-");
     528    perms += ((mode & S_IWGRP) ? "w" : "-");
     529    perms += ((mode & S_IXGRP) ? "x" : "-");
     530    perms += ((mode & S_IROTH) ? "r" : "-");
     531    perms += ((mode & S_IWOTH) ? "w" : "-");
     532    perms += ((mode & S_IXOTH) ? "x" : "-");
     533   
     534    SetField(new BStringField(perms.String()), kPermissionsColumn);
     535}
    293536
    294     {
    295         BAutolock lock(&fPackageLock);
    296         fPackage = package;
    297     }
    298     release_sem_etc(fContentPopulatorSem, 1, 0);
     537
     538void
     539PackageEntryRow::UpdateLinkTargets()
     540{
     541    //TODO: Get link targets
     542    BString targets(Entry()->SymlinkPath());
     543    SetField(new BStringField(targets), kLinkTargetsColumn);
    299544}
    300545
    301546
    302 void
    303 PackageContentsView::Clear()
     547// #pragma mark - private
     548
     549PackageEntryRow*
     550PackageContentsView::_FindRow(const PackageEntry* entry, PackageEntryRow* parent)
    304551{
    305     {
    306         BAutolock lock(&fPackageLock);
    307         fPackage.Unset();
     552    for (int32 i = CountRows(parent) - 1; i >= 0; i--) {
     553        PackageEntryRow* row = dynamic_cast<PackageEntryRow*>(RowAt(i, parent));
     554        if (row != NULL && row->Entry() == entry)
     555            return row;
     556        if (CountRows(row) > 0) {
     557            // recurse into child rows
     558            row = _FindRow(entry, row);
     559            if (row != NULL)
     560                return row;
     561        }
    308562    }
    309563
    310     fContentListView->MakeEmpty();
     564    return NULL;
    311565}
    312566
    313567
    314 // #pragma mark - private
     568PackageEntryRow*
     569PackageContentsView::_FindRow(const BString& packageTitle, PackageEntryRow* parent)
     570{
     571    for (int32 i = CountRows(parent) - 1; i >= 0; i--) {
     572        PackageEntryRow* row = dynamic_cast<PackageEntryRow*>(RowAt(i, parent));
     573        if (row != NULL && row->Entry() != NULL
     574            && row->Entry()->Name() == packageTitle) {
     575            return row;
     576        }
     577        if (CountRows(row) > 0) {
     578            // recurse into child rows
     579            row = _FindRow(packageTitle, row);
     580            if (row != NULL)
     581                return row;
     582        }
     583    }
    315584
     585    return NULL;
     586}
    316587
    317588void
    318589PackageContentsView::_InitContentPopulator()
    319590{
     591    printf("In _InitContentPopulator\n");
    320592    fContentPopulatorSem = create_sem(0, "PopulatePackageContents");
    321593    if (fContentPopulatorSem >= 0) {
    322594        fContentPopulator = spawn_thread(&_ContentPopulatorThread,
    323595            "Package Contents Populator", B_NORMAL_PRIORITY, this);
    324         if (fContentPopulator >= 0)
     596        if (fContentPopulator >= 0) {
    325597            resume_thread(fContentPopulator);
     598            printf("fContentPopulator resumed!");
     599        }
    326600    } else
    327601        fContentPopulator = -1;
    328602}
    PackageContentsView::_InitContentPopulator() 
    332606PackageContentsView::_ContentPopulatorThread(void* arg)
    333607{
    334608    PackageContentsView* view = reinterpret_cast<PackageContentsView*>(arg);
    335 
     609    printf("In _ContentPopulatorThread\n");
     610    if(view == NULL) {
     611        printf("_ContentPopulatorThread:: View null!\n");
     612        return 1;
     613    } else  printf("_ContentPopulatorThread:: View not null\n");
    336614    while (acquire_sem(view->fContentPopulatorSem) == B_OK) {
     615        printf("_ContentPopulatorThread: Acquiring sem");
    337616        PackageInfoRef package;
    338617        {
    339618            BAutolock lock(&view->fPackageLock);
    340619            package = view->fPackage;
    341620        }
    342 
    343621        if (package.Get() != NULL) {
    344             if (!view->_PopuplatePackageContens(*package.Get())) {
     622                printf("In _ContentPopulatorThread: Package not null\n");
     623            if (!view->_PopulatePackageContents(view, *package.Get())) {
    345624                if (view->LockLooper()) {
    346                     view->fContentListView->AddItem(
    347                         new BStringItem(B_TRANSLATE("<Package contents not "
    348                             "available for remote packages>")));
     625                        printf("In _ContentPopulatorThread:Remote package\n");
     626                    PackageEntryRow* notAvailable = new PackageEntryRow(
     627                        "<Package contents not available for remote packages>");
     628                    view->AddRow(notAvailable);
     629                    view->ExpandOrCollapse(notAvailable, true);
    349630                    view->UnlockLooper();
    350631                }
    351632            }
    352         }
     633        }else   printf("In _ContentPopulatorThread: package null\n");
    353634    }
    354 
    355635    return 0;
    356636}
    357637
    358638
    359639bool
    360 PackageContentsView::_PopuplatePackageContens(const PackageInfo& package)
     640PackageContentsView::_PopulatePackageContents(PackageContentsView* view,
     641                                    const PackageInfo& package)
    361642{
    362643    BPath packagePath;
    363 
     644    printf("In _PopulatePackageContents\n");
    364645    // Obtain path to the package file
    365646    if (package.IsLocalFile()) {
    366647        BString pathString = package.LocalFilePath();
    PackageContentsView::_PopuplatePackageContens(const PackageInfo& package) 
    378659                return false;
    379660            }
    380661        } else {
    381             printf("PackageContentsView::_PopuplatePackageContens(): "
     662            printf("PackageContentsView::_PopulatePackageContents(): "
    382663                "unknown install location");
    383664            return false;
    384665        }
    PackageContentsView::_PopuplatePackageContens(const PackageInfo& package) 
    399680    }
    400681
    401682    // Scan package contents and populate list
    402     PackageContentOutliner contentHandler(fContentListView, &package,
    403         fPackageLock, fPackage);
     683    PackageContentOutliner contentHandler( &package,
     684        fPackageLock, fPackage, packagePath, view);
    404685    status = reader.ParseContent(&contentHandler);
    405686    if (status != B_OK) {
    406687        printf("PackageContentsView::SetPackage(): "
    PackageContentsView::_InstallLocation(const PackageInfo& package) const 
    424705
    425706    return B_PACKAGE_INSTALLATION_LOCATION_SYSTEM;
    426707}
     708
     709
     710// #pragma mark - PackageContentsView
     711
     712
     713PackageContentsView::PackageContentsView()
     714    :
     715    BColumnListView("package contents view", 0, B_FANCY_BORDER, true),
     716    fPackageLock("package contents populator lock")
     717{
     718    AddColumn(new PackageEntryColumn(B_TRANSLATE("Name"), 375, 50, 400,
     719        B_TRUNCATE_MIDDLE), kTitleColumn);
     720    AddColumn(new PackageEntryColumn(B_TRANSLATE("Size"), 150, 50, 150,
     721        B_TRUNCATE_MIDDLE), kSizeColumn);
     722    AddColumn(new PackageEntryColumn(B_TRANSLATE("Permissions"), 100, 80, 100,
     723        B_TRUNCATE_MIDDLE), kPermissionsColumn);
     724    AddColumn(new PackageEntryColumn(B_TRANSLATE("Link Targets"), 300, 60, 400,
     725        B_TRUNCATE_END), kLinkTargetsColumn);
     726//  fItemCountView = new ItemCountView();
     727//  AddStatusView(fItemCountView);
     728    printf("Initializing population\n");
     729    _InitContentPopulator();
     730}
     731
     732
     733PackageContentsView::~PackageContentsView()
     734{
     735    Clear();
     736    delete_sem(fContentPopulatorSem);
     737    if (fContentPopulator >= 0)
     738        wait_for_thread(fContentPopulator, NULL);
     739}
     740
     741
     742void
     743PackageContentsView::AttachedToWindow()
     744{
     745    BColumnListView::AttachedToWindow();
     746    PackageEntryColumn::InitTextMargin(ScrollView());
     747}
     748
     749
     750void
     751PackageContentsView::AllAttached()
     752{
     753    BColumnListView::AllAttached();
     754
     755    SetSortingEnabled(true);
     756    SetSortColumn(ColumnAt(0), false, true);
     757}
     758
     759
     760void
     761PackageContentsView::MessageReceived(BMessage* message)
     762{
     763    switch (message->what) {
     764/*      case MSG_UPDATE_PACKAGE:
     765        {
     766            BString title;
     767            uint32 changes;
     768            if (message->FindString("title", &title) != B_OK
     769                || message->FindUInt32("changes", &changes) != B_OK) {
     770                break;
     771            }
     772
     773            PackageEntryRow* row = _FindRow(title);
     774            if (row != NULL) {
     775                if ((changes & PKG_CHANGED_SUMMARY) != 0)
     776                    row->UpdateTitle(row->PackageEntry());
     777                if ((changes & PKG_CHANGED_RATINGS) != 0)
     778                    row->UpdateSize(row->PackageEntry());
     779                if ((changes & PKG_CHANGED_STATE) != 0)
     780                    row->UpdatePermissions(row->PackageEntry());
     781                if ((changes & PKG_CHANGED_ICON) != 0)
     782                    row->UpdateLinkTargets(row->PackageEntry());
     783            }
     784            break;
     785        }
     786*/
     787        default:
     788            BColumnListView::MessageReceived(message);
     789            break;
     790    }
     791}
     792
     793
     794void
     795PackageContentsView::SelectionChanged()
     796{
     797    BColumnListView::SelectionChanged();
     798
     799    BMessage message(MSG_PACKAGE_SELECTED);
     800
     801    PackageEntryRow* selected = dynamic_cast<PackageEntryRow*>(CurrentSelection());
     802    if (selected != NULL)
     803        message.AddString("title", selected->Entry()->Name());
     804
     805    Window()->PostMessage(&message);
     806}
     807
     808
     809void
     810PackageContentsView::Clear()
     811{
     812//  fItemCountView->SetItemCount(0);
     813    BColumnListView::Clear();
     814    BAutolock lock(&fPackageLock);
     815    fPackage.Unset();
     816}
     817
     818
     819void
     820PackageContentsView::AddPackageEntry(const PackageEntry& package)
     821{
     822    PackageEntryRow* packageRow =(PackageEntryRow*) _FindRow(&package);
     823    printf("In AddPackageEntry: %s\n", package.Name());
     824    // forget about it if this package is already in the listview
     825    if (packageRow != NULL)
     826        return;
     827
     828    BAutolock _(fPackageLock);
     829
     830    // create the row for this package
     831    packageRow = new PackageEntryRow(&package);
     832
     833    // add the row, parent may be NULL (add at top level)
     834    AddRow(packageRow);
     835
     836    // make sure the row is initially expanded
     837    ExpandOrCollapse(packageRow, true);
     838
     839//  fItemCountView->SetItemCount(CountRows());
     840}
     841
     842
     843void
     844PackageContentsView::SelectPackageEntry(const PackageEntry* entry)
     845{
     846    PackageEntryRow* row = (PackageEntryRow*) _FindRow(entry);
     847    BRow* selected = CurrentSelection();
     848    if (row != selected)
     849        DeselectAll();
     850    if (row != NULL) {
     851        AddToSelection(row);
     852        SetFocusRow(row, false);
     853        ScrollTo(row);
     854    }
     855}
     856
     857
     858void
     859PackageContentsView::SetPackage(const PackageInfoRef& package)
     860{
     861if (fPackage == package)
     862        return;
     863
     864//  printf("PackageContentsView::SetPackage(%s)\n",
     865//      package.Get() != NULL ? package->Title().String() : "NULL");
     866
     867    Clear();
     868
     869    {
     870        BAutolock lock(&fPackageLock);
     871        fPackage = package;
     872    }
     873    release_sem_etc(fContentPopulatorSem, 1, 0);
     874}
     875
  • src/apps/haikudepot/ui/PackageContentsView.h

    diff --git a/src/apps/haikudepot/ui/PackageContentsView.h b/src/apps/haikudepot/ui/PackageContentsView.h
    index 2cd58a2..a83a26b 100644
    a b  
    11/*
    2  * Copyright 2015, TigerKid001.
     2 * Copyright 2015, Stephan Aßmus <superstippi@gmx.de>.
     3 * Copyright 2015, Sidhant Sharma <tigerkid001@gmail.com>.
    34 * All rights reserved. Distributed under the terms of the MIT License.
    45 */
     6
    57#ifndef PACKAGE_CONTENTS_VIEW_H
    68#define PACKAGE_CONTENTS_VIEW_H
    79
     10#include <ColumnListView.h>
     11#include <ColumnTypes.h>
    812#include <Locker.h>
    9 #include <View.h>
     13#include <package/hpkg/PackageEntry.h>
    1014
    1115#include "PackageInfo.h"
    1216
    13 class BOutlineListView;
     17using BPackageKit::BHPKG::BPackageEntry;
    1418
     19class PackageEntryRow;
     20class PackageEntry;
    1521
    16 class PackageContentsView : public BView {
     22class PackageContentsView : public BColumnListView {
    1723public:
    18                                 PackageContentsView(const char* name);
     24                                PackageContentsView();
    1925    virtual                     ~PackageContentsView();
    2026
    2127    virtual void                AttachedToWindow();
    2228    virtual void                AllAttached();
    2329
     30    void                            MessageReceived(BMessage*);
     31    virtual void                SelectionChanged();
     32
     33    virtual void                Clear();
     34   
     35            void                AddPackageEntry(const PackageEntry& package);
    2436            void                SetPackage(const PackageInfoRef& package);
    25             void                Clear();
     37
     38            void                SelectPackageEntry(const PackageEntry* entry);
    2639
    2740private:
     41            PackageEntryRow*            _FindRow(const PackageEntry* entry,
     42                                    PackageEntryRow* parent = NULL);
     43            PackageEntryRow*            _FindRow(const BString& packageTitle,
     44                                    PackageEntryRow* parent = NULL);
    2845            void                _InitContentPopulator();
    2946    static  int32               _ContentPopulatorThread(void* arg);
    30             bool                _PopuplatePackageContens(
    31                                     const PackageInfo& package);
     47            bool            _PopulatePackageContents(PackageContentsView* view,
     48                                            const PackageInfo& package);
    3249            int32               _InstallLocation(
    3350                                    const PackageInfo& package) const;
    3451
    3552private:
    36             BOutlineListView*   fContentListView;
    37 
     53//          class ItemCountView;
     54            friend class PackageContentOutliner;
    3855            thread_id           fContentPopulator;
    3956            sem_id              fContentPopulatorSem;
    4057            BLocker             fPackageLock;
    4158            PackageInfoRef      fPackage;
     59//          ItemCountView*      fItemCountView;
    4260};
    4361
    4462#endif // PACKAGE_CONTENTS_VIEW_H
  • src/apps/haikudepot/ui/PackageInfoView.cpp

    diff --git a/src/apps/haikudepot/ui/PackageInfoView.cpp b/src/apps/haikudepot/ui/PackageInfoView.cpp
    index 821406a..6b1dd24 100644
    a b public: 
    11781178        SetViewColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR),
    11791179            kContentTint));
    11801180
    1181         fPackageContents = new PackageContentsView("contents_list");
     1181        fPackageContents = new PackageContentsView();
    11821182        AddChild(fPackageContents);
    11831183
    11841184    }