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

File bug#11563-haikudepot-contents-tab-2.patch, 28.4 KB (added by TigerKid001, 5 years ago)
  • src/apps/haikudepot/ui/PackageContentsView.cpp

    From 268eb0c6bd65b6c6102179ee8cd70ef1cb39f071 Mon Sep 17 00:00:00 2001
    From: "Sidhant Sharma [:TigerKid001]" <tigerkid001@gmail.com>
    Date: Tue, 3 Feb 2015 15:09:09 +0530
    Subject: [PATCH] Package Contents Tab v2.0
    
    ---
     src/apps/haikudepot/ui/PackageContentsView.cpp | 744 +++++++++++++++++++------
     src/apps/haikudepot/ui/PackageContentsView.h   |  38 +-
     src/apps/haikudepot/ui/PackageInfoView.cpp     |   2 +-
     3 files changed, 617 insertions(+), 167 deletions(-)
    
    diff --git a/src/apps/haikudepot/ui/PackageContentsView.cpp b/src/apps/haikudepot/ui/PackageContentsView.cpp
    index 4e900ab..0b2c546 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 BPath 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 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);
     81
     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;
     87
     88    virtual bool                AcceptsField(const BField* field) const;
     89
     90    static  void                InitTextMargin(BView* parent);
    7591
    76 // #pragma mark - PackageEntryItem
     92private:
     93            uint32              fTruncateMode;
     94    static  float               sTextMargin;
     95};
    7796
    7897
    79 class PackageEntryItem : public BStringItem {
     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 BPath path)
     122    :
     123    BPackageEntry(*entry),
     124    fPath(path.Path())
     125{
     126        //TODO: Something!
     127}
     128
     129
     130PackageEntry::~PackageEntry()
     131{
     132}
    102133
    103134
    104 class PackageContentOutliner : public BPackageContentHandler {
     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}
     148
     149
     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("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        fPackagePath.Append(path.String());
     222        // create the row for this package
     223        PackageEntryRow* packageRow = new PackageEntryRow(
     224                                        new PackageEntry(entry, fPackagePath));
     225//      BitmapStringField* item = new BitmapStringField(entry/*, path*/);
    148226
    149227        if (entry->Parent() == NULL) {
    150 //          printf("  adding root entry\n");
    151             fListView->AddItem(item);
     228            // add the row, parent may be NULL (add at top level)
     229            fView->AddRow(packageRow);
    152230            fLastParentEntry = NULL;
    153             fLastParentItem = NULL;
     231            fLastParentRow = NULL;
    154232        } else if (entry->Parent() == fLastEntry) {
    155 //          printf("  adding to last entry %s\n", fLastEntry->Name());
    156             fListView->AddUnder(item, fLastItem);
     233            fView->AddRow(packageRow, fLastRow);
    157234            fLastParentEntry = fLastEntry;
    158             fLastParentItem = fLastItem;
     235            fLastParentRow = fLastRow;
    159236        } else if (entry->Parent() == fLastParentEntry) {
    160 //          printf("  adding to last parent %s\n", fLastParentEntry->Name());
    161             fListView->AddUnder(item, fLastParentItem);
     237            fView->AddRow(packageRow, fLastParentRow);
    162238        } else {
    163239            // Not the last parent entry, need to search for the parent
    164240            // among the already added list items.
    165241            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                 }
     242            BPath parentPath;
     243            fPackagePath.GetParent(&parentPath);
     244            PackageEntry parentEntry(entry->Parent(),
     245                                                                parentPath);
     246            PackageEntryRow* row = (PackageEntryRow*) fView->_FindRow(&parentEntry);
     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                fView->AddRow(packageRow);
    187260                fLastParentEntry = NULL;
    188                 fLastParentItem = NULL;
     261                fLastParentRow = NULL;
    189262            }
    190263        }
    191 
     264        // make sure the row is initially expanded
     265        fView->ExpandOrCollapse(packageRow, true);
    192266        fLastEntry = entry;
    193         fLastItem = item;
     267        fLastRow = packageRow;
    194268
    195         fListView->UnlockLooper();
     269    fView->UnlockLooper();
    196270
    197         return B_OK;
     271    return B_OK;
    198272    }
    199273
    200274    virtual status_t HandleEntryAttribute(BPackageEntry* entry,
    public:  
    219293    }
    220294   
    221295private:
    222     BOutlineListView*       fListView;
    223296
     297    PackageContentsView* fView;
     298   
    224299    const BPackageEntry*    fLastParentEntry;
    225     PackageEntryItem*       fLastParentItem;
     300    PackageEntryRow*        fLastParentRow;
    226301
    227302    const BPackageEntry*    fLastEntry;
    228     PackageEntryItem*       fLastItem;
     303    PackageEntryRow*        fLastRow;
    229304
    230305    const PackageInfo*      fPackageInfoToPopulate;
    231306    BLocker&                fPackageLock;
    232     PackageInfoRef&         fPackageInfoRef;
     307    PackageInfoRef          fPackageInfoRef;
     308    BPath                   fPackagePath;
    233309};
    234310
    235311
    236 // #pragma mark - PackageContentView
     312// #pragma mark - PackageEntryColumn
     313
    237314
     315float PackageEntryColumn::sTextMargin = 0.0;
    238316
    239 PackageContentsView::PackageContentsView(const char* name)
     317PackageEntryColumn::PackageEntryColumn(const char* title, float width, float minWidth,
     318        float maxWidth, uint32 truncateMode, alignment align)
    240319    :
    241     BView("package_contents_view", B_WILL_DRAW),
    242     fPackageLock("package contents populator lock")
     320    Inherited(title, width, minWidth, maxWidth, align),
     321    fTruncateMode(truncateMode)
    243322{
    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     ;
     323    SetWantsEvents(true);
     324}
    254325
    255     _InitContentPopulator();
     326
     327void
     328PackageEntryColumn::DrawField(BField* field, BRect rect, BView* parent)
     329{
     330    BitmapStringField* bitmapField
     331        = dynamic_cast<BitmapStringField*>(field);
     332    BStringField* stringField = dynamic_cast<BStringField*>(field);
     333
     334    if (bitmapField != NULL) {
     335        const BBitmap* bitmap = bitmapField->Bitmap();
     336
     337        // figure out the placement
     338        float x = 0.0;
     339        BRect r = bitmap ? bitmap->Bounds() : BRect(0, 0, 15, 15);
     340        float y = rect.top + ((rect.Height() - r.Height()) / 2);
     341        float width = 0.0;
     342
     343        switch (Alignment()) {
     344            default:
     345            case B_ALIGN_LEFT:
     346            case B_ALIGN_CENTER:
     347                x = rect.left + sTextMargin;
     348                width = rect.right - (x + r.Width()) - (2 * sTextMargin);
     349                r.Set(x + r.Width(), rect.top, rect.right - width, rect.bottom);
     350                break;
     351
     352            case B_ALIGN_RIGHT:
     353                x = rect.right - sTextMargin - r.Width();
     354                width = (x - rect.left - (2 * sTextMargin));
     355                r.Set(rect.left, rect.top, rect.left + width, rect.bottom);
     356                break;
     357        }
     358
     359        if (width != bitmapField->Width()) {
     360            BString truncatedString(bitmapField->String());
     361            parent->TruncateString(&truncatedString, fTruncateMode, width + 2);
     362            bitmapField->SetClippedString(truncatedString.String());
     363            bitmapField->SetWidth(width);
     364        }
     365
     366        // draw the bitmap
     367        if (bitmap != NULL) {
     368            parent->SetDrawingMode(B_OP_ALPHA);
     369            parent->DrawBitmap(bitmap, BPoint(x, y));
     370            parent->SetDrawingMode(B_OP_OVER);
     371        }
     372
     373        // draw the string
     374        DrawString(bitmapField->ClippedString(), parent, r);
     375
     376    } else if (stringField != NULL) {
     377
     378        float width = rect.Width() - (2 * sTextMargin);
     379
     380        if (width != stringField->Width()) {
     381            BString truncatedString(stringField->String());
     382
     383            parent->TruncateString(&truncatedString, fTruncateMode, width + 2);
     384            stringField->SetClippedString(truncatedString.String());
     385            stringField->SetWidth(width);
     386        }
     387
     388        DrawString(stringField->ClippedString(), parent, rect);
     389
     390    }
    256391}
    257392
    258393
    259 PackageContentsView::~PackageContentsView()
     394int
     395PackageEntryColumn::CompareFields(BField* field1, BField* field2)
    260396{
    261     Clear();
     397    BStringField* stringField1 = dynamic_cast<BStringField*>(field1);
     398    BStringField* stringField2 = dynamic_cast<BStringField*>(field2);
     399    if (stringField1 != NULL && stringField2 != NULL) {
     400        // TODO: Locale aware string compare... not too important if
     401        // package names are not translated.
     402        return strcmp(stringField1->String(), stringField2->String());
     403    }
     404    return Inherited::CompareFields(field1, field2);
     405}
    262406
    263     delete_sem(fContentPopulatorSem);
    264     if (fContentPopulator >= 0)
    265         wait_for_thread(fContentPopulator, NULL);
     407
     408float
     409PackageEntryColumn::GetPreferredWidth(BField *_field, BView* parent) const
     410{
     411    BitmapStringField* bitmapField
     412        = dynamic_cast<BitmapStringField*>(_field);
     413    BStringField* stringField = dynamic_cast<BStringField*>(_field);
     414
     415    float parentWidth = Inherited::GetPreferredWidth(_field, parent);
     416    float width = 0.0;
     417
     418    if (bitmapField) {
     419        const BBitmap* bitmap = bitmapField->Bitmap();
     420        BFont font;
     421        parent->GetFont(&font);
     422        width = font.StringWidth(bitmapField->String()) + 3 * sTextMargin;
     423        if (bitmap)
     424            width += bitmap->Bounds().Width();
     425        else
     426            width += 16;
     427    } else if (stringField) {
     428        BFont font;
     429        parent->GetFont(&font);
     430        width = font.StringWidth(stringField->String()) + 2 * sTextMargin;
     431    }
     432    return max_c(width, parentWidth);
     433}
     434
     435
     436bool
     437PackageEntryColumn::AcceptsField(const BField* field) const
     438{
     439    return dynamic_cast<const BStringField*>(field) != NULL;
    266440}
    267441
    268442
    269443void
    270 PackageContentsView::AttachedToWindow()
     444PackageEntryColumn::InitTextMargin(BView* parent)
     445{
     446    BFont font;
     447    parent->GetFont(&font);
     448    sTextMargin = ceilf(font.Size() * 0.8);
     449}
     450
     451
     452// #pragma mark - PackageEntryRow
     453
     454
     455enum {
     456    kTitleColumn,
     457    kSizeColumn,
     458    kPermissionsColumn,
     459    kLinkTargetsColumn,
     460};
     461
     462PackageEntryRow::PackageEntryRow(const PackageEntry* entry)
     463    :
     464    Inherited(ceilf(be_plain_font->Size() * 1.8f)),
     465    fPackageEntry(entry)
     466{
     467    // Package icon and title
     468    UpdateTitle();
     469
     470    // Size
     471    UpdateSize();
     472
     473    // Summary
     474    UpdatePermissions();
     475
     476    // Target Links
     477    UpdateLinkTargets();
     478}
     479
     480PackageEntryRow::PackageEntryRow(BString msg)
     481{
     482    SetField(new BStringField(msg), kTitleColumn);
     483}
     484
     485PackageEntryRow::~PackageEntryRow()
    271486{
    272     BView::AttachedToWindow();
    273487}
    274488
    275489
    276490void
    277 PackageContentsView::AllAttached()
     491PackageEntryRow::UpdateTitle()
    278492{
    279     BView::AllAttached();
     493        SetField(new BitmapStringField(Entry()), kTitleColumn);
    280494}
    281495
    282496
    283497void
    284 PackageContentsView::SetPackage(const PackageInfoRef& package)
     498PackageEntryRow::UpdateSize()
    285499{
    286     if (fPackage == package)
    287         return;
     500    char sizeBuffer[128];
     501    SetField(new BStringField(string_for_size(
     502                    (double) (((PackageEntry*) Entry())->Data().Size()),
     503                            sizeBuffer, sizeof(sizeBuffer))), kSizeColumn);
     504}
    288505
    289 //  printf("PackageContentsView::SetPackage(%s)\n",
    290 //      package.Get() != NULL ? package->Title().String() : "NULL");
    291506
    292     Clear();
     507void
     508PackageEntryRow::UpdatePermissions()
     509{
     510    PackageEntry* entry = (PackageEntry*) Entry();
     511    if (entry == NULL)
     512        return;
     513    mode_t mode = entry->Mode();
     514    BString perms;
     515   
     516    perms += (S_ISDIR(mode) ? "d" : "-");
     517    perms += ((mode & S_IRUSR) ? "r" : "-");
     518    perms += ((mode & S_IWUSR) ? "w" : "-");
     519    perms += ((mode & S_IXUSR) ? "x" : "-");
     520    perms += ((mode & S_IRGRP) ? "r" : "-");
     521    perms += ((mode & S_IWGRP) ? "w" : "-");
     522    perms += ((mode & S_IXGRP) ? "x" : "-");
     523    perms += ((mode & S_IROTH) ? "r" : "-");
     524    perms += ((mode & S_IWOTH) ? "w" : "-");
     525    perms += ((mode & S_IXOTH) ? "x" : "-");
     526   
     527    SetField(new BStringField(perms.String()), kPermissionsColumn);
     528}
    293529
    294     {
    295         BAutolock lock(&fPackageLock);
    296         fPackage = package;
    297     }
    298     release_sem_etc(fContentPopulatorSem, 1, 0);
     530
     531void
     532PackageEntryRow::UpdateLinkTargets()
     533{
     534    //TODO: Get link targets
     535    BString targets(Entry()->SymlinkPath());
     536    SetField(new BStringField(targets), kLinkTargetsColumn);
    299537}
    300538
    301539
    302 void
    303 PackageContentsView::Clear()
     540// #pragma mark - private
     541
     542PackageEntryRow*
     543PackageContentsView::_FindRow(const PackageEntry* entry, PackageEntryRow* parent)
    304544{
    305     {
    306         BAutolock lock(&fPackageLock);
    307         fPackage.Unset();
     545    for (int32 i = CountRows(parent) - 1; i >= 0; i--) {
     546        PackageEntryRow* row = dynamic_cast<PackageEntryRow*>(RowAt(i, parent));
     547        if (row != NULL && row->Entry() == entry)
     548            return row;
     549        if (CountRows(row) > 0) {
     550            // recurse into child rows
     551            row = _FindRow(entry, row);
     552            if (row != NULL)
     553                return row;
     554        }
    308555    }
    309556
    310     fContentListView->MakeEmpty();
     557    return NULL;
    311558}
    312559
    313560
    314 // #pragma mark - private
     561PackageEntryRow*
     562PackageContentsView::_FindRow(const BString& packageTitle, PackageEntryRow* parent)
     563{
     564    for (int32 i = CountRows(parent) - 1; i >= 0; i--) {
     565        PackageEntryRow* row = dynamic_cast<PackageEntryRow*>(RowAt(i, parent));
     566        if (row != NULL && row->Entry() != NULL
     567            && row->Entry()->Name() == packageTitle) {
     568            return row;
     569        }
     570        if (CountRows(row) > 0) {
     571            // recurse into child rows
     572            row = _FindRow(packageTitle, row);
     573            if (row != NULL)
     574                return row;
     575        }
     576    }
    315577
     578    return NULL;
     579}
    316580
    317581void
    318582PackageContentsView::_InitContentPopulator()
    319583{
     584    printf("In _InitContentPopulator\n");
    320585    fContentPopulatorSem = create_sem(0, "PopulatePackageContents");
    321586    if (fContentPopulatorSem >= 0) {
    322587        fContentPopulator = spawn_thread(&_ContentPopulatorThread,
    323588            "Package Contents Populator", B_NORMAL_PRIORITY, this);
    324         if (fContentPopulator >= 0)
     589        if (fContentPopulator >= 0) {
    325590            resume_thread(fContentPopulator);
     591            printf("fContentPopulator resumed!");
     592        }
    326593    } else
    327594        fContentPopulator = -1;
    328595}
    PackageContentsView::_InitContentPopulator()  
    332599PackageContentsView::_ContentPopulatorThread(void* arg)
    333600{
    334601    PackageContentsView* view = reinterpret_cast<PackageContentsView*>(arg);
    335 
     602    printf("In _ContentPopulatorThread\n");
     603    if(view == NULL) {
     604        printf("_ContentPopulatorThread:: View null!\n");
     605        return 1;
     606    } else  printf("_ContentPopulatorThread:: View not null\n");
    336607    while (acquire_sem(view->fContentPopulatorSem) == B_OK) {
     608        printf("_ContentPopulatorThread: Acquiring sem");
    337609        PackageInfoRef package;
    338610        {
    339611            BAutolock lock(&view->fPackageLock);
    340612            package = view->fPackage;
    341613        }
    342 
    343614        if (package.Get() != NULL) {
    344             if (!view->_PopuplatePackageContens(*package.Get())) {
     615                printf("In _ContentPopulatorThread: Package not null\n");
     616            if (!view->_PopulatePackageContents(view, *package.Get())) {
    345617                if (view->LockLooper()) {
    346                     view->fContentListView->AddItem(
    347                         new BStringItem(B_TRANSLATE("<Package contents not "
    348                             "available for remote packages>")));
     618                        printf("In _ContentPopulatorThread:Remote package\n");
     619                    PackageEntryRow* notAvailable = new PackageEntryRow(
     620                        "<Package contents not available for remote packages>");
     621                    view->AddRow(notAvailable);
     622                    view->ExpandOrCollapse(notAvailable, true);
    349623                    view->UnlockLooper();
    350624                }
    351625            }
    352         }
     626        }else   printf("In _ContentPopulatorThread: package null\n");
    353627    }
    354 
    355628    return 0;
    356629}
    357630
    358631
    359632bool
    360 PackageContentsView::_PopuplatePackageContens(const PackageInfo& package)
     633PackageContentsView::_PopulatePackageContents(PackageContentsView* view,
     634                                    const PackageInfo& package)
    361635{
    362636    BPath packagePath;
    363 
     637    printf("In _PopulatePackageContents\n");
    364638    // Obtain path to the package file
    365639    if (package.IsLocalFile()) {
    366640        BString pathString = package.LocalFilePath();
    PackageContentsView::_PopuplatePackageContens(const PackageInfo& package)  
    378652                return false;
    379653            }
    380654        } else {
    381             printf("PackageContentsView::_PopuplatePackageContens(): "
     655            printf("PackageContentsView::_PopulatePackageContents(): "
    382656                "unknown install location");
    383657            return false;
    384658        }
    PackageContentsView::_PopuplatePackageContens(const PackageInfo& package)  
    399673    }
    400674
    401675    // Scan package contents and populate list
    402     PackageContentOutliner contentHandler(fContentListView, &package,
    403         fPackageLock, fPackage);
     676    PackageContentOutliner contentHandler( &package,
     677        fPackageLock, fPackage, packagePath, view);
    404678    status = reader.ParseContent(&contentHandler);
    405679    if (status != B_OK) {
    406680        printf("PackageContentsView::SetPackage(): "
    PackageContentsView::_InstallLocation(const PackageInfo& package) const  
    424698
    425699    return B_PACKAGE_INSTALLATION_LOCATION_SYSTEM;
    426700}
     701
     702
     703// #pragma mark - PackageContentsView
     704
     705
     706PackageContentsView::PackageContentsView()
     707    :
     708    BColumnListView("package contents view", 0, B_FANCY_BORDER, true),
     709    fPackageLock("package contents populator lock")
     710{
     711    AddColumn(new PackageEntryColumn(B_TRANSLATE("Name"), 150, 50, 300,
     712        B_TRUNCATE_MIDDLE), kTitleColumn);
     713    AddColumn(new PackageEntryColumn(B_TRANSLATE("Size"), 80, 50, 100,
     714        B_TRUNCATE_MIDDLE), kSizeColumn);
     715    AddColumn(new PackageEntryColumn(B_TRANSLATE("Permissions"), 100, 80, 1000,
     716        B_TRUNCATE_MIDDLE), kPermissionsColumn);
     717    AddColumn(new PackageEntryColumn(B_TRANSLATE("Link Targets"), 200, 60, 100,
     718        B_TRUNCATE_END), kLinkTargetsColumn);
     719//  fItemCountView = new ItemCountView();
     720//  AddStatusView(fItemCountView);
     721}
     722
     723
     724PackageContentsView::~PackageContentsView()
     725{
     726    Clear();
     727    delete_sem(fContentPopulatorSem);
     728    if (fContentPopulator >= 0)
     729        wait_for_thread(fContentPopulator, NULL);
     730}
     731
     732
     733void
     734PackageContentsView::AttachedToWindow()
     735{
     736    BColumnListView::AttachedToWindow();
     737    PackageEntryColumn::InitTextMargin(ScrollView());
     738}
     739
     740
     741void
     742PackageContentsView::AllAttached()
     743{
     744    BColumnListView::AllAttached();
     745
     746    SetSortingEnabled(true);
     747    SetSortColumn(ColumnAt(0), false, true);
     748}
     749
     750
     751void
     752PackageContentsView::MessageReceived(BMessage* message)
     753{
     754    switch (message->what) {
     755/*      case MSG_UPDATE_PACKAGE:
     756        {
     757            BString title;
     758            uint32 changes;
     759            if (message->FindString("title", &title) != B_OK
     760                || message->FindUInt32("changes", &changes) != B_OK) {
     761                break;
     762            }
     763
     764            PackageEntryRow* row = _FindRow(title);
     765            if (row != NULL) {
     766                if ((changes & PKG_CHANGED_SUMMARY) != 0)
     767                    row->UpdateTitle(row->PackageEntry());
     768                if ((changes & PKG_CHANGED_RATINGS) != 0)
     769                    row->UpdateSize(row->PackageEntry());
     770                if ((changes & PKG_CHANGED_STATE) != 0)
     771                    row->UpdatePermissions(row->PackageEntry());
     772                if ((changes & PKG_CHANGED_ICON) != 0)
     773                    row->UpdateLinkTargets(row->PackageEntry());
     774            }
     775            break;
     776        }
     777*/
     778        default:
     779            BColumnListView::MessageReceived(message);
     780            break;
     781    }
     782}
     783
     784
     785void
     786PackageContentsView::SelectionChanged()
     787{
     788    BColumnListView::SelectionChanged();
     789
     790    BMessage message(MSG_PACKAGE_SELECTED);
     791
     792    PackageEntryRow* selected = dynamic_cast<PackageEntryRow*>(CurrentSelection());
     793    if (selected != NULL)
     794        message.AddString("title", selected->Entry()->Name());
     795
     796    Window()->PostMessage(&message);
     797}
     798
     799
     800void
     801PackageContentsView::Clear()
     802{
     803//  fItemCountView->SetItemCount(0);
     804    BColumnListView::Clear();
     805    BAutolock lock(&fPackageLock);
     806    fPackage.Unset();
     807}
     808
     809
     810void
     811PackageContentsView::AddPackageEntry(const PackageEntry& package)
     812{
     813    PackageEntryRow* packageRow =(PackageEntryRow*) _FindRow(&package);
     814    printf("In AddPackageEntry: %s\n", package.Name());
     815    // forget about it if this package is already in the listview
     816    if (packageRow != NULL)
     817        return;
     818
     819    BAutolock _(fPackageLock);
     820
     821    // create the row for this package
     822    packageRow = new PackageEntryRow(&package);
     823
     824    // add the row, parent may be NULL (add at top level)
     825    AddRow(packageRow);
     826
     827    // make sure the row is initially expanded
     828    ExpandOrCollapse(packageRow, true);
     829
     830//  fItemCountView->SetItemCount(CountRows());
     831}
     832
     833
     834void
     835PackageContentsView::SelectPackageEntry(const PackageEntry* entry)
     836{
     837    PackageEntryRow* row = (PackageEntryRow*) _FindRow(entry);
     838    BRow* selected = CurrentSelection();
     839    if (row != selected)
     840        DeselectAll();
     841    if (row != NULL) {
     842        AddToSelection(row);
     843        SetFocusRow(row, false);
     844        ScrollTo(row);
     845    }
     846}
     847
     848
     849void
     850PackageContentsView::SetPackage(const PackageInfoRef& package)
     851{
     852    fPackage = package;
     853    printf("\nPackage set to %s\n", (fPackage->Title()).String());
     854   
     855    printf("Initializing population\n");
     856    _InitContentPopulator();
     857}
     858
  • 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    }