Ticket #11007: patch-v4.patch

File patch-v4.patch, 156.6 KB (added by atalax, 9 years ago)

Use ColumnListView instead of Santa's CLV in Shortcuts

  • new file src/preferences/shortcuts/EditWindow.cpp

    diff --git a/src/preferences/shortcuts/EditWindow.cpp b/src/preferences/shortcuts/EditWindow.cpp
    new file mode 100644
    index 0000000..e2e08a6
    - +  
     1/*
     2 * Copyright 2015 Haiku, Inc. All rights reserved.
     3 * Distributed under the terms of the MIT License.
     4 *
     5 * Authors:
     6 *      Josef Gajdusek
     7 */
     8
     9
     10#include "EditWindow.h"
     11
     12#include <math.h>
     13
     14#include <Button.h>
     15#include <LayoutBuilder.h>
     16#include <TextControl.h>
     17#include <String.h>
     18#include <StringView.h>
     19
     20#include "ShortcutsWindow.h"
     21
     22
     23EditWindow::EditWindow(const char* placeholder, uint32 flags)
     24    :
     25    BWindow(BRect(0, 0, 0, 0), "", B_MODAL_WINDOW, flags)
     26{
     27    fTextControl = new BTextControl("", placeholder, NULL);
     28
     29    BButton* okButton = new BButton("Ok", new BMessage(B_CONTROL_MODIFIED));
     30    okButton->SetExplicitAlignment(BAlignment(B_ALIGN_RIGHT, B_ALIGN_TOP));
     31    SetDefaultButton(okButton);
     32
     33    BLayoutBuilder::Group<>(this, B_VERTICAL)
     34        .SetInsets(B_USE_WINDOW_INSETS)
     35        .Add(fTextControl)
     36        .Add(okButton);
     37}
     38
     39
     40void
     41EditWindow::MessageReceived(BMessage* message)
     42{
     43    switch (message->what) {
     44        case B_CONTROL_MODIFIED:
     45            delete_sem(fSem);
     46            break;
     47        default:
     48            BWindow::MessageReceived(message);
     49            break;
     50    }
     51}
     52
     53
     54BString
     55EditWindow::Go()
     56{
     57    fSem = create_sem(0, "EditSem");
     58    if (fSem < B_OK) {
     59        Quit();
     60        return "";
     61    }
     62
     63    BSize psize = GetLayout()->PreferredSize();
     64    ResizeTo(max_c(be_plain_font->StringWidth(fTextControl->Text()) * 1.5,
     65                psize.Width()),
     66        psize.Height());
     67    Show();
     68    CenterOnScreen();
     69
     70    acquire_sem(fSem);
     71    if (Lock())
     72        Quit();
     73    return fTextControl->Text();
     74}
  • new file src/preferences/shortcuts/EditWindow.h

    diff --git a/src/preferences/shortcuts/EditWindow.h b/src/preferences/shortcuts/EditWindow.h
    new file mode 100644
    index 0000000..99e88f3
    - +  
     1/*
     2 * Copyright 2015 Haiku, Inc. All rights reserved.
     3 * Distributed under the terms of the MIT License.
     4 *
     5 * Authors:
     6 *      Josef Gajdusek
     7 */
     8
     9#ifndef EDITWINDOW_H
     10#define EDITWINDOW_H
     11
     12#include <Window.h>
     13
     14class BTextControl;
     15
     16class EditWindow : public BWindow {
     17public:
     18                        EditWindow(const char* placeholder, uint32 flags);
     19
     20        void            MessageReceived(BMessage* message);
     21        BString         Go();
     22
     23private:
     24    sem_id              fSem;
     25    BTextControl*       fTextControl;
     26};
     27
     28#endif  // EDITWINDOW_H
  • src/preferences/shortcuts/Jamfile

    diff --git a/src/preferences/shortcuts/Jamfile b/src/preferences/shortcuts/Jamfile
    index 6ac4a3e..cf9e4b3 100644
    a b  
    11SubDir HAIKU_TOP src preferences shortcuts ;
    22
     3UsePrivateHeaders interface ;
     4
    35SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src preferences shortcuts clv ] ;
    46SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src add-ons input_server filters shortcut_catcher ] ;
    57
    Preference Shortcuts :  
    79    main.cpp
    810    MetaKeyStateMap.cpp
    911    ShortcutsApp.cpp
    10     ShortcutsSpec.cpp
    1112    ShortcutsWindow.cpp
     13    ShortcutsSpec.cpp
     14    PopUpColumn.cpp
     15    EditWindow.cpp
    1216
    13 #   clv files
    14     CLVColumn.cpp
    15     CLVColumnLabelView.cpp
    16     CLVListItem.cpp
    17     ColumnListView.cpp
    18     MouseWatcher.cpp
    19     PrefilledBitmap.cpp
    20     ScrollViewCorner.cpp
    21    
    22     : be localestub tracker libshortcuts_shared.a [ TargetLibstdc++ ]
     17    : be localestub tracker libshortcuts_shared.a libcolumnlistview.a [ TargetLibstdc++ ]
    2318    : Shortcuts.rdef
    2419;
    2520
  • new file src/preferences/shortcuts/PopUpColumn.cpp

    diff --git a/src/preferences/shortcuts/PopUpColumn.cpp b/src/preferences/shortcuts/PopUpColumn.cpp
    new file mode 100644
    index 0000000..e7f5b1e
    - +  
     1/*
     2 * Copyright 2015 Haiku, Inc. All rights reserved.
     3 * Distributed under the terms of the MIT License.
     4 *
     5 * Authors:
     6 *      Josef Gajdusek
     7 */
     8
     9
     10#include "PopUpColumn.h"
     11
     12#include <PopUpMenu.h>
     13#include <MenuItem.h>
     14#include <Window.h>
     15
     16#include "EditWindow.h"
     17#include "ShortcutsWindow.h"
     18
     19PopUpColumn::PopUpColumn(BPopUpMenu* menu, const char* name, float width,
     20    float minWidth, float maxWidth, uint32 truncate, bool editable,
     21    bool cycle, int cycleInit, alignment align)
     22    :
     23    BStringColumn(name, width, minWidth, maxWidth, truncate, align),
     24    fEditable(editable),
     25    fCycle(cycle),
     26    fCycleInit(cycleInit),
     27    fMenu(menu)
     28{
     29    SetWantsEvents(true);
     30}
     31
     32
     33PopUpColumn::~PopUpColumn()
     34{
     35    delete fMenu;
     36}
     37
     38void
     39PopUpColumn::MouseDown(BColumnListView* parent, BRow* row, BField* field,
     40    BRect fieldRect, BPoint point, uint32 buttons)
     41{
     42    if ((buttons & B_SECONDARY_MOUSE_BUTTON)
     43        || (buttons & B_PRIMARY_MOUSE_BUTTON && (fEditable || fCycle))) {
     44        BMessage* msg = new BMessage(ShortcutsWindow::HOTKEY_ITEM_MODIFIED);
     45        msg->SetInt32("row", parent->IndexOf(row));
     46        msg->SetInt32("column", LogicalFieldNum());
     47        if (buttons & B_SECONDARY_MOUSE_BUTTON) {
     48            BMenuItem* selected = fMenu->Go(parent->ConvertToScreen(point));
     49            if (selected) {
     50                msg->SetString("text", selected->Label());
     51                parent->Window()->PostMessage(msg);
     52            }
     53        }
     54        if (buttons & B_PRIMARY_MOUSE_BUTTON && row->IsSelected()) {
     55            BStringField* stringField = static_cast<BStringField*>(field);
     56            if (fEditable) {
     57                EditWindow* edit = new EditWindow(stringField->String(), 0);
     58                msg->SetString("text", edit->Go());
     59            } else if (fCycle) {
     60                BMenuItem* item;
     61                for (int i = 0; (item = fMenu->ItemAt(i)) != NULL; i++)
     62                    if (strcmp(stringField->String(), item->Label()) == 0) {
     63                        item = fMenu->ItemAt((i + 1) % fMenu->CountItems());
     64                        break;
     65                    }
     66                if (item == NULL)
     67                    item = fMenu->ItemAt(fCycleInit);
     68                msg->SetString("text", item->Label());
     69            }
     70            parent->Window()->PostMessage(msg);
     71        }
     72    }
     73    BStringColumn::MouseDown(parent, row, field, fieldRect, point, buttons);
     74}
     75
  • new file src/preferences/shortcuts/PopUpColumn.h

    diff --git a/src/preferences/shortcuts/PopUpColumn.h b/src/preferences/shortcuts/PopUpColumn.h
    new file mode 100644
    index 0000000..2b3e8fb
    - +  
     1/*
     2 * Copyright 2015 Haiku, Inc. All rights reserved.
     3 * Distributed under the terms of the MIT License.
     4 *
     5 * Authors:
     6 *      Josef Gajdusek
     7 */
     8#ifndef POPUPCOLUMN_H
     9#define POPUPCOLUMN_H
     10
     11#include <ColumnTypes.h>
     12
     13class BPopUpMenu;
     14
     15class PopUpColumn : public BStringColumn {
     16public:
     17                        PopUpColumn(BPopUpMenu* menu, const char* name,
     18                                float width, float minWidth, float maxWidth,
     19                                uint32 truncate, bool editable = false,
     20                                bool cycle = false, int cycleInit = 0,
     21                                alignment align = B_ALIGN_LEFT);
     22    virtual             ~PopUpColumn();
     23
     24            void        MouseDown(BColumnListView* parent, BRow* row,
     25                            BField* field, BRect fieldRect, BPoint point,
     26                            uint32 buttons);
     27
     28private:
     29            bool        fEditable;
     30            bool        fCycle;
     31            int         fCycleInit;
     32            BPopUpMenu* fMenu;
     33};
     34
     35#endif  // POPUPCOLUMN_H
  • src/preferences/shortcuts/ShortcutsSpec.cpp

    diff --git a/src/preferences/shortcuts/ShortcutsSpec.cpp b/src/preferences/shortcuts/ShortcutsSpec.cpp
    index 41917c4..b4a651b 100644
    a b  
    1414
    1515#include <Beep.h>
    1616#include <Catalog.h>
     17#include <ColumnTypes.h>
    1718#include <Directory.h>
    1819#include <Locale.h>
    1920#include <NodeInfo.h>
     
    2425#include "ColumnListView.h"
    2526
    2627#include "BitFieldTesters.h"
    27 #include "Colors.h"
    2828#include "CommandActuators.h"
     29#include "KeyInfos.h"
    2930#include "MetaKeyStateMap.h"
    3031#include "ParseCommandLine.h"
    3132
    static MetaKeyStateMap sMetaMaps[ShortcutsSpec::NUM_META_COLUMNS];  
    4243static bool sFontCached = false;
    4344static BFont sViewFont;
    4445static float sFontHeight;
    45 static BBitmap* sActuatorBitmaps[2];
    4646
    4747const char* ShortcutsSpec::sShiftName;
    4848const char* ShortcutsSpec::sControlName;
    GetNthKeyMap(int which)  
    9999}
    100100
    101101
    102 static BBitmap*
    103 MakeActuatorBitmap(bool lit)
    104 {
    105     BBitmap* map = new BBitmap(ICON_BITMAP_RECT, ICON_BITMAP_SPACE, true);
    106     const rgb_color yellow = {255, 255, 0};
    107     const rgb_color red = {200, 200, 200};
    108     const rgb_color black = {0, 0, 0};
    109     const BPoint points[10] = {
    110         BPoint(8, 0), BPoint(9.8, 5.8), BPoint(16, 5.8),
    111         BPoint(11, 9.0), BPoint(13, 16), BPoint(8, 11),
    112         BPoint(3, 16), BPoint(5, 9.0), BPoint(0, 5.8),
    113         BPoint(6.2, 5.8) };
    114 
    115     BView* view = new BView(BRect(0, 0, 16, 16), NULL, B_FOLLOW_ALL_SIDES, 0L);
    116     map->AddChild(view);
    117     map->Lock();
    118     view->SetHighColor(B_TRANSPARENT_32_BIT);
    119     view->FillRect(ICON_BITMAP_RECT);
    120     view->SetHighColor(lit ? yellow : red);
    121     view->FillPolygon(points, 10);
    122     view->SetHighColor(black);
    123     view->StrokePolygon(points, 10);
    124     map->Unlock();
    125     map->RemoveChild(view);
    126     delete view;
    127     return map;
    128 }
    129 
    130 
    131102/*static*/ void
    132103ShortcutsSpec::InitializeMetaMaps()
    133104{
    ShortcutsSpec::InitializeMetaMaps()  
    149120
    150121    SetupStandardMap(sMetaMaps[ShortcutsSpec::OPTION_COLUMN_INDEX], sOptionName
    151122        , B_OPTION_KEY, B_LEFT_OPTION_KEY, B_RIGHT_OPTION_KEY);
    152 
    153     sActuatorBitmaps[0] = MakeActuatorBitmap(false);
    154     sActuatorBitmaps[1] = MakeActuatorBitmap(true);
    155123}
    156124
    157125
    158126ShortcutsSpec::ShortcutsSpec(const char* cmd)
    159127    :
    160     CLVListItem(0, false, false, _height),
     128    BRow(),
    161129    fCommand(NULL),
    162     fTextOffset(0),
    163130    fBitmap(ICON_BITMAP_RECT, ICON_BITMAP_SPACE),
    164131    fLastBitmapName(NULL),
    165132    fBitmapValid(false),
    ShortcutsSpec::ShortcutsSpec(const char* cmd)  
    174141
    175142ShortcutsSpec::ShortcutsSpec(const ShortcutsSpec& from)
    176143    :
    177     CLVListItem(0, false, false, _height),
     144    BRow(),
    178145    fCommand(NULL),
    179     fTextOffset(from.fTextOffset),
    180146    fBitmap(ICON_BITMAP_RECT, ICON_BITMAP_SPACE),
    181147    fLastBitmapName(NULL),
    182148    fBitmapValid(false),
    ShortcutsSpec::ShortcutsSpec(const ShortcutsSpec& from)  
    188154
    189155    SetCommand(from.fCommand);
    190156    SetSelectedColumn(from.GetSelectedColumn());
     157
     158    for (int i = 0; i < from.CountFields(); i++)
     159        SetField(new BStringField(
     160                    static_cast<const BStringField*>(from.GetField(i))->String()), i);
    191161}
    192162
    193163
    194164ShortcutsSpec::ShortcutsSpec(BMessage* from)
    195165    :
    196     CLVListItem(0, false, false, _height),
     166    BRow(),
    197167    fCommand(NULL),
    198     fTextOffset(0),
    199168    fBitmap(ICON_BITMAP_RECT, ICON_BITMAP_SPACE),
    200169    fLastBitmapName(NULL),
    201170    fBitmapValid(false),
    ShortcutsSpec::ShortcutsSpec(BMessage* from)  
    221190            printf(CLASS);
    222191            printf(" Error, no modifiers int32 in archive BMessage!\n");
    223192        }
     193
     194    const char* string;
     195    for (int i = 0; (string = from->GetString("strings", i, NULL)); i++)
     196        SetField(new BStringField(string), i);
    224197}
    225198
    226199
    ShortcutsSpec::SetCommand(const char* command)  
    233206    fCommandNul = fCommandLen - 1;
    234207    fCommand = new char[fCommandLen];
    235208    strcpy(fCommand, command);
    236     _UpdateIconBitmap();
     209    SetField(new BStringField(command), STRING_COLUMN_INDEX);
    237210}
    238211
    239212
    ShortcutsSpec::Archive(BMessage* into, bool deep) const  
    253226
    254227    into->AddString("class", "ShortcutsSpec");
    255228
     229    for (int i = 0; i < CountFields(); i++) {
     230        const BStringField* field =
     231            static_cast<const BStringField*>(GetField(i));
     232        into->AddString("strings", field->String());
     233    }
     234
    256235    // These fields are for our prefs panel's benefit only
    257236    into->AddString("command", fCommand);
    258237    into->AddInt32("key", fKey);
    ShortcutsSpec::Archive(BMessage* into, bool deep) const  
    281260    delete act;
    282261
    283262    into->AddMessage("act", &actMsg);
    284     return ret;
    285 }
    286 
    287263
    288 static bool IsValidActuatorName(const char* c);
    289 static bool
    290 IsValidActuatorName(const char* c)
    291 {
    292     return (strcmp(c, B_TRANSLATE("InsertString")) == 0
    293         || strcmp(c, B_TRANSLATE("MoveMouse")) == 0
    294         || strcmp(c, B_TRANSLATE("MoveMouseTo")) == 0
    295         || strcmp(c, B_TRANSLATE("MouseButton")) == 0
    296         || strcmp(c, B_TRANSLATE("LaunchHandler")) == 0
    297         || strcmp(c, B_TRANSLATE("Multi")) == 0
    298         || strcmp(c, B_TRANSLATE("MouseDown")) == 0
    299         || strcmp(c, B_TRANSLATE("MouseUp")) == 0
    300         || strcmp(c, B_TRANSLATE("SendMessage")) == 0
    301         || strcmp(c, B_TRANSLATE("Beep")) == 0);
     264    return ret;
    302265}
    303266
    304267
    ShortcutsSpec::_CacheViewFont(BView* owner)  
    339302}
    340303
    341304
    342 void
    343 ShortcutsSpec::DrawItemColumn(BView* owner, BRect item_column_rect,
    344     int32 column_index, bool columnSelected, bool complete)
    345 {
    346     const float STRING_COLUMN_LEFT_MARGIN = 25.0f;
    347         // 16 for the icon, +9 empty
    348 
    349     rgb_color color;
    350     bool selected = IsSelected();
    351     if (selected)
    352         color = columnSelected ? BeBackgroundGrey : BeListSelectGrey;
    353     else
    354         color = BeInactiveControlGrey;
    355     owner->SetLowColor(color);
    356     owner->SetDrawingMode(B_OP_COPY);
    357     owner->SetHighColor(color);
    358     owner->FillRect(item_column_rect);
    359 
    360     const char* text = GetCellText(column_index);
    361 
    362     if (text == NULL)
    363         return;
    364 
    365     _CacheViewFont(owner);
    366         // Ensure that sViewFont is configured before using it to calculate
    367         // widths.  The lack of this call was causing the initial display of
    368         // columns to be incorrect, with a "jump" as all the columns correct
    369         // themselves upon the first column resize.
    370 
    371     float textWidth = sViewFont.StringWidth(text);
    372     BPoint point;
    373     rgb_color lowColor = color;
    374 
    375     if (column_index == STRING_COLUMN_INDEX) {
    376         // left justified
    377         point.Set(item_column_rect.left + STRING_COLUMN_LEFT_MARGIN,
    378             item_column_rect.top + fTextOffset);
    379 
    380         item_column_rect.left = point.x;
    381             // keep text from drawing into icon area
    382 
    383         // scroll if too wide
    384         float rectWidth = item_column_rect.Width() - STRING_COLUMN_LEFT_MARGIN;
    385         float extra = textWidth - rectWidth;
    386         if (extra > 0.0f)
    387             point.x -= extra;
    388     } else {
    389         if ((column_index < NUM_META_COLUMNS) && (text[0] == '('))
    390             return; // don't draw for this ...
    391 
    392         if ((column_index <= NUM_META_COLUMNS) && (text[0] == '\0'))
    393             return; // don't draw for this ...
    394 
    395         // centered
    396         point.Set((item_column_rect.left + item_column_rect.right) / 2.0,
    397             item_column_rect.top + fTextOffset);
    398         _CacheViewFont(owner);
    399         point.x -= textWidth / 2.0f;
    400     }
    401 
    402     BRegion Region;
    403     Region.Include(item_column_rect);
    404     owner->ConstrainClippingRegion(&Region);
    405     if (column_index != STRING_COLUMN_INDEX) {
    406         const float KEY_MARGIN = 3.0f;
    407         const float CORNER_RADIUS = 3.0f;
    408         _CacheViewFont(owner);
    409 
    410         // How about I draw a nice "key" background for this one?
    411         BRect textRect(point.x - KEY_MARGIN, (point.y - sFontHeight) - KEY_MARGIN,
    412             point.x + textWidth + KEY_MARGIN - 2.0f, point.y + KEY_MARGIN);
    413 
    414         if (column_index == KEY_COLUMN_INDEX)
    415             lowColor = ReallyLightPurple;
    416         else
    417             lowColor = LightYellow;
    418 
    419         owner->SetHighColor(lowColor);
    420         owner->FillRoundRect(textRect, CORNER_RADIUS, CORNER_RADIUS);
    421         owner->SetHighColor(Black);
    422         owner->StrokeRoundRect(textRect, CORNER_RADIUS, CORNER_RADIUS);
    423     }
    424 
    425     owner->SetHighColor(Black);
    426     owner->SetLowColor(lowColor);
    427     owner->DrawString(text, point);
    428     // with a cursor at the end if highlighted
    429     if (column_index == STRING_COLUMN_INDEX) {
    430         // Draw cursor
    431         if ((columnSelected) && (selected)) {
    432             point.x += textWidth;
    433             point.y += (fTextOffset / 4.0f);
    434 
    435             BPoint pt2 = point;
    436             pt2.y -= fTextOffset;
    437             owner->StrokeLine(point, pt2);
    438 
    439             fCursorPt1 = point;
    440             fCursorPt2 = pt2;
    441             fCursorPtsValid = true;
    442         }
    443 
    444         BRegion bitmapRegion;
    445         item_column_rect.left   -= (STRING_COLUMN_LEFT_MARGIN - 4.0f);
    446         item_column_rect.right  = item_column_rect.left + 16.0f;
    447         item_column_rect.top    += 3.0f;
    448         item_column_rect.bottom = item_column_rect.top + 16.0f;
    449 
    450         bitmapRegion.Include(item_column_rect);
    451         owner->ConstrainClippingRegion(&bitmapRegion);
    452         owner->SetDrawingMode(B_OP_ALPHA);
    453 
    454         if ((fCommand != NULL) && (fCommand[0] == '*'))
    455             owner->DrawBitmap(sActuatorBitmaps[fBitmapValid ? 1 : 0],
    456                 ICON_BITMAP_RECT, item_column_rect);
    457         else
    458             // Draw icon, if any
    459             if (fBitmapValid)
    460                 owner->DrawBitmap(&fBitmap, ICON_BITMAP_RECT,
    461                     item_column_rect);
    462     }
    463 
    464     owner->SetDrawingMode(B_OP_COPY);
    465     owner->ConstrainClippingRegion(NULL);
    466 }
    467 
    468 
    469 void
    470 ShortcutsSpec::Update(BView* owner, const BFont* font)
    471 {
    472     CLVListItem::Update(owner, font);
    473     font_height FontAttributes;
    474     be_plain_font->GetHeight(&FontAttributes);
    475     float fontHeight = ceil(FontAttributes.ascent) +
    476         ceil(FontAttributes.descent);
    477     fTextOffset = ceil(FontAttributes.ascent) + (Height() - fontHeight) / 2.0;
    478 }
    479 
    480 
    481305const char*
    482306ShortcutsSpec::GetCellText(int whichColumn) const
    483307{
    484308    const char* temp = ""; // default
    485     switch(whichColumn) {
     309    switch (whichColumn) {
    486310        case KEY_COLUMN_INDEX:
    487311        {
    488312            if ((fKey > 0) && (fKey <= 0xFF)) {
    ShortcutsSpec::GetCellText(int whichColumn) const  
    504328            if ((whichColumn >= 0) && (whichColumn < NUM_META_COLUMNS))
    505329                temp = sMetaMaps[whichColumn].GetNthStateDesc(
    506330                            fMetaCellStateIndex[whichColumn]);
     331            if (temp[0] == '(')
     332                temp = "";
    507333            break;
    508334    }
    509335    return temp;
    ShortcutsSpec::ProcessColumnMouseClick(int whichColumn)  
    527353bool
    528354ShortcutsSpec::ProcessColumnTextString(int whichColumn, const char* string)
    529355{
    530     switch(whichColumn) {
     356    switch (whichColumn) {
    531357        case STRING_COLUMN_INDEX:
    532358            SetCommand(string);
    533359            return true;
    ShortcutsSpec::ProcessColumnTextString(int whichColumn, const char* string)  
    536362        case KEY_COLUMN_INDEX:
    537363        {
    538364            fKey = FindKeyCode(string);
     365            SetField(new BStringField(GetCellText(whichColumn)),
     366                KEY_COLUMN_INDEX);
    539367            return true;
    540368            break;
    541369        }
    ShortcutsSpec::ProcessColumnKeyStroke(int whichColumn, const char* bytes,  
    669497{
    670498    bool result = false;
    671499
    672     switch(whichColumn) {
     500    switch (whichColumn) {
    673501        case KEY_COLUMN_INDEX:
    674502            if (key > -1) {
    675503                if ((int32)fKey != key) {
    ShortcutsSpec::ProcessColumnKeyStroke(int whichColumn, const char* bytes,  
    681509
    682510        case STRING_COLUMN_INDEX:
    683511        {
    684             switch(bytes[0]) {
     512            switch (bytes[0]) {
    685513                case B_BACKSPACE:
    686514                case B_DELETE:
    687515                    if (fCommandNul > 0) {
    ShortcutsSpec::ProcessColumnKeyStroke(int whichColumn, const char* bytes,  
    689517                        fCommand[fCommandNul - 1] = '\0';
    690518                        fCommandNul--;  // note new nul position
    691519                        result = true;
    692                         _UpdateIconBitmap();
    693520                    }
    694521                    break;
    695522
    696523                case B_TAB:
    697524                    if (_AttemptTabCompletion()) {
    698                         _UpdateIconBitmap();
    699525                        result = true;
    700526                    } else
    701527                        beep();
    ShortcutsSpec::ProcessColumnKeyStroke(int whichColumn, const char* bytes,  
    727553                        strncat(fCommand, bytes, fCommandLen);
    728554                        fCommandNul += newCharLen;
    729555                        result = true;
    730                         _UpdateIconBitmap();
    731556                    }
    732557                }
    733558            }
    ShortcutsSpec::ProcessColumnKeyStroke(int whichColumn, const char* bytes,  
    787612                result = true;
    788613    }
    789614
    790     return result;
    791 }
    792 
     615    SetField(new BStringField(GetCellText(whichColumn)), whichColumn);
    793616
    794 int
    795 ShortcutsSpec::CLVListItemCompare(const CLVListItem* firstItem,
    796     const CLVListItem* secondItem, int32 keyColumn)
    797 {
    798     ShortcutsSpec* left = (ShortcutsSpec*) firstItem;
    799     ShortcutsSpec* right = (ShortcutsSpec*) secondItem;
    800 
    801     int result = strcmp(left->GetCellText(keyColumn),
    802         right->GetCellText(keyColumn));
    803 
    804     return result > 0 ? 1 : (result == 0 ? 0 : -1);
    805 }
    806 
    807 
    808 void
    809 ShortcutsSpec::Pulse(BView* owner)
    810 {
    811     if ((fCursorPtsValid)&&(owner->Window()->IsActive())) {
    812         rgb_color prevColor = owner->HighColor();
    813         rgb_color backgroundColor = (GetSelectedColumn() ==
    814             STRING_COLUMN_INDEX) ? BeBackgroundGrey : BeListSelectGrey;
    815         rgb_color barColor = ((GetSelectedColumn() == STRING_COLUMN_INDEX)
    816             && ((system_time() % 1000000) > 500000)) ? Black : backgroundColor;
    817         owner->SetHighColor(barColor);
    818         owner->StrokeLine(fCursorPt1, fCursorPt2);
    819         owner->SetHighColor(prevColor);
    820     }
    821 }
    822 
    823 
    824 void
    825 ShortcutsSpec::_UpdateIconBitmap()
    826 {
    827     BString firstWord = ParseArgvZeroFromString(fCommand);
    828 
    829     // we only need to change if the first word has changed...
    830     if (fLastBitmapName == NULL || firstWord.Length() == 0
    831         || firstWord.Compare(fLastBitmapName)) {
    832         if (firstWord.ByteAt(0) == '*')
    833             fBitmapValid = IsValidActuatorName(&firstWord.String()[1]);
    834         else {
    835             fBitmapValid = false;
    836             // default until we prove otherwise
    837 
    838             if (firstWord.Length() > 0) {
    839                 delete [] fLastBitmapName;
    840                 fLastBitmapName = new char[firstWord.Length() + 1];
    841                 strcpy(fLastBitmapName, firstWord.String());
    842 
    843                 BEntry progEntry(fLastBitmapName, true);
    844                 if ((progEntry.InitCheck() == B_NO_ERROR)
    845                     && (progEntry.Exists())) {
    846                     BNode progNode(&progEntry);
    847                     if (progNode.InitCheck() == B_NO_ERROR) {
    848                         BNodeInfo progNodeInfo(&progNode);
    849                         if ((progNodeInfo.InitCheck() == B_NO_ERROR)
    850                         && (progNodeInfo.GetTrackerIcon(&fBitmap, B_MINI_ICON)
    851                             == B_NO_ERROR)) {
    852                             fBitmapValid = fBitmap.IsValid();
    853                         }
    854                     }
    855                 }
    856             }
    857         }
    858     }
     617    return result;
    859618}
    860619
    861620
  • src/preferences/shortcuts/ShortcutsSpec.h

    diff --git a/src/preferences/shortcuts/ShortcutsSpec.h b/src/preferences/shortcuts/ShortcutsSpec.h
    index 289656e..d43658a 100644
    a b  
    1212
    1313#include <Bitmap.h>
    1414
    15 #include "CLVListItem.h"
     15#include <ColumnListView.h>
    1616#include "KeyInfos.h"
    1717
    1818
    MetaKeyStateMap& GetNthKeyMap(int which);  
    2828 * the proper GUI display, and the proper BitFieldTester and CommandActuator
    2929 * object for the ShortcutsCatcher add-on to use.
    3030 */
    31 class ShortcutsSpec : public CLVListItem {
     31class ShortcutsSpec : public BRow, public BArchivable {
    3232public:
    3333    static  void            InitializeMetaMaps();
    3434
    public:  
    3838                            ~ShortcutsSpec();
    3939
    4040    virtual status_t        Archive(BMessage* into, bool deep = true) const;
    41     virtual void            Pulse(BView* owner);
    4241    static  BArchivable*    Instantiate(BMessage* from);
    43             void            Update(BView* owner, const BFont* font);
    4442    const   char*           GetCellText(int whichColumn) const;
    4543            void            SetCommand(const char* commandStr);
    4644
    47     virtual void            DrawItemColumn(BView* owner, BRect item_column_rect,
    48                                 int32 column_index, bool columnSelected,
    49                                 bool complete);
    50    
    51     static  int             CLVListItemCompare(const CLVListItem* firstItem,
    52                                 const CLVListItem* secondItem, int32 keyColumn);
    53 
    5445    // Returns the name of the Nth Column.
    5546    static  const char*     GetColumnName(int index);
    5647
    private:  
    8475            void            _CacheViewFont(BView* owner);
    8576            bool            _AttemptTabCompletion();
    8677
    87             // call this to ensure the icon is up-to-date
    88             void            _UpdateIconBitmap();
    89 
    9078            char*           fCommand;
    9179            uint32          fCommandLen;    // number of bytes in fCommand buffer
    9280            uint32          fCommandNul;    // index of the NUL byte in fCommand
    93             float           fTextOffset;
    9481
    9582            // icon for associated program. Invalid if none available.
    9683            BBitmap         fBitmap;
  • src/preferences/shortcuts/ShortcutsWindow.cpp

    diff --git a/src/preferences/shortcuts/ShortcutsWindow.cpp b/src/preferences/shortcuts/ShortcutsWindow.cpp
    index 953daaa..6cc3aa6 100644
    a b  
    1919#include <Button.h>
    2020#include <Catalog.h>
    2121#include <Clipboard.h>
     22#include <ColumnListView.h>
     23#include <ColumnTypes.h>
    2224#include <ControlLook.h>
    2325#include <File.h>
    2426#include <FilePanel.h>
    2527#include <FindDirectory.h>
    2628#include <Input.h>
     29#include <LayoutBuilder.h>
    2730#include <Locale.h>
    2831#include <Message.h>
    2932#include <Menu.h>
     
    3841#include <String.h>
    3942#include <SupportDefs.h>
    4043
    41 #include "ColumnListView.h"
    42 
     44#include "EditWindow.h"
    4345#include "KeyInfos.h"
    4446#include "MetaKeyStateMap.h"
    4547#include "ParseCommandLine.h"
     48#include "PopUpColumn.h"
    4649#include "ShortcutsFilterConstants.h"
    4750#include "ShortcutsSpec.h"
    4851
    ShortcutsWindow::ShortcutsWindow()  
    113116
    114117    float spacing = be_control_look->DefaultItemSpacing();
    115118
    116     BView* top = new BView(Bounds(), NULL, B_FOLLOW_ALL_SIDES, 0);
    117     top->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
    118     AddChild(top);
    119 
    120119    BMenuBar* menuBar = new BMenuBar(BRect(0, 0, 0, 0), "Menu Bar");
    121120
    122121    BMenu* fileMenu = new BMenu(B_TRANSLATE("File"));
    ShortcutsWindow::ShortcutsWindow()  
    136135        new BMessage(B_QUIT_REQUESTED), 'Q'));
    137136    menuBar->AddItem(fileMenu);
    138137
    139     top->AddChild(menuBar);
    140 
    141138    BRect tableBounds = Bounds();
    142139    tableBounds.top = menuBar->Bounds().bottom + 1;
    143140    tableBounds.right -= B_V_SCROLL_BAR_WIDTH;
    144141    tableBounds.bottom -= B_H_SCROLL_BAR_HEIGHT;
    145142
    146     BScrollView* containerView;
    147     fColumnListView = new ColumnListView(tableBounds, &containerView, NULL,
    148         B_FOLLOW_ALL_SIDES, B_WILL_DRAW | B_FRAME_EVENTS | B_NAVIGABLE,
    149         B_SINGLE_SELECTION_LIST, true, true, true, B_NO_BORDER);
    150 
    151     fColumnListView->SetEditMessage(new BMessage(HOTKEY_ITEM_MODIFIED),
    152         BMessenger(this));
     143    fColumnListView = new BColumnListView(NULL,
     144        B_WILL_DRAW | B_FRAME_EVENTS, B_FANCY_BORDER);
    153145
    154     float minListWidth = 0;
    155         // A running total is kept as the columns are created.
    156146    float cellWidth = be_plain_font->StringWidth("Either") + 20;
    157147        // ShortcutsSpec does not seem to translate the string "Either".
    158148
    ShortcutsWindow::ShortcutsWindow()  
    160150        const char* name = ShortcutsSpec::GetColumnName(i);
    161151        float headerWidth = be_plain_font->StringWidth(name) + 20;
    162152        float width = max_c(headerWidth, cellWidth);
    163         minListWidth += width + 1;
    164153
    165         fColumnListView->AddColumn(
    166             new CLVColumn(name, CreateMetaPopUp(i), width, CLV_SORT_KEYABLE));
     154        fColumnListView->AddColumn(new PopUpColumn(CreateMetaPopUp(i), name,
     155                width, width - 1, width * 1.5, B_TRUNCATE_END, false, true, 1),
     156            fColumnListView->CountColumns());
    167157    }
    168158
    169159    float keyCellWidth = be_plain_font->StringWidth("Caps Lock") + 20;
    170     fColumnListView->AddColumn(new CLVColumn(B_TRANSLATE("Key"),
    171         CreateKeysPopUp(), keyCellWidth, CLV_SORT_KEYABLE));
    172     minListWidth += keyCellWidth + 1;
    173 
     160    fColumnListView->AddColumn(new PopUpColumn(CreateKeysPopUp(),
     161            B_TRANSLATE("Key"), keyCellWidth, keyCellWidth - 10,
     162            keyCellWidth + 30, B_TRUNCATE_END),
     163        fColumnListView->CountColumns());
    174164    BPopUpMenu* popup = new BPopUpMenu(NULL, false);
    175165    popup->AddItem(new BMenuItem(
    176166        B_TRANSLATE("(Choose application with file requester)"), NULL));
    ShortcutsWindow::ShortcutsWindow()  
    190180    popup->AddItem(new BMenuItem(
    191181        B_TRANSLATE("*SendMessage application/x-vnd.Be-TRAK 'Tfnd'"), NULL));
    192182    popup->AddItem(new BMenuItem(B_TRANSLATE("*Beep"), NULL));
    193     fColumnListView->AddColumn(new CLVColumn(B_TRANSLATE("Application"), popup,
    194         323.0, CLV_SORT_KEYABLE));
    195     minListWidth += 323.0 + 1;
    196     minListWidth += B_V_SCROLL_BAR_WIDTH;
    197 
    198     fColumnListView->SetSortFunction(ShortcutsSpec::CLVListItemCompare);
    199     top->AddChild(containerView);
     183    fColumnListView->AddColumn(new PopUpColumn(popup, B_TRANSLATE("Application"),
     184            300.0, 223.0, 324.0, B_TRUNCATE_END, true),
     185        fColumnListView->CountColumns());
    200186
    201187    fColumnListView->SetSelectionMessage(new BMessage(HOTKEY_ITEM_SELECTED));
     188    fColumnListView->SetSelectionMode(B_SINGLE_SELECTION_LIST);
    202189    fColumnListView->SetTarget(this);
    203190
    204191    fAddButton = new BButton(BRect(0, 0, 0, 0), "add",
    ShortcutsWindow::ShortcutsWindow()  
    207194    fAddButton->ResizeToPreferred();
    208195    fAddButton->MoveBy(spacing,
    209196        Bounds().bottom - fAddButton->Bounds().bottom - spacing);
    210     top->AddChild(fAddButton);
    211197
    212198    fRemoveButton = new BButton(BRect(0, 0, 0, 0), "remove",
    213199        B_TRANSLATE("Remove selected shortcut"),
    ShortcutsWindow::ShortcutsWindow()  
    215201    fRemoveButton->ResizeToPreferred();
    216202    fRemoveButton->MoveBy(fAddButton->Frame().right + spacing,
    217203        Bounds().bottom - fRemoveButton->Bounds().bottom - spacing);
    218     top->AddChild(fRemoveButton);
    219204
    220205    fRemoveButton->SetEnabled(false);
    221206
    ShortcutsWindow::ShortcutsWindow()  
    225210    fSaveButton->ResizeToPreferred();
    226211    fSaveButton->MoveBy(Bounds().right - fSaveButton->Bounds().right - spacing,
    227212        Bounds().bottom - fSaveButton->Bounds().bottom - spacing);
    228     top->AddChild(fSaveButton);
    229213
    230214    fSaveButton->SetEnabled(false);
    231215
    232     containerView->ResizeBy(0,
    233         -(fAddButton->Bounds().bottom + 2 * spacing + 2));
    234 
    235     float minButtonBarWidth = fRemoveButton->Frame().right
    236         + fSaveButton->Bounds().right + 2 * spacing;
    237     float minWidth = max_c(minListWidth, minButtonBarWidth);
    238 
    239     float menuBarHeight = menuBar->Bounds().bottom;
    240     float buttonBarHeight = Bounds().bottom - containerView->Frame().bottom;
    241     float minHeight = menuBarHeight + 200 + buttonBarHeight;
    242 
    243     SetSizeLimits(minWidth, MAX_WIDTH, minHeight, MAX_HEIGHT);
    244         // SetSizeLimits() will resize the window to the minimum size.
    245 
    246216    CenterOnScreen();
    247217
    248218    entry_ref windowSettingsRef;
    ShortcutsWindow::ShortcutsWindow()  
    265235            // tell ourselves to load this file if it exists
    266236    }
    267237
     238    fColumnListView->ResizeAllColumnsToPreferred();
     239
     240    BLayoutBuilder::Group<>(this, B_VERTICAL, 0)
     241        .Add(menuBar)
     242        .AddGroup(B_VERTICAL)
     243            .SetInsets(B_USE_WINDOW_INSETS)
     244            .Add(fColumnListView)
     245            .AddGroup(B_HORIZONTAL)
     246                .AddGroup(B_HORIZONTAL)
     247                .SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, B_ALIGN_TOP))
     248                .Add(fAddButton)
     249                .Add(fRemoveButton)
     250                .End()
     251                .AddGroup(B_HORIZONTAL)
     252                    .SetExplicitAlignment(BAlignment(B_ALIGN_RIGHT, B_ALIGN_TOP))
     253                    .Add(fSaveButton)
     254                .End()
     255            .End()
     256        .End();
     257
    268258    Show();
    269259}
    270260
    ShortcutsWindow::QuitRequested()  
    291281        alert->SetShortcut(0, B_ESCAPE);
    292282        alert->SetShortcut(1, 'd');
    293283        alert->SetShortcut(2, 's');
    294         switch(alert->Go()) {
     284        switch (alert->Go()) {
    295285            case 0:
    296286                result = false;
    297287                break;
    ShortcutsWindow::QuitRequested()  
    311301                            B_TRANSLATE("Oh no"));
    312302                        alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
    313303                        alert->Go();
    314                         result = true; //quit anyway
     304                        result = true; // quit anyway
    315305                    }
    316306                } else {
    317307                    PostMessage(SAVE_KEYSET);
    ShortcutsWindow::_SaveKeySet(BEntry& saveEntry)  
    361351        return false;
    362352
    363353    BMessage saveMessage;
    364     for (int i = 0; i < fColumnListView->CountItems(); i++) {
     354    for (int i = 0; i < fColumnListView->CountRows(); i++) {
    365355        BMessage next;
    366         if (((ShortcutsSpec*)fColumnListView->ItemAt(i))->Archive(&next)
     356        if (((ShortcutsSpec*)fColumnListView->RowAt(i))->Archive(&next)
    367357                == B_OK) {
    368358            saveMessage.AddMessage("spec", &next);
    369359        } else
    ShortcutsWindow::_LoadKeySet(const BMessage& loadMessage)  
    392382        ShortcutsSpec* spec
    393383            = (ShortcutsSpec*)ShortcutsSpec::Instantiate(&message);
    394384        if (spec != NULL)
    395             fColumnListView->AddItem(spec);
     385            fColumnListView->AddRow(spec);
    396386        else
    397387            printf("_LoadKeySet: Error parsing spec!\n");
    398388    }
    ShortcutsWindow::_SaveWindowSettings(BEntry& saveEntry)  
    428418    saveMsg.AddRect("window frame", Frame());
    429419
    430420    for (int i = 0; i < fColumnListView->CountColumns(); i++) {
    431         CLVColumn* column = fColumnListView->ColumnAt(i);
     421        BColumn* column = fColumnListView->ColumnAt(i);
    432422        saveMsg.AddFloat("column width", column->Width());
    433423    }
    434424
    ShortcutsWindow::_LoadWindowSettings(const BMessage& loadMessage)  
    457447    }
    458448
    459449    for (int i = 0; i < fColumnListView->CountColumns(); i++) {
    460         CLVColumn* column = fColumnListView->ColumnAt(i);
     450        BColumn* column = fColumnListView->ColumnAt(i);
    461451        float columnWidth;
    462452        if (loadMessage.FindFloat("column width", i, &columnWidth) == B_OK)
    463453            column->SetWidth(max_c(column->Width(), columnWidth));
    ShortcutsWindow::_AddNewSpec(const char* defaultCommand)  
    473463    _MarkKeySetModified();
    474464
    475465    ShortcutsSpec* spec;
    476     int curSel = fColumnListView->CurrentSelection();
    477     if (curSel >= 0) {
    478         spec = new ShortcutsSpec(*((ShortcutsSpec*)
    479             fColumnListView->ItemAt(curSel)));
    480 
    481         if (defaultCommand)
    482             spec->SetCommand(defaultCommand);
    483     } else
    484         spec = new ShortcutsSpec(defaultCommand ? defaultCommand : "");
    485 
    486     fColumnListView->AddItem(spec);
    487     fColumnListView->Select(fColumnListView->CountItems() - 1);
    488     fColumnListView->ScrollToSelection();
     466    BRow* curSel = fColumnListView->CurrentSelection();
     467    if (curSel)
     468        spec = new ShortcutsSpec(*((ShortcutsSpec*)curSel));
     469    else {
     470        spec = new ShortcutsSpec("");
     471        for (int i = 0; i < fColumnListView->CountColumns(); i++)
     472            spec->SetField(new BStringField(""), i);
     473    }
     474
     475    fColumnListView->AddRow(spec);
     476    fColumnListView->AddToSelection(spec);
     477    fColumnListView->ScrollTo(spec);
     478    if (defaultCommand)
     479        spec->SetCommand(defaultCommand);
    489480}
    490481
    491482
    492483void
    493484ShortcutsWindow::MessageReceived(BMessage* message)
    494485{
    495     switch(message->what) {
     486    switch (message->what) {
    496487        case OPEN_KEYSET:
    497488        case APPEND_KEYSET:
    498489            fLastOpenWasAppend = (message->what == APPEND_KEYSET);
    ShortcutsWindow::MessageReceived(BMessage* message)  
    531522                BEntry entry(&ref);
    532523                if (entry.InitCheck() == B_OK) {
    533524                    BPath path(&entry);
    534                    
     525
    535526                    if (path.InitCheck() == B_OK) {
    536527                        // Add a new item with the given path.
    537528                        BString str(path.Path());
    ShortcutsWindow::MessageReceived(BMessage* message)  
    570561                        }
    571562                    }
    572563                }
    573  
     564
    574565                if (fLastOpenWasAppend == false) {
    575566                    // Clear the menu...
    576                     while (ShortcutsSpec* item
    577                         = ((ShortcutsSpec*)
    578                             fColumnListView->RemoveItem((int32)0))) {
    579                         delete item;
     567                    while (fColumnListView->CountRows()) {
     568                        ShortcutsSpec* row =
     569                            static_cast<ShortcutsSpec*>(fColumnListView->RowAt(0));
     570                        fColumnListView->RemoveRow(row);
     571                        delete row;
    580572                    }
    581573                }
    582574
    ShortcutsWindow::MessageReceived(BMessage* message)  
    604596        // these messages come from the pop-up menu of the Applications column
    605597        case SELECT_APPLICATION:
    606598        {
    607             int csel = fColumnListView->CurrentSelection();
    608             if (csel >= 0) {
     599            ShortcutsSpec* row =
     600                static_cast<ShortcutsSpec*>(fColumnListView->CurrentSelection());
     601            if (row != NULL) {
    609602                entry_ref aref;
    610603                if (message->FindRef("refs", &aref) == B_OK) {
    611604                    BEntry ent(&aref);
    612605                    if (ent.InitCheck() == B_OK) {
    613606                        BPath path;
    614607                        if ((ent.GetPath(&path) == B_OK)
    615                             && (((ShortcutsSpec*)fColumnListView->ItemAt(csel))->
     608                            && (row->
    616609                                ProcessColumnTextString(ShortcutsSpec::STRING_COLUMN_INDEX,
    617610                                    path.Path()))) {
    618                             fColumnListView->InvalidateItem(csel);
    619611                            _MarkKeySetModified();
    620612                        }
    621613                    }
    ShortcutsWindow::MessageReceived(BMessage* message)  
    673665
    674666        case REMOVE_HOTKEY_ITEM:
    675667        {
    676             int index = fColumnListView->CurrentSelection();
    677             if (index >= 0) {
    678                 CLVListItem* item = (CLVListItem*)
    679                     fColumnListView->ItemAt(index);
    680                 fColumnListView->RemoveItem(index);
     668            BRow* item = fColumnListView->CurrentSelection();
     669            if (item) {
     670                int index = fColumnListView->IndexOf(item);
     671                fColumnListView->RemoveRow(item);
    681672                delete item;
    682673                _MarkKeySetModified();
    683674
    684675                // Rules for new selection: If there is an item at (index),
    685676                // select it. Otherwise, if there is an item at (index-1),
    686677                // select it. Otherwise, select nothing.
    687                 int num = fColumnListView->CountItems();
     678                int num = fColumnListView->CountRows();
    688679                if (num > 0) {
    689680                    if (index < num)
    690                         fColumnListView->Select(index);
     681                        fColumnListView->AddToSelection(
     682                            fColumnListView->RowAt(index));
    691683                    else {
    692684                        if (index > 0)
    693685                            index--;
    694                         if (index < num)
    695                             fColumnListView->Select(index);
     686                        if (index < num)
     687                            fColumnListView->AddToSelection(
     688                                fColumnListView->RowAt(index));
    696689                    }
    697690                }
    698691            }
    ShortcutsWindow::MessageReceived(BMessage* message)  
    702695        // Received when the user clicks on the ColumnListView
    703696        case HOTKEY_ITEM_SELECTED:
    704697        {
    705             int32 index = -1;
    706             message->FindInt32("index", &index);
    707             bool validItem = (index >= 0);
    708             fRemoveButton->SetEnabled(validItem);
     698            if (fColumnListView->CountRows() > 0)
     699                fRemoveButton->SetEnabled(true);
     700            else
     701                fRemoveButton->SetEnabled(false);
    709702            break;
    710703        }
    711704
    ShortcutsWindow::MessageReceived(BMessage* message)  
    721714
    722715                if (row >= 0) {
    723716                    ShortcutsSpec* item = (ShortcutsSpec*)
    724                         fColumnListView->ItemAt(row);
     717                        fColumnListView->RowAt(row);
    725718                    bool repaintNeeded = false; // default
    726719
    727720                    if (message->HasInt32("mouseClick")) {
    728721                        repaintNeeded = item->ProcessColumnMouseClick(column);
    729722                    } else if ((message->FindString("bytes", &bytes) == B_OK)
    730723                        && (message->FindInt32("key", &key) == B_OK)) {
    731                         repaintNeeded = item->ProcessColumnKeyStroke(column, 
     724                        repaintNeeded = item->ProcessColumnKeyStroke(column,
    732725                            bytes, key);
    733726                    } else if (message->FindInt32("unmappedkey", &key) ==
    734727                        B_OK) {
    735                         repaintNeeded = ((column == item->KEY_COLUMN_INDEX) 
    736                             && ((key > 0xFF) || (GetKeyName(key) != NULL)) 
    737                             && (item->ProcessColumnKeyStroke(column, NULL, 
     728                        repaintNeeded = ((column == item->KEY_COLUMN_INDEX)
     729                            && ((key > 0xFF) || (GetKeyName(key) != NULL))
     730                            && (item->ProcessColumnKeyStroke(column, NULL,
    738731                            key)));
    739732                    } else if (message->FindString("text", &bytes) == B_OK) {
    740733                        if ((bytes[0] == '(')&&(bytes[1] == 'C')) {
    ShortcutsWindow::MessageReceived(BMessage* message)  
    747740                                    NULL, 0, false, &message);
    748741                                fSelectPanel->Show();
    749742                            }
    750                             fSelectPanel->SetButtonLabel(B_DEFAULT_BUTTON, 
     743                            fSelectPanel->SetButtonLabel(B_DEFAULT_BUTTON,
    751744                                B_TRANSLATE("Select"));
    752                         } else {
     745                        } else
    753746                            repaintNeeded = item->ProcessColumnTextString(
    754747                                column, bytes);
    755                         }
    756748                    }
    757                    
     749
    758750                    if (repaintNeeded) {
    759                         fColumnListView->InvalidateItem(row);
     751                        fColumnListView->Invalidate(row);
    760752                        _MarkKeySetModified();
    761753                    }
    762754                }
    ShortcutsWindow::_MarkKeySetModified()  
    784776void
    785777ShortcutsWindow::Quit()
    786778{
    787     for (int i = fColumnListView->CountItems() - 1; i >= 0; i--)
    788         delete (ShortcutsSpec*)fColumnListView->ItemAt(i);
    789 
    790     fColumnListView->MakeEmpty();
    791779    BWindow::Quit();
    792780}
    793781
    ShortcutsWindow::Quit()  
    795783void
    796784ShortcutsWindow::DispatchMessage(BMessage* message, BHandler* handler)
    797785{
    798     switch(message->what) {
     786    switch (message->what) {
     787        case B_SIMPLE_DATA:
     788            MessageReceived(message);
     789            break;
     790
    799791        case B_COPY:
    800792        case B_CUT:
    801793            if (be_clipboard->Lock()) {
    802                 int32 row = fColumnListView->CurrentSelection();
    803                 int32 column = fColumnListView->GetSelectedColumn();
    804                 if ((row >= 0)
    805                     && (column == ShortcutsSpec::STRING_COLUMN_INDEX)) {
    806                     ShortcutsSpec* spec = (ShortcutsSpec*)
    807                         fColumnListView->ItemAt(row);
    808                     if (spec) {
    809                         BMessage* data = be_clipboard->Data();
    810                         data->RemoveName("text/plain");
    811                         data->AddData("text/plain", B_MIME_TYPE,
    812                             spec->GetCellText(column),
    813                             strlen(spec->GetCellText(column)));
    814                         be_clipboard->Commit();
    815                        
    816                         if (message->what == B_CUT) {
    817                             spec->ProcessColumnTextString(column, "");
    818                             _MarkKeySetModified();
    819                             fColumnListView->InvalidateItem(row);
    820                         }
     794                ShortcutsSpec* row =
     795                    static_cast<ShortcutsSpec*>(fColumnListView->CurrentSelection());
     796                if (row) {
     797                    BMessage* data = be_clipboard->Data();
     798                    data->RemoveName("text/plain");
     799                    data->AddData("text/plain", B_MIME_TYPE,
     800                        row->GetCellText(ShortcutsSpec::STRING_COLUMN_INDEX),
     801                        strlen(row->GetCellText(ShortcutsSpec::STRING_COLUMN_INDEX)));
     802                    be_clipboard->Commit();
     803
     804                    if (message->what == B_CUT) {
     805                        row->ProcessColumnTextString(
     806                            ShortcutsSpec::STRING_COLUMN_INDEX, "");
     807                        _MarkKeySetModified();
    821808                    }
    822809                }
    823810                be_clipboard->Unlock();
    ShortcutsWindow::DispatchMessage(BMessage* message, BHandler* handler)  
    831818                ssize_t textLen;
    832819                if (data->FindData("text/plain", B_MIME_TYPE, (const void**)
    833820                    &text, &textLen) == B_OK) {
    834                     int32 row = fColumnListView->CurrentSelection();
    835                     int32 column = fColumnListView->GetSelectedColumn();
    836                     if ((row >= 0)
    837                         && (column == ShortcutsSpec::STRING_COLUMN_INDEX)) {
    838                         ShortcutsSpec* spec = (ShortcutsSpec*)
    839                             fColumnListView->ItemAt(row);
    840                         if (spec) {
    841                             for (ssize_t i = 0; i < textLen; i++) {
    842                                 char buf[2] = {text[i], 0x00};
    843                                 spec->ProcessColumnKeyStroke(column, buf, 0);
    844                             }
     821                    ShortcutsSpec* row =
     822                    static_cast<ShortcutsSpec*>(fColumnListView->CurrentSelection());
     823                    if (row) {
     824                        for (ssize_t i = 0; i < textLen; i++) {
     825                            char buf[2] = {text[i], 0x00};
     826                            row->ProcessColumnKeyStroke(
     827                                ShortcutsSpec::STRING_COLUMN_INDEX, buf, 0);
    845828                        }
    846                         fColumnListView->InvalidateItem(row);
    847                         _MarkKeySetModified();
    848829                    }
     830                    _MarkKeySetModified();
    849831                }
    850832                be_clipboard->Unlock();
    851833            }
    852834            break;
    853        
     835
     836        case B_KEY_DOWN:
     837            ShortcutsSpec* selected;
     838            if (message->GetInt32("modifiers", 0) != 0)
     839                BWindow::DispatchMessage(message, handler);
     840            else if (handler == fColumnListView
     841                && (selected =
     842                    static_cast<ShortcutsSpec*>(fColumnListView->CurrentSelection()))) {
     843                selected->ProcessColumnTextString(
     844                        ShortcutsSpec::KEY_COLUMN_INDEX,
     845                        GetKeyName(message->GetInt32("key", 0)));
     846                _MarkKeySetModified();
     847            }
     848            break;
     849
    854850        default:
    855851            BWindow::DispatchMessage(message, handler);
    856852            break;
  • src/preferences/shortcuts/ShortcutsWindow.h

    diff --git a/src/preferences/shortcuts/ShortcutsWindow.h b/src/preferences/shortcuts/ShortcutsWindow.h
    index 792ec2d..00d1001 100644
    a b  
    1010#define SHORTCUTS_WINDOW_H
    1111
    1212
     13#include <ColumnListView.h>
    1314#include <Entry.h>
    1415#include <Window.h>
    1516
    16 #include "ColumnListView.h"
    17 
    1817
    1918class BButton;
     19class BColumnListView;
    2020class BFilePanel;
    2121class BMessage;
     22class ShortcutsSpec;
    2223
    2324// This class defines our preferences/configuration window.
    2425class ShortcutsWindow : public BWindow {
    private:  
    6970            BButton*            fAddButton;
    7071            BButton*            fRemoveButton;
    7172            BButton*            fSaveButton;
    72             ColumnListView*     fColumnListView;
     73            BColumnListView*    fColumnListView;
    7374            BFilePanel*         fSavePanel;
    7475                // for saving settings
    7576            BFilePanel*         fOpenPanel;
    private:  
    8586
    8687            // true iff the file-requester's ref should be appended to current
    8788            bool                fLastOpenWasAppend;
     89
     90            BRow*               fSelectedRow;
    8891};
    8992
    9093
  • deleted file src/preferences/shortcuts/clv/CLVColumn.cpp

    diff --git a/src/preferences/shortcuts/clv/CLVColumn.cpp b/src/preferences/shortcuts/clv/CLVColumn.cpp
    deleted file mode 100644
    index 1b3e635..0000000
    + -  
    1 /*
    2  * Copyright 1999-2009 Jeremy Friesner
    3  * Copyright 2009-2014 Haiku, Inc. All rights reserved.
    4  * Distributed under the terms of the MIT License.
    5  *
    6  * Authors:
    7  *      Jeremy Friesner
    8  *      John Scipione, jscipione@gmail.com
    9  */
    10 
    11 
    12 #define CLVColumn_CPP
    13 
    14 #include <string.h>
    15 
    16 #include "CLVColumn.h"
    17 #include "ColumnListView.h"
    18 #include "CLVColumnLabelView.h"
    19 
    20 
    21 CLVColumn::CLVColumn(const char* label, BPopUpMenu* popup, float width,
    22     uint32 flags, float minWidth)
    23 {
    24     fPopup = popup;
    25 
    26     if (flags & CLV_EXPANDER) {
    27         label = NULL;
    28         width = 20.0;
    29         minWidth = 20.0;
    30         flags &= CLV_NOT_MOVABLE | CLV_LOCK_AT_BEGINNING | CLV_HIDDEN
    31             | CLV_LOCK_WITH_RIGHT;
    32         flags |= CLV_EXPANDER | CLV_NOT_RESIZABLE | CLV_MERGE_WITH_RIGHT;
    33     }
    34 
    35     if (minWidth < 4.0)
    36         minWidth = 4.0;
    37 
    38     if (width < minWidth)
    39         width = minWidth;
    40 
    41     if (label != NULL) {
    42         fLabel = new char[strlen(label) + 1];
    43         strcpy((char*)fLabel, label);
    44     } else
    45         fLabel = NULL;
    46 
    47     fWidth = width;
    48     fMinWidth = minWidth;
    49     fFlags = flags;
    50     fPushedByExpander = false;
    51     fParent = NULL;
    52     fSortMode = SORT_MODE_NONE;
    53 }
    54 
    55 
    56 CLVColumn::~CLVColumn()
    57 {
    58     delete[] fLabel;
    59     if (fParent != NULL)
    60         fParent->RemoveColumn(this);
    61 
    62     delete fPopup;
    63 }
    64 
    65 
    66 float
    67 CLVColumn::Width() const
    68 {
    69     return fWidth;
    70 }
    71 
    72 
    73 void
    74 CLVColumn::SetWidth(float width)
    75 {
    76     if(width < fMinWidth)
    77         width = fMinWidth;
    78 
    79     if(width != fWidth) {
    80         float oldWidth = fWidth;
    81         fWidth = width;
    82         if (IsShown() && fParent != NULL) {
    83             BWindow* parentWindow = fParent->Window();
    84             if (parentWindow != NULL)
    85                 parentWindow->Lock();
    86 
    87             // figure out the area after this column to scroll
    88             BRect ColumnViewBounds = fParent->fColumnLabelView->Bounds();
    89             BRect MainViewBounds = fParent->Bounds();
    90             BRect sourceArea = ColumnViewBounds;
    91             sourceArea.left = fColumnEnd + 1.0;
    92             BRect destArea = sourceArea;
    93             float delta = width-oldWidth;
    94             destArea.left += delta;
    95             destArea.right += delta;
    96             float LimitShift;
    97             if (destArea.right > ColumnViewBounds.right) {
    98                 LimitShift = destArea.right-ColumnViewBounds.right;
    99                 destArea.right -= LimitShift;
    100                 sourceArea.right -= LimitShift;
    101             }
    102             if (destArea.left < ColumnViewBounds.left) {
    103                 LimitShift = ColumnViewBounds.left - destArea.left;
    104                 destArea.left += LimitShift;
    105                 sourceArea.left += LimitShift;
    106             }
    107 
    108             // scroll the area that is being shifted
    109             if(parentWindow)
    110                 parentWindow->UpdateIfNeeded();
    111 
    112             fParent->fColumnLabelView->CopyBits(sourceArea, destArea);
    113             sourceArea.top = MainViewBounds.top;
    114             sourceArea.bottom = MainViewBounds.bottom;
    115             destArea.top = MainViewBounds.top;
    116             destArea.bottom = MainViewBounds.bottom;
    117             fParent->CopyBits(sourceArea, destArea);
    118 
    119             // invalidate the region that got revealed
    120             destArea = ColumnViewBounds;
    121             if (width > oldWidth) {
    122                 destArea.left = fColumnEnd + 1.0;
    123                 destArea.right = fColumnEnd + delta;
    124             } else {
    125                 destArea.left = ColumnViewBounds.right + delta + 1.0;
    126                 destArea.right = ColumnViewBounds.right;
    127             }
    128             fParent->fColumnLabelView->Invalidate(destArea);
    129             destArea.top = MainViewBounds.top;
    130             destArea.bottom = MainViewBounds.bottom;
    131             fParent->Invalidate(destArea);
    132 
    133             // invalidate the old or new resize handle as necessary
    134             destArea = ColumnViewBounds;
    135             if (width > oldWidth)
    136                 destArea.left = fColumnEnd;
    137             else
    138                 destArea.left = fColumnEnd + delta;
    139 
    140             destArea.right = destArea.left;
    141             fParent->fColumnLabelView->Invalidate(destArea);
    142 
    143             // update the column sizes, positions and group positions
    144             fParent->ShiftDragGroup();
    145             fParent->fColumnLabelView->UpdateDragGroups();
    146             if(parentWindow)
    147                 parentWindow->Unlock();
    148         }
    149         if (fParent != NULL) {
    150             fParent->ColumnWidthChanged(fParent->fColumnList.IndexOf(this),
    151                 fWidth);
    152         }
    153     }
    154 }
    155 
    156 
    157 uint32
    158 CLVColumn::Flags() const
    159 {
    160     return fFlags;
    161 }
    162 
    163 
    164 bool
    165 CLVColumn::IsShown() const
    166 {
    167     if ((fFlags & CLV_HIDDEN) != 0)
    168         return false;
    169     else
    170         return true;
    171 }
    172 
    173 
    174 void
    175 CLVColumn::SetShown(bool show)
    176 {
    177     bool shown = IsShown();
    178     if (shown != show) {
    179         if (show)
    180             fFlags &= 0xFFFFFFFF^CLV_HIDDEN;
    181         else
    182             fFlags |= CLV_HIDDEN;
    183 
    184         if (fParent != NULL) {
    185             float updateLeft = fColumnBegin;
    186             BWindow* parentWindow = fParent->Window();
    187             if (parentWindow != NULL)
    188                 parentWindow->Lock();
    189 
    190             fParent->ShiftDragGroup();
    191             fParent->fColumnLabelView->UpdateDragGroups();
    192             if (show)
    193                 updateLeft = fColumnBegin;
    194 
    195             BRect area = fParent->fColumnLabelView->Bounds();
    196             area.left = updateLeft;
    197             fParent->fColumnLabelView->Invalidate(area);
    198             area = fParent->Bounds();
    199             area.left = updateLeft;
    200             fParent->Invalidate(area);
    201             if ((fFlags & CLV_EXPANDER) != 0) {
    202                 if (!show)
    203                     fParent->fExpanderColumn = -1;
    204                 else
    205                     fParent->fExpanderColumn = fParent->IndexOfColumn(this);
    206             }
    207             if (parentWindow != NULL)
    208                 parentWindow->Unlock();
    209         }
    210     }
    211 }
    212 
    213 
    214 CLVSortMode
    215 CLVColumn::SortMode() const
    216 {
    217     return fSortMode;
    218 }
    219 
    220 
    221 void
    222 CLVColumn::SetSortMode(CLVSortMode mode)
    223 {
    224     if (fParent != NULL)
    225         fParent->SetSortMode(fParent->IndexOfColumn(this), mode);
    226     else
    227         fSortMode = mode;
    228 }
  • deleted file src/preferences/shortcuts/clv/CLVColumn.h

    diff --git a/src/preferences/shortcuts/clv/CLVColumn.h b/src/preferences/shortcuts/clv/CLVColumn.h
    deleted file mode 100644
    index 2b77288..0000000
    + -  
    1 /*
    2  * Copyright 1999-2009 Jeremy Friesner
    3  * Copyright 2009-2014 Haiku, Inc. All rights reserved.
    4  * Distributed under the terms of the MIT License.
    5  *
    6  * Authors:
    7  *      Jeremy Friesner
    8  *      John Scipione, jscipione@gmail.com
    9  */
    10 #ifndef CLV_COLUMN_H
    11 #define CLV_COLUMN_H
    12 
    13 
    14 #include <support/SupportDefs.h>
    15 #include <interface/PopUpMenu.h>
    16 
    17 
    18 // flags
    19 enum {
    20     CLV_SORT_KEYABLE =          0x00000001,
    21         // Can be used as the sorting key
    22     CLV_NOT_MOVABLE =           0x00000002,
    23         // Column can't be moved by user
    24     CLV_NOT_RESIZABLE =         0x00000004,
    25         // Column can't be resized by user
    26     CLV_LOCK_AT_BEGINNING =     0x00000008,
    27         // Movable columns may not be placed or moved by the user
    28         // into a position before this one
    29     CLV_LOCK_AT_END =           0x00000010,
    30         // Movable columns may not be placed or moved by the user
    31         // into a position after this one
    32     CLV_HIDDEN =                0x00000020,
    33         // This column is hidden initially
    34     CLV_MERGE_WITH_RIGHT =      0x00000040,
    35         // Merge this column label with the one that follows it.
    36     CLV_LOCK_WITH_RIGHT =       0x00000080,
    37         // Lock this column to the one that follows it such that
    38         // if the column to the right is moved by the user, this
    39         // one will move with it and vice versa
    40     CLV_EXPANDER =              0x00000100,
    41         // Column contains an expander. You may only use one
    42         // expander in a ColumnListView, and an expander may not be
    43         // added to a non-hierarchal ColumnListView.  It may not
    44         // have a label.  Its width is automatically set to 20.0.
    45         // The only flags that affect it are CLV_NOT_MOVABLE,
    46         // CLV_LOCK_AT_BEGINNING, CLV_NOT_SHOWN and
    47         // CLV_LOCK_WITH_RIGHT.  The others are set for you:
    48         // CLV_NOT_RESIZABLE | CLV_MERGE_WITH_RIGHT
    49     CLV_PUSH_PASS =             0x00000200
    50         // Causes this column, if pushed by an expander to the
    51         // left, to pass that push on and also push the next
    52         // column to the right.
    53 };
    54 
    55 enum CLVSortMode {
    56     SORT_MODE_ASCENDING,
    57     SORT_MODE_DESCENDING,
    58     SORT_MODE_NONE
    59 };
    60 
    61 
    62 class ColumnListView;
    63 class CLVColumn;
    64 class CLVListItem;
    65 
    66 
    67 class CLVColumn {
    68 public:
    69                                 CLVColumn(const char* label,
    70                                     BPopUpMenu* popup = NULL,
    71                                     float width = 20.0, uint32 flags = 0L,
    72                                     float min_width = 20.0);
    73     virtual                     ~CLVColumn();
    74 
    75     // Archival stuff
    76     /* Not implemented yet
    77                                 CLVColumn(BMessage* archive);
    78                                 static CLVColumn* Instantiate(BMessage* data);
    79     virtual status_t            Archive(BMessage* data, bool deep = true) const;
    80     */
    81 
    82     // Functions
    83             float               Width() const;
    84     virtual void                SetWidth(float width);
    85             // Can be overridden to detect changes to the column width
    86             // however since you are probably overriding ColumnListView
    87             // and dealing with an array of columns anyway, it is
    88             // probably more useful to override
    89             // ColumnListView::ColumnWidthChanged to detect changes to
    90             // column widths
    91             uint32              Flags() const;
    92             bool                IsShown() const;
    93             void                SetShown(bool show);
    94             CLVSortMode         SortMode() const;
    95             void                SetSortMode(CLVSortMode mode);
    96             const char*         GetLabel() const { return fLabel; }
    97             BPopUpMenu*         GetPopup() { return fPopup; }
    98 
    99 private:
    100         friend class ColumnListView;
    101         friend class CLVColumnLabelView;
    102         friend class CLVListItem;
    103 
    104             const char*         fLabel;
    105             float               fWidth;
    106             float               fMinWidth;
    107             float               fColumnBegin;
    108             float               fColumnEnd;
    109             uint32              fFlags;
    110             bool                fPushedByExpander;
    111             CLVSortMode         fSortMode;
    112             ColumnListView*     fParent;
    113             BPopUpMenu*         fPopup;
    114                 // added by jaf
    115 };
    116 
    117 
    118 #endif  // CLV_COLUMN_H
  • deleted file src/preferences/shortcuts/clv/CLVColumnLabelView.cpp

    diff --git a/src/preferences/shortcuts/clv/CLVColumnLabelView.cpp b/src/preferences/shortcuts/clv/CLVColumnLabelView.cpp
    deleted file mode 100644
    index 3567bce..0000000
    + -  
    1 /*
    2  * Copyright 1999-2009 Jeremy Friesner
    3  * Copyright 2009-2014 Haiku, Inc. All rights reserved.
    4  * Distributed under the terms of the MIT License.
    5  *
    6  * Authors:
    7  *      Jeremy Friesner
    8  *      John Scipione, jscipione@gmail.com
    9  */
    10 
    11 
    12 #define CLVColumnLabelView_CPP
    13 
    14 #include "CLVColumnLabelView.h"
    15 #include "ColumnListView.h"
    16 #include "CLVColumn.h"
    17 #include "MouseWatcher.h"
    18 
    19 
    20 CLVColumnLabelView::CLVColumnLabelView(BRect frame, ColumnListView* parent,
    21     const BFont* font)
    22     :
    23     BView(frame, NULL, B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP,
    24         B_WILL_DRAW | B_FRAME_EVENTS),
    25     fDragGroupsList(10)
    26 {
    27     SetFont(font);
    28     SetViewColor(BeBackgroundGrey);
    29     SetLowColor(BeBackgroundGrey);
    30     SetHighColor(Black);
    31     fParent = parent;
    32     fDisplayList = &fParent->fColumnDisplayList;
    33     fColumnClicked = NULL;
    34     fColumnDragging = false;
    35     fColumnResizing = false;
    36     font_height fontAttributes;
    37     font->GetHeight(&fontAttributes);
    38     fFontAscent = ceil(fontAttributes.ascent);
    39 }
    40 
    41 
    42 CLVColumnLabelView::~CLVColumnLabelView()
    43 {
    44     int32 groupCount = fDragGroupsList.CountItems();
    45     for (int32 i = 0; i < groupCount; i++)
    46         fDragGroupsList.RemoveItem(int32(0));
    47 }
    48 
    49 
    50 void
    51 CLVColumnLabelView::Draw(BRect updateRect)
    52 {
    53     BRegion clippingRegion;
    54     GetClippingRegion(&clippingRegion);
    55     BRect bounds = Bounds();
    56 
    57     // draw each column label in turn
    58     float columnBegin = 0.0;
    59     float columnEnd = -1.0;
    60     bool shouldMergeWithLeft = false;
    61     int32 columnCount = fDisplayList->CountItems();
    62     BPoint startingPoint;
    63     BPoint stoppingPoint;
    64     for (int32 i = 0; i < columnCount; i++) {
    65         CLVColumn* column = (CLVColumn*)fDisplayList->ItemAt(i);
    66         if (column->IsShown()) {
    67             // figure out where this column is
    68             columnBegin = column->fColumnBegin;
    69             columnEnd = column->fColumnEnd;
    70             // start by figuring out if this column will merge
    71             // with a shown column to the right
    72             bool shouldMergeWithRight = false;
    73             if ((column->fFlags & CLV_MERGE_WITH_RIGHT) != 0) {
    74                 for (int32 j = i + 1; j < columnCount; j++) {
    75                     CLVColumn* nextColumn = (CLVColumn*)fDisplayList->ItemAt(j);
    76                     if (nextColumn->IsShown()) {
    77                         // next column is shown
    78                         shouldMergeWithRight = true;
    79                         break;
    80                     } else if ((nextColumn->fFlags & CLV_MERGE_WITH_RIGHT)
    81                             == 0) {
    82                         // next column is not shown and doesn't
    83                         // pass on the merge
    84                         break;
    85                     }
    86                 }
    87             }
    88 
    89             if (clippingRegion.Intersects(BRect(columnBegin,
    90                     bounds.top, columnEnd, bounds.bottom))) {
    91                 // need to draw this column
    92                 BeginLineArray(4);
    93 
    94                 // top line
    95                 startingPoint.Set(columnBegin, bounds.top);
    96                 stoppingPoint.Set(columnEnd - 1.0, bounds.top);
    97                 if (shouldMergeWithRight && !(column == fColumnClicked
    98                     && fColumnResizing)) {
    99                     stoppingPoint.x = columnEnd;
    100                 }
    101                 AddLine(startingPoint, stoppingPoint, BeHighlight);
    102 
    103                 // left line
    104                 if (!shouldMergeWithLeft) {
    105                     AddLine(BPoint(columnBegin, bounds.top + 1.0),
    106                         BPoint(columnBegin, bounds.bottom), BeHighlight);
    107                 }
    108 
    109                 // bottom line
    110                 startingPoint.Set(columnBegin + 1.0, bounds.bottom);
    111                 if (shouldMergeWithLeft)
    112                     startingPoint.x = columnBegin;
    113 
    114                 stoppingPoint.Set(columnEnd - 1.0, bounds.bottom);
    115                 if (shouldMergeWithRight && !(column == fColumnClicked
    116                     && fColumnResizing)) {
    117                     stoppingPoint.x = columnEnd;
    118                 }
    119                 AddLine(startingPoint, stoppingPoint, BeShadow);
    120 
    121                 // right line
    122                 if (column == fColumnClicked && fColumnResizing) {
    123                     AddLine(BPoint(columnEnd, bounds.top),
    124                     BPoint(columnEnd, bounds.bottom), BeFocusBlue);
    125                 } else if (!shouldMergeWithRight) {
    126                     AddLine(BPoint(columnEnd, bounds.top),
    127                         BPoint(columnEnd, bounds.bottom), BeShadow);
    128                 }
    129                 EndLineArray();
    130 
    131                 // add the label
    132                 if (column->fLabel != NULL) {
    133                     // limit the clipping region to the interior of the box
    134                     BRegion textRegion;
    135                     textRegion.Include(BRect(columnBegin + 1.0,
    136                         bounds.top + 1.0, columnEnd - 1.0,
    137                         bounds.bottom - 1.0));
    138                     ConstrainClippingRegion(&textRegion);
    139 
    140                     // draw the label
    141                     if (column == fColumnClicked && !fColumnResizing)
    142                         SetHighColor(BeFocusBlue);
    143 
    144                     SetDrawingMode(B_OP_OVER);
    145                     DrawString(column->fLabel,
    146                         BPoint(columnBegin + 9.0,
    147                             bounds.top + 2.0 + fFontAscent));
    148                     SetDrawingMode(B_OP_COPY);
    149 
    150                     // underline if this is a selected sort column
    151                     if (fParent->fSortKeyList.HasItem(column)
    152                         && column->fSortMode != SORT_MODE_NONE) {
    153                         float Width = StringWidth(column->fLabel);
    154                         StrokeLine(BPoint(columnBegin + 8.0,
    155                             bounds.top + 2.0 + fFontAscent + 2.0),
    156                             BPoint(columnBegin + 8.0 + Width,
    157                                 bounds.top + 2.0 + fFontAscent + 2.0));
    158                     }
    159                     if (column == fColumnClicked && !fColumnResizing)
    160                         SetHighColor(Black);
    161 
    162                     // restore the clipping region
    163                     ConstrainClippingRegion(NULL);
    164                 }
    165             }
    166 
    167             // set shouldMergeWithLeft flag for the next column to
    168             // the appropriate state
    169             shouldMergeWithLeft = shouldMergeWithRight;
    170         }
    171     }
    172 
    173     // add highlight and shadow to the region after the columns if necessary
    174     if (columnEnd < bounds.right) {
    175         columnBegin = columnEnd + 1.0;
    176 
    177         if (clippingRegion.Intersects(BRect(columnEnd + 1.0,
    178                 bounds.top, bounds.right, bounds.bottom))) {
    179             BeginLineArray(3);
    180 
    181             // top line
    182             AddLine(BPoint(columnBegin, bounds.top),
    183                 BPoint(bounds.right, bounds.top), BeHighlight);
    184 
    185             // left line
    186             AddLine(BPoint(columnBegin, bounds.top + 1.0),
    187                 BPoint(columnBegin, bounds.bottom), BeHighlight);
    188 
    189             // bottom line
    190             startingPoint.Set(columnBegin + 1.0, bounds.bottom);
    191             if (shouldMergeWithLeft)
    192                 startingPoint.x = columnBegin;
    193 
    194             stoppingPoint.Set(bounds.right, bounds.bottom);
    195             AddLine(startingPoint, stoppingPoint, BeShadow);
    196             EndLineArray();
    197         }
    198     }
    199 
    200     // draw the dragging box if necessary
    201     if (fColumnClicked && fColumnDragging) {
    202         float dragOutlineLeft = fPreviousMousePosition.x
    203             - fDragBoxMouseHoldOffset;
    204         float groupBegin = ((CLVDragGroup*)fDragGroupsList.ItemAt(
    205             fDragGroupIndex))->groupBeginIndex;
    206         if (dragOutlineLeft < groupBegin && fSnapGroupBeforeIndex == -1)
    207             dragOutlineLeft = groupBegin;
    208 
    209         if (dragOutlineLeft > groupBegin && fSnapGroupAfterIndex == -1)
    210             dragOutlineLeft = groupBegin;
    211 
    212         float DragOutlineRight = dragOutlineLeft + fDragBoxWidth;
    213 
    214         BeginLineArray(4);
    215         AddLine(BPoint(dragOutlineLeft, bounds.top),
    216             BPoint(DragOutlineRight, bounds.top), BeFocusBlue);
    217         AddLine(BPoint(dragOutlineLeft, bounds.bottom),
    218             BPoint(DragOutlineRight, bounds.bottom), BeFocusBlue);
    219         AddLine(BPoint(dragOutlineLeft, bounds.top + 1.0),
    220             BPoint(dragOutlineLeft, bounds.bottom - 1.0), BeFocusBlue);
    221         AddLine(BPoint(DragOutlineRight, bounds.top + 1.0),
    222             BPoint(DragOutlineRight, bounds.bottom - 1.0), BeFocusBlue);
    223         EndLineArray();
    224 
    225         fPreviousDragOutlineLeft = dragOutlineLeft;
    226         fPreviousDragOutlineRight = DragOutlineRight;
    227     }
    228 }
    229 
    230 
    231 void
    232 CLVColumnLabelView::MouseDown(BPoint where)
    233 {
    234     // pay attention only to primary mouse button
    235     bool shouldWatchMouse = false;
    236     BPoint mousePosition;
    237     uint32 buttons;
    238     GetMouse(&mousePosition, &buttons);
    239     if (buttons == B_PRIMARY_MOUSE_BUTTON) {
    240         BRect bounds = Bounds();
    241 
    242         // Make sure no other column was already clicked.
    243         // If so, just discard the old one and redraw the view.
    244         if (fColumnClicked != NULL) {
    245             Invalidate();
    246             fColumnClicked = NULL;
    247         }
    248 
    249         // find the column that the user clicked, if any
    250         bool didGrabResizeTab = false;
    251         int32 columnCount = fDisplayList->CountItems();
    252         int32 i;
    253         CLVColumn* column = NULL;
    254         for (i = 0; i < columnCount; i++) {
    255             column = (CLVColumn*)fDisplayList->ItemAt(i);
    256             if (column->IsShown()) {
    257                 float columnBegin = column->fColumnBegin;
    258                 float columnEnd = column->fColumnEnd;
    259                 if ((where.x >= columnBegin && where.x <= columnEnd)
    260                     || ((i == columnCount - 1) && (where.x >= columnBegin))) {
    261                     // anything after the rightmost column can drag... jaf
    262                     const float resizeTolerance = 5.0f;
    263                     // jaf is too clumsy to click on a 2 pixel space.  :)
    264 
    265                     // user clicked in this column
    266                     if (where.x <= columnBegin + resizeTolerance) {
    267                         // user clicked the resize tab preceding this column
    268                         for (i--; i >= 0; i--) {
    269                             column = (CLVColumn*)fDisplayList->ItemAt(i);
    270                             if (column->IsShown()) {
    271                                 didGrabResizeTab = true;
    272                                 break;
    273                             }
    274                         }
    275                     } else if (where.x >= columnEnd-resizeTolerance) {
    276                         // user clicked the resize tab for (after) this column
    277                         didGrabResizeTab = true;
    278                     } else {
    279                         // user clicked in this column
    280                         fColumnClicked = (CLVColumn*)fDisplayList->ItemAt(i);
    281                         fColumnResizing = false;
    282                         fPreviousMousePosition = where;
    283                         fMouseClickedPosition = where;
    284                         fColumnDragging = false;
    285                         SetSnapMinMax();
    286                         fDragBoxMouseHoldOffset = where.x
    287                             - ((CLVDragGroup*)fDragGroupsList.ItemAt(
    288                                 fDragGroupIndex))->groupBeginIndex;
    289 
    290                             Invalidate(BRect(columnBegin + 1.0,
    291                                 bounds.top + 1.0, columnEnd - 1.0,
    292                                 bounds.bottom - 1.0));
    293 
    294                         // start watching the mouse
    295                         shouldWatchMouse = true;
    296                     }
    297                     break;
    298                 }
    299             }
    300         }
    301 
    302         if (didGrabResizeTab) {
    303             // user grabbed a resize tab, check to see if
    304             // resizing this column is allowed
    305             if ((column->fFlags & CLV_NOT_RESIZABLE) == 0) {
    306                 fColumnClicked = (CLVColumn*)fDisplayList->ItemAt(i);
    307                 fColumnResizing = true;
    308                 fPreviousMousePosition = where;
    309                 fMouseClickedPosition = where;
    310                 fColumnDragging = false;
    311                 fResizeMouseHoldOffset = where.x - fColumnClicked->fColumnEnd;
    312                 Invalidate(BRect(fColumnClicked->fColumnEnd, bounds.top,
    313                     column->fColumnEnd, bounds.bottom));
    314 
    315                 // start watching the mouse
    316                 shouldWatchMouse = true;
    317             }
    318         }
    319     }
    320 
    321     if (shouldWatchMouse) {
    322         thread_id MouseWatcherThread = StartMouseWatcher(this);
    323         if (MouseWatcherThread == B_NO_MORE_THREADS
    324             || MouseWatcherThread == B_NO_MEMORY) {
    325             fColumnClicked = NULL;
    326         }
    327     }
    328 }
    329 
    330 
    331 void
    332 CLVColumnLabelView::MessageReceived(BMessage* message)
    333 {
    334     if (message->what != MW_MOUSE_MOVED && message->what != MW_MOUSE_DOWN
    335         && message->what != MW_MOUSE_UP) {
    336         BView::MessageReceived(message);
    337     } else if (fColumnClicked != NULL) {
    338         BPoint mousePosition;
    339         message->FindPoint("where", &mousePosition);
    340         uint32 buttons;
    341         message->FindInt32("buttons", (int32*)&buttons);
    342         uint32 modifiers;
    343         message->FindInt32("modifiers", (int32*)&modifiers);
    344         BRect bounds;
    345         bounds = Bounds();
    346         uint32 columnFlags = fColumnClicked->Flags();
    347         if (buttons == B_PRIMARY_MOUSE_BUTTON) {
    348             // mouse is still held down
    349             if (!fColumnResizing) {
    350                 // user is clicking or dragging
    351                 if ((mousePosition.x < fMouseClickedPosition.x - 2.0
    352                         || mousePosition.x > fMouseClickedPosition.x + 2.0)
    353                     && !fColumnDragging) {
    354                     // user is initiating a drag
    355                     if ((fDragGroup->flags & CLV_NOT_MOVABLE) != 0) {
    356                         // not allowed to drag this column - terminate the click
    357                         Invalidate(BRect(fColumnClicked->fColumnBegin,
    358                             bounds.top, fColumnClicked->fColumnEnd,
    359                             bounds.bottom));
    360                         fColumnClicked = NULL;
    361                     } else {
    362                         // actually initiate a drag
    363                         fColumnDragging = true;
    364                         fPreviousDragOutlineLeft = -1.0;
    365                         fPreviousDragOutlineRight = -1.0;
    366                     }
    367                 }
    368 
    369                 // now deal with dragging
    370                 if (fColumnDragging) {
    371                     // user is dragging
    372                     if (mousePosition.x < fPreviousMousePosition.x
    373                         || mousePosition.x > fPreviousMousePosition.x) {
    374                         // mouse moved since I last checked
    375                         bounds = Bounds();
    376 
    377                         bool hasColumnSnapped;
    378                         do {
    379                             // live dragging of columns
    380                             hasColumnSnapped = false;
    381                             float columnsUpdateLeft = 0;
    382                             float columnsUpdateRight = 0;
    383                             float MainViewUpdateLeft = 0;
    384                             float MainViewUpdateRight = 0;
    385                             CLVColumn* lastSwapColumn = NULL;
    386                             if (fSnapMin != -1.0
    387                                 && mousePosition.x < fSnapMin) {
    388                                 // shift the group left
    389                                 columnsUpdateLeft
    390                                     = fShownGroupBefore->groupBeginIndex;
    391                                 columnsUpdateRight = fDragGroup->groupEndIndex;
    392                                 MainViewUpdateLeft = columnsUpdateLeft;
    393                                 MainViewUpdateRight = columnsUpdateRight;
    394                                 lastSwapColumn
    395                                     = fShownGroupBefore->lastColumnShown;
    396                                 if ((fDragGroup->lastColumnShown->fFlags
    397                                         & CLV_MERGE_WITH_RIGHT) != 0) {
    398                                     columnsUpdateRight += 1.0;
    399                                 } else if ((fShownGroupBefore->
    400                                     lastColumnShown->fFlags
    401                                         & CLV_MERGE_WITH_RIGHT) != 0) {
    402                                     columnsUpdateRight += 1.0;
    403                                 }
    404 
    405                                 ShiftDragGroup(fSnapGroupBeforeIndex);
    406                                 hasColumnSnapped = true;
    407                             }
    408 
    409                             if (fSnapMax != -1.0
    410                                 && mousePosition.x > fSnapMax) {
    411                                 // shift the group right
    412                                 columnsUpdateLeft = fDragGroup->groupBeginIndex;
    413                                 columnsUpdateRight
    414                                     = fShownGroupAfter->groupEndIndex;
    415                                 MainViewUpdateLeft = columnsUpdateLeft;
    416                                 MainViewUpdateRight = columnsUpdateRight;
    417                                 lastSwapColumn = fDragGroup->lastColumnShown;
    418                                 if ((fDragGroup->lastColumnShown->fFlags
    419                                         & CLV_MERGE_WITH_RIGHT) != 0) {
    420                                     columnsUpdateRight += 1.0;
    421                                 } else if ((fShownGroupAfter
    422                                     ->lastColumnShown->fFlags
    423                                         & CLV_MERGE_WITH_RIGHT) != 0) {
    424                                     columnsUpdateRight += 1.0;
    425                                 }
    426                                 ShiftDragGroup(fSnapGroupAfterIndex + 1);
    427                                 hasColumnSnapped = true;
    428                             }
    429 
    430                             if (hasColumnSnapped) {
    431                                 // redraw the snapped column labels
    432                                 Invalidate(BRect(columnsUpdateLeft,
    433                                     bounds.top, columnsUpdateRight,
    434                                     bounds.bottom));
    435                                 BRect mainBounds = fParent->Bounds();
    436                                 // modify MainViewUpdateRight if more
    437                                 // columns are pushed by expanders
    438                                 if ((lastSwapColumn->fFlags & CLV_EXPANDER) != 0
    439                                         || (lastSwapColumn->fPushedByExpander
    440                                     && ((lastSwapColumn->fFlags & CLV_PUSH_PASS)
    441                                         != 0))) {
    442                                     int32 columnCount
    443                                         = fDisplayList->CountItems();
    444                                     for (int32 j = fDisplayList->IndexOf(
    445                                             lastSwapColumn) + 1;
    446                                         j < columnCount; j++) {
    447                                         CLVColumn* column =
    448                                             (CLVColumn*)fDisplayList->ItemAt(j);
    449                                         if (column->IsShown()) {
    450                                             if (column->fPushedByExpander)
    451                                                 MainViewUpdateRight
    452                                                     = column->fColumnEnd;
    453                                             else
    454                                                 break;
    455                                         }
    456                                     }
    457                                 }
    458                                 fParent->Invalidate(BRect(MainViewUpdateLeft,
    459                                     mainBounds.top, MainViewUpdateRight,
    460                                     mainBounds.bottom));
    461                             }
    462                         } while (hasColumnSnapped);
    463                         // erase and redraw the drag rectangle but not the
    464                         // interior to avoid label flicker
    465                         float min = fPreviousDragOutlineLeft;
    466                         float max = fPreviousDragOutlineRight;
    467                         float min2 = mousePosition.x - fDragBoxMouseHoldOffset;
    468                         float groupBegin = ((CLVDragGroup*)fDragGroupsList.ItemAt(
    469                             fDragGroupIndex))->groupBeginIndex;
    470                         if (min2 < groupBegin && fSnapGroupBeforeIndex == -1)
    471                             min2 = groupBegin;
    472 
    473                         if (min2 > groupBegin && fSnapGroupAfterIndex == -1)
    474                             min2 = groupBegin;
    475 
    476                         float max2 = min2 + fDragBoxWidth;
    477                         float Temp;
    478                         if (min2 < min || min == -1.0) {
    479                             Temp = min2;
    480                             min2 = min;
    481                             min = Temp;
    482                         }
    483 
    484                         if (max2 > max || max == -1.0) {
    485                             Temp = max2;
    486                             max2 = max;
    487                             max = Temp;
    488                         }
    489                         Invalidate(BRect(min, bounds.top + 1.0, min,
    490                             bounds.bottom - 1.0));
    491                         if (min2 != -1.0) {
    492                             Invalidate(BRect(min2, bounds.top + 1.0, min2,
    493                                 bounds.bottom - 1.0));
    494                         }
    495                         Invalidate(BRect(max, bounds.top + 1.0, max,
    496                             bounds.bottom - 1.0));
    497                         if (max2 != -1.0) {
    498                             Invalidate(BRect(max2, bounds.top + 1.0, max2,
    499                                 bounds.bottom - 1.0));
    500                         }
    501                         Invalidate(BRect(min, bounds.top, max, bounds.top));
    502                         Invalidate(BRect(min, bounds.bottom, max,
    503                             bounds.bottom));
    504                     }
    505                 }
    506             } else {
    507                 // user is resizing the column
    508                 if (mousePosition.x < fPreviousMousePosition.x
    509                     || mousePosition.x > fPreviousMousePosition.x) {
    510                     float newWidth = mousePosition.x - fResizeMouseHoldOffset
    511                         - fColumnClicked->fColumnBegin;
    512                     if (newWidth < fColumnClicked->fMinWidth)
    513                         newWidth = fColumnClicked->fMinWidth;
    514 
    515                     if (newWidth != fColumnClicked->fWidth) {
    516                         fColumnClicked->SetWidth(newWidth);
    517                         fParent->ColumnWidthChanged(fParent->IndexOfColumn(
    518                             fColumnClicked), newWidth);
    519                     }
    520                 }
    521             }
    522         } else if (buttons == 0) {
    523             // mouse button was released
    524             if (!fColumnDragging && !fColumnResizing) {
    525                 // column was clicked
    526                 if ((columnFlags & CLV_SORT_KEYABLE) != 0) {
    527                     // column is a "sortable" column
    528                     if ((modifiers & B_SHIFT_KEY) == 0) {
    529                         // user wants to select it as the main sorting column
    530                         if (fParent->fSortKeyList.ItemAt(0) == fColumnClicked) {
    531                             // column was already selected; switch sort modes
    532                             fParent->ReverseSortMode(
    533                                 fParent->fColumnList.IndexOf(fColumnClicked));
    534                         } else {
    535                             //The user selected this column for sorting
    536                             fParent->SetSortKey(
    537                                 fParent->fColumnList.IndexOf(fColumnClicked));
    538                         }
    539                     } else {
    540                         // user wants to add it as a secondary sorting column
    541                         if (fParent->fSortKeyList.HasItem(fColumnClicked)) {
    542                             // column was already selected; switch sort modes
    543                             fParent->ReverseSortMode(
    544                                 fParent->fColumnList.IndexOf(fColumnClicked));
    545                         } else {
    546                             // user selected this column for sorting
    547                             fParent->AddSortKey(
    548                                 fParent->fColumnList.IndexOf(fColumnClicked));
    549                         }
    550                     }
    551                 }
    552             } else if (fColumnDragging) {
    553                 // column was dragging; erase the drag box but not
    554                 // the interior to avoid label flicker
    555                 Invalidate(BRect(fPreviousDragOutlineLeft, bounds.top + 1.0,
    556                     fPreviousDragOutlineLeft, bounds.bottom - 1.0));
    557                 Invalidate(BRect(fPreviousDragOutlineRight, bounds.top + 1.0,
    558                     fPreviousDragOutlineRight, bounds.bottom - 1.0));
    559                 Invalidate(BRect(fPreviousDragOutlineLeft, bounds.top,
    560                     fPreviousDragOutlineRight, bounds.top));
    561                 Invalidate(BRect(fPreviousDragOutlineLeft, bounds.bottom,
    562                     fPreviousDragOutlineRight, bounds.bottom));
    563             } else {
    564                 // column was resizing; erase the drag tab
    565                 Invalidate(BRect(fColumnClicked->fColumnEnd,
    566                     bounds.top, fColumnClicked->fColumnEnd,
    567                     bounds.bottom));
    568             }
    569 
    570             // unhighlight the label and forget the column
    571             Invalidate(BRect(fColumnClicked->fColumnBegin + 1.0,
    572                 bounds.top + 1.0, fColumnClicked->fColumnEnd - 1.0,
    573                 bounds.bottom - 1.0));
    574             fColumnClicked = NULL;
    575             fColumnDragging = false;
    576             fColumnResizing = false;
    577         } else {
    578             // unused button combination, unhighlight the label and
    579             // forget the column
    580             Invalidate(BRect(fColumnClicked->fColumnBegin + 1.0,
    581                 bounds.top + 1.0, fColumnClicked->fColumnEnd - 1.0,
    582                 bounds.bottom - 1.0));
    583             fColumnClicked = NULL;
    584             fColumnDragging = false;
    585             fColumnResizing = false;
    586         }
    587 
    588         fPreviousMousePosition = mousePosition;
    589     }
    590 }
    591 
    592 
    593 // Shift the drag group into a new position
    594 void
    595 CLVColumnLabelView::ShiftDragGroup(int32 newPosition)
    596 {
    597     int32 groupCount = fDragGroupsList.CountItems();
    598     CLVDragGroup* group;
    599     BList newDisplayList;
    600 
    601     //Copy the groups up to the new position
    602     for (int32 i = 0; i < newPosition; i++) {
    603         if (i != fDragGroupIndex) {
    604             group = (CLVDragGroup*)fDragGroupsList.ItemAt(i);
    605             for (int32 j = group->groupStartDisplayListIndex;
    606                     j <= group->groupStopDisplayListIndex; j++) {
    607                 newDisplayList.AddItem(fDisplayList->ItemAt(j));
    608             }
    609         }
    610     }
    611 
    612     // copy the group into the new position
    613     group = (CLVDragGroup*)fDragGroupsList.ItemAt(fDragGroupIndex);
    614     for (int32 j = group->groupStartDisplayListIndex;
    615             j <= group->groupStopDisplayListIndex; j++) {
    616         newDisplayList.AddItem(fDisplayList->ItemAt(j));
    617     }
    618 
    619     // copy the rest of the groups, but skip the dragging group
    620     for (int32 i = newPosition; i < groupCount; i++) {
    621         if (i != fDragGroupIndex) {
    622             group = (CLVDragGroup*)fDragGroupsList.ItemAt(i);
    623             for (int32 j = group->groupStartDisplayListIndex;
    624                     j <= group->groupStopDisplayListIndex; j++) {
    625                 newDisplayList.AddItem(fDisplayList->ItemAt(j));
    626             }
    627         }
    628     }
    629 
    630     // set the new order
    631     *fDisplayList = newDisplayList;
    632 
    633     // update columns and drag groups
    634     fParent->ShiftDragGroup();
    635     UpdateDragGroups();
    636     SetSnapMinMax();
    637 
    638     // inform the program that the display order changed
    639     int32* newOrder = fParent->DisplayOrder();
    640     fParent->DisplayOrderChanged(newOrder);
    641     delete[] newOrder;
    642 }
    643 
    644 
    645 // Make a copy of the DragGroups list, use it to store
    646 // the CLVDragGroup's for recycling.
    647 void
    648 CLVColumnLabelView::UpdateDragGroups()
    649 {
    650     BList tempList(fDragGroupsList);
    651     fDragGroupsList.MakeEmpty();
    652     int32 columnCount = fDisplayList->CountItems();
    653     bool shouldContinueGroup = false;
    654     CLVDragGroup* CurrentGroup = NULL;
    655 
    656     for (int32 i = 0; i < columnCount; i++) {
    657         CLVColumn* CurrentColumn = (CLVColumn*)fDisplayList->ItemAt(i);
    658         if (!shouldContinueGroup) {
    659             // recycle or obtain a new CLVDragGroup
    660             CurrentGroup = (CLVDragGroup*)tempList.RemoveItem(int32(0));
    661             if (CurrentGroup == NULL)
    662                 CurrentGroup = new CLVDragGroup;
    663 
    664             // add the CLVDragGroup to the DragGroups list
    665             fDragGroupsList.AddItem(CurrentGroup);
    666             // set up the new DragGroup
    667             CurrentGroup->groupStartDisplayListIndex = i;
    668             CurrentGroup->groupStopDisplayListIndex = i;
    669             CurrentGroup->flags = 0;
    670 
    671             if (CurrentColumn->IsShown()) {
    672                 CurrentGroup->groupBeginIndex = CurrentColumn->fColumnBegin;
    673                 CurrentGroup->groupEndIndex = CurrentColumn->fColumnEnd;
    674                 CurrentGroup->lastColumnShown = CurrentColumn;
    675                 CurrentGroup->isShown = true;
    676                 if (CurrentColumn->fFlags & CLV_LOCK_AT_BEGINNING)
    677                     CurrentGroup->isAllLockBeginning = true;
    678                 else
    679                     CurrentGroup->isAllLockBeginning = false;
    680 
    681                 if (CurrentColumn->fFlags & CLV_LOCK_AT_END)
    682                     CurrentGroup->isAllLockEnd = true;
    683                 else
    684                     CurrentGroup->isAllLockEnd = false;
    685             } else {
    686                 CurrentGroup->groupBeginIndex = -1.0;
    687                 CurrentGroup->groupEndIndex = -1.0;
    688                 CurrentGroup->lastColumnShown = NULL;
    689                 CurrentGroup->isShown = false;
    690                 if (CurrentColumn->fFlags & CLV_LOCK_AT_BEGINNING)
    691                     CurrentGroup->isAllLockBeginning = true;
    692                 else
    693                     CurrentGroup->isAllLockBeginning = false;
    694                 if (CurrentColumn->fFlags & CLV_LOCK_AT_END)
    695                     CurrentGroup->isAllLockEnd = true;
    696                 else
    697                     CurrentGroup->isAllLockEnd = false;
    698             }
    699         } else {
    700             // add this column to the current DragGroup
    701             CurrentGroup->groupStopDisplayListIndex = i;
    702             if (CurrentColumn->IsShown()) {
    703                 if (CurrentGroup->groupBeginIndex == -1.0)
    704                     CurrentGroup->groupBeginIndex = CurrentColumn->fColumnBegin;
    705                 CurrentGroup->groupEndIndex = CurrentColumn->fColumnEnd;
    706                 CurrentGroup->lastColumnShown = CurrentColumn;
    707                 CurrentGroup->isShown = true;
    708             }
    709             if ((CurrentColumn->fFlags & CLV_LOCK_AT_BEGINNING) == 0)
    710                 CurrentGroup->isAllLockBeginning = false;
    711             if ((CurrentColumn->fFlags & CLV_LOCK_AT_END) == 0)
    712                 CurrentGroup->isAllLockEnd = false;
    713         }
    714 
    715         CurrentGroup->flags = CurrentColumn->fFlags
    716             & (CLV_NOT_MOVABLE | CLV_LOCK_AT_BEGINNING
    717                 | CLV_LOCK_AT_END);
    718         // see if I should add more columns to this group
    719         if (CurrentColumn->fFlags & CLV_LOCK_WITH_RIGHT)
    720             shouldContinueGroup = true;
    721         else
    722             shouldContinueGroup = false;
    723     }
    724     // if any unused groups remain in tempList, delete them
    725     while ((CurrentGroup = (CLVDragGroup*)tempList.RemoveItem(int32(0)))
    726             != NULL) {
    727         delete CurrentGroup;
    728     }
    729 }
    730 
    731 
    732 // find the column group that the user is dragging and the shown
    733 // group before it
    734 void
    735 CLVColumnLabelView::SetSnapMinMax()
    736 {
    737     int32 groupCount = fDragGroupsList.CountItems();
    738     int32 columnCount;
    739     fDragGroupIndex = -1;
    740     fShownGroupBefore = NULL;
    741     fSnapGroupBeforeIndex = -1;
    742     CLVDragGroup* group;
    743     for (int32 i = 0; i < groupCount; i++) {
    744         group = (CLVDragGroup*)fDragGroupsList.ItemAt(i);
    745         for (columnCount = group->groupStartDisplayListIndex;
    746             columnCount <= group->groupStopDisplayListIndex; columnCount++) {
    747             if (fDisplayList->ItemAt(columnCount) == fColumnClicked) {
    748                 fDragGroupIndex = i;
    749                 fDragGroup = group;
    750                 break;
    751             }
    752         }
    753 
    754         if (fDragGroupIndex != -1)
    755             break;
    756         else if (group->isShown) {
    757             fShownGroupBefore = group;
    758             fSnapGroupBeforeIndex = i;
    759         }
    760     }
    761 
    762     // find the position of shown group after the one that the user is dragging
    763     fShownGroupAfter = NULL;
    764     fSnapGroupAfterIndex = -1;
    765     for (int32 i = fDragGroupIndex + 1; i < groupCount; i++) {
    766         group = (CLVDragGroup*)fDragGroupsList.ItemAt(i);
    767         if (group->isShown) {
    768             fShownGroupAfter = group;
    769             fSnapGroupAfterIndex = i;
    770             break;
    771         }
    772     }
    773 
    774     // see if it can actually snap in the given direction
    775     if (fSnapGroupBeforeIndex != -1) {
    776         if ((fShownGroupBefore->flags & CLV_LOCK_AT_BEGINNING) != 0
    777             && !fDragGroup->isAllLockBeginning) {
    778             fSnapGroupBeforeIndex = -1;
    779         }
    780         if ((fDragGroup->flags & CLV_LOCK_AT_END) != 0
    781             && !fShownGroupBefore->isAllLockEnd) {
    782             fSnapGroupBeforeIndex = -1;
    783         }
    784     }
    785     if (fSnapGroupAfterIndex != -1) {
    786         if (fShownGroupAfter->flags & CLV_LOCK_AT_END
    787             && !fDragGroup->isAllLockEnd) {
    788                 fSnapGroupAfterIndex = -1;
    789         }
    790         if (fDragGroup->flags & CLV_LOCK_AT_BEGINNING
    791             && !fShownGroupAfter->isAllLockBeginning) {
    792                 fSnapGroupAfterIndex = -1;
    793         }
    794     }
    795 
    796     // find the minumum and maximum positions for the group to snap
    797     fSnapMin = -1.0;
    798     fSnapMax = -1.0;
    799     fDragBoxWidth = fDragGroup->groupEndIndex - fDragGroup->groupBeginIndex;
    800     if (fSnapGroupBeforeIndex != -1) {
    801         fSnapMin = fShownGroupBefore->groupBeginIndex + fDragBoxWidth;
    802         if (fSnapMin > fShownGroupBefore->groupEndIndex)
    803             fSnapMin = fShownGroupBefore->groupEndIndex;
    804     }
    805     if (fSnapGroupAfterIndex != -1){
    806         fSnapMax = fShownGroupAfter->groupEndIndex - fDragBoxWidth;
    807         if (fSnapMax < fShownGroupAfter->groupBeginIndex)
    808             fSnapMax = fShownGroupAfter->groupBeginIndex;
    809     }
    810 }
  • deleted file src/preferences/shortcuts/clv/CLVColumnLabelView.h

    diff --git a/src/preferences/shortcuts/clv/CLVColumnLabelView.h b/src/preferences/shortcuts/clv/CLVColumnLabelView.h
    deleted file mode 100644
    index 2adf0f7..0000000
    + -  
    1 /*
    2  * Copyright 1999-2009 Jeremy Friesner
    3  * Copyright 2009-2014 Haiku, Inc. All rights reserved.
    4  * Distributed under the terms of the MIT License.
    5  *
    6  * Authors:
    7  *      Jeremy Friesner
    8  *      John Scipione, jscipione@gmail.com
    9  */
    10 #ifndef CLV_COLUMN_LABEL_VIEW_H
    11 #define CLV_COLUMN_LABEL_VIEW_H
    12 
    13 
    14 #include <support/SupportDefs.h>
    15 #include <InterfaceKit.h>
    16 
    17 
    18 class ColumnListView;
    19 class CLVColumn;
    20 
    21 
    22 struct CLVDragGroup
    23 {
    24     int32 groupStartDisplayListIndex;
    25         // indices in the column display list where this group starts
    26     int32 groupStopDisplayListIndex;
    27         // and finishes
    28     float groupBeginIndex;
    29         // -1.0 if whole group is hidden
    30     float groupEndIndex;
    31         // -1.0 if whole group is hidden
    32     CLVColumn* lastColumnShown;
    33     bool isAllLockBeginning;
    34     bool isAllLockEnd;
    35     bool isShown;
    36         // false if none of the columns in this group are shown
    37     uint32 flags;
    38         // Uses CLV_NOT_MOVABLE, CLV_LOCK_AT_BEGINNING, CLV_LOCK_AT_END
    39 };
    40 
    41 
    42 class CLVColumnLabelView : public BView
    43 {
    44 public:
    45                             CLVColumnLabelView(BRect frame,
    46                                 ColumnListView* parent,
    47                                 const BFont* font);
    48                             ~CLVColumnLabelView();
    49 
    50         // BView overrides
    51             void            Draw(BRect UpdateRect);
    52             void            MouseDown(BPoint Point);
    53             void            MessageReceived(BMessage* message);
    54 
    55 private:
    56         friend class ColumnListView;
    57         friend class CLVColumn;
    58 
    59             void            ShiftDragGroup(int32 newPosition);
    60             void            UpdateDragGroups();
    61             void            SetSnapMinMax();
    62 
    63             float           fFontAscent;
    64             BList*          fDisplayList;
    65 
    66         // column select and drag stuff
    67             CLVColumn*      fColumnClicked;
    68             BPoint          fPreviousMousePosition;
    69             BPoint          fMouseClickedPosition;
    70             bool            fColumnDragging;
    71             bool            fColumnResizing;
    72             BList           fDragGroupsList;
    73         // groups of CLVColumns that must drag together
    74             int32           fDragGroupIndex;
    75         // index into DragGroups of the group being dragged by user
    76             CLVDragGroup*   fDragGroup;
    77             CLVDragGroup*   fShownGroupBefore;
    78             CLVDragGroup*   fShownGroupAfter;
    79             int32           fSnapGroupBeforeIndex;
    80             int32           fSnapGroupAfterIndex;
    81         // index into DragGroups of fShownGroupBefore and
    82         // fShownGroupAfter, if the group the user is dragging is
    83         // allowed to snap there, otherwise -1
    84             float           fDragBoxMouseHoldOffset;
    85             float           fResizeMouseHoldOffset;
    86             float           fDragBoxWidth;
    87         // can include multiple columns; depends on CLV_LOCK_WITH_RIGHT
    88             float           fPreviousDragOutlineLeft;
    89             float           fPreviousDragOutlineRight;
    90             float           fSnapMin;
    91             float           fSnapMax;
    92         // -1.0 indicates the column can't snap in the given direction
    93             ColumnListView* fParent;
    94 };
    95 
    96 
    97 #endif  // CLV_COLUMN_LABEL_VIEW_H
  • deleted file src/preferences/shortcuts/clv/CLVListItem.cpp

    diff --git a/src/preferences/shortcuts/clv/CLVListItem.cpp b/src/preferences/shortcuts/clv/CLVListItem.cpp
    deleted file mode 100644
    index a7bfc67..0000000
    + -  
    1 /*
    2  * Copyright 1999-2009 Jeremy Friesner
    3  * Copyright 2009-2014 Haiku, Inc. All rights reserved.
    4  * Distributed under the terms of the MIT License.
    5  *
    6  * Authors:
    7  *      Jeremy Friesner
    8  *      John Scipione, jscipione@gmail.com
    9  */
    10 
    11 
    12 #define CLVListItem_CPP
    13 
    14 #include <stdio.h>
    15 
    16 #include "CLVListItem.h"
    17 #include "ColumnListView.h"
    18 #include "CLVColumn.h"
    19 #include "PrefilledBitmap.h"
    20 
    21 #include "InterfaceKit.h"
    22 
    23 
    24 CLVListItem::CLVListItem(uint32 level, bool superitem, bool expanded,
    25     float minheight)
    26     :
    27     BListItem(level, expanded),
    28     fExpanderButtonRect(-1.0, -1.0, -1.0, -1.0),
    29     fExpanderColumnRect(-1.0, -1.0, -1.0, -1.0),
    30     fSelectedColumn(-1)
    31 {
    32     fIsSuperItem = superitem;
    33     fOutlineLevel = level;
    34     fMinHeight = minheight;
    35 }
    36 
    37 
    38 CLVListItem::~CLVListItem()
    39 {
    40 }
    41 
    42 
    43 bool
    44 CLVListItem::IsSuperItem() const
    45 {
    46     return fIsSuperItem;
    47 }
    48 
    49 
    50 void
    51 CLVListItem::SetSuperItem(bool superitem)
    52 {
    53     fIsSuperItem = superitem;
    54 }
    55 
    56 
    57 uint32
    58 CLVListItem::OutlineLevel() const
    59 {
    60     return fOutlineLevel;
    61 }
    62 
    63 
    64 void
    65 CLVListItem::SetOutlineLevel(uint32 level)
    66 {
    67     fOutlineLevel = level;
    68 }
    69 
    70 
    71 void
    72 CLVListItem::Pulse(BView* owner)
    73 {
    74 }
    75 
    76 void
    77 CLVListItem::DrawItem(BView* owner, BRect itemRect, bool complete)
    78 {
    79     BList* displayList = &((ColumnListView*)owner)->fColumnDisplayList;
    80     int32 columnCount = displayList->CountItems();
    81     float PushMax = itemRect.right;
    82     CLVColumn* column;
    83     BRect columnRect = itemRect;
    84     float expanderDelta = OutlineLevel() * 20.0;
    85     // figure out what the limit is for expanders pushing other columns
    86     for (int32 i = 0; i < columnCount; i++) {
    87         column = (CLVColumn*)displayList->ItemAt(i);
    88         if((column->fFlags & CLV_EXPANDER) || column->fPushedByExpander)
    89             PushMax = column->fColumnEnd;
    90     }
    91 
    92     BRegion ClippingRegion;
    93     if (!complete)
    94         owner->GetClippingRegion(&ClippingRegion);
    95     else
    96         ClippingRegion.Set(itemRect);
    97 
    98     float LastColumnEnd = -1.0;
    99 
    100     // draw the columns
    101     for (int32 Counter = 0; Counter < columnCount; Counter++) {
    102         column = (CLVColumn*)displayList->ItemAt(Counter);
    103         if(!column->IsShown())
    104             continue;
    105 
    106         columnRect.left = column->fColumnBegin;
    107         columnRect.right = LastColumnEnd = column->fColumnEnd;
    108         float shift = 0.0;
    109         if ((column->fFlags & CLV_EXPANDER) || column->fPushedByExpander)
    110             shift = expanderDelta;
    111 
    112         if (column->fFlags & CLV_EXPANDER) {
    113             columnRect.right += shift;
    114             if(columnRect.right > PushMax)
    115                 columnRect.right = PushMax;
    116 
    117             fExpanderColumnRect = columnRect;
    118             if (ClippingRegion.Intersects(columnRect)) {
    119                 // give the programmer a chance to do his kind of
    120                 // highlighting if the item is selected
    121                 int32 actualIndex
    122                     = ((ColumnListView*)owner)->fColumnList.IndexOf(column);
    123                 DrawItemColumn(owner, columnRect, actualIndex,
    124                     (fSelectedColumn == actualIndex), complete);
    125                 if (fIsSuperItem) {
    126                     // draw the expander, clip manually
    127                     float top
    128                         = ceilf((columnRect.bottom-columnRect.top - 10.0)
    129                             / 2.0);
    130                     float left = column->fColumnEnd + shift - 3.0 - 10.0;
    131                     float rightClip = left + 10.0 - columnRect.right;
    132                     if (rightClip < 0.0)
    133                         rightClip = 0.0;
    134 
    135                     BBitmap* arrow;
    136                     if (IsExpanded())
    137                         arrow = &((ColumnListView*)owner)->fDownArrow;
    138                     else
    139                         arrow = &((ColumnListView*)owner)->fRightArrow;
    140 
    141                     if (left <= columnRect.right) {
    142                         fExpanderButtonRect.Set(left, columnRect.top + top,
    143                             left + 10.0 - rightClip, columnRect.top + top + 10.0);
    144                         owner->SetDrawingMode(B_OP_OVER);
    145                         owner->DrawBitmap(arrow,
    146                             BRect(0.0, 0.0, 10.0 - rightClip, 10.0),
    147                             fExpanderButtonRect);
    148                         owner->SetDrawingMode(B_OP_COPY);
    149                     } else
    150                         fExpanderButtonRect.Set(-1.0, -1.0, -1.0, -1.0);
    151                 }
    152             }
    153         } else {
    154             columnRect.left += shift;
    155             columnRect.right += shift;
    156             if (shift > 0.0 && columnRect.right > PushMax)
    157                 columnRect.right = PushMax;
    158 
    159             if (columnRect.right >= columnRect.left
    160                 && ClippingRegion.Intersects(columnRect))
    161             {
    162                 int32 actualIndex
    163                     = ((ColumnListView*)owner)->fColumnList.IndexOf(column);
    164                 DrawItemColumn(owner, columnRect, actualIndex,
    165                     (fSelectedColumn == actualIndex), complete);
    166             }
    167         }
    168     }
    169 
    170     // fill the area after all the columns (so the select highlight goes
    171     // all the way across)
    172     columnRect.left = LastColumnEnd + 1.0;
    173     columnRect.right = owner->Bounds().right;
    174     if (columnRect.left <= columnRect.right
    175         && ClippingRegion.Intersects(columnRect)) {
    176         DrawItemColumn(owner, columnRect, -1, false, complete);
    177     }
    178 }
    179 
    180 
    181 float
    182 CLVListItem::ExpanderShift(int32 columnIndex, BView* owner)
    183 {
    184     BList* displayList = &((ColumnListView*)owner)->fColumnDisplayList;
    185     CLVColumn* column = (CLVColumn*)displayList->ItemAt(columnIndex);
    186     float expanderDelta = OutlineLevel() * 20.0f;
    187     if (!column->fPushedByExpander)
    188         expanderDelta = 0.0;
    189 
    190     return expanderDelta;
    191 }
    192 
    193 
    194 void
    195 CLVListItem::Update(BView* owner, const BFont* font)
    196 {
    197     BListItem::Update(owner, font);
    198     float itemHeight = Height();
    199     if (itemHeight < fMinHeight)
    200         itemHeight = fMinHeight;
    201 
    202     SetWidth(((ColumnListView*)owner)->fPageWidth);
    203     SetHeight(itemHeight);
    204 }
  • deleted file src/preferences/shortcuts/clv/CLVListItem.h

    diff --git a/src/preferences/shortcuts/clv/CLVListItem.h b/src/preferences/shortcuts/clv/CLVListItem.h
    deleted file mode 100644
    index f2d0db4..0000000
    + -  
    1 /*
    2  * Copyright 1999-2009 Jeremy Friesner
    3  * Copyright 2009-2014 Haiku, Inc. All rights reserved.
    4  * Distributed under the terms of the MIT License.
    5  *
    6  * Authors:
    7  *      Jeremy Friesner
    8  *      John Scipione, jscipione@gmail.com
    9  */
    10 #ifndef CLV_LIST_ITEM_H
    11 #define CLV_LIST_ITEM_H
    12 
    13 
    14 #include <interface/ListItem.h>
    15 
    16 
    17 class ColumnListView;
    18 
    19 
    20 class CLVListItem : public BListItem
    21 {
    22 public:
    23                                     CLVListItem(uint32 level = 0,
    24                                         bool superitem = false,
    25                                         bool expanded = false,
    26                                         float minheight = 0.0);
    27     virtual                         ~CLVListItem();
    28 
    29         //Archival stuff
    30         /* Not implemented yet
    31                                     CLVItem(BMessage* archive);
    32     static  CLVItem*                Instantiate(BMessage* data);
    33     virtual status_t                Archive(BMessage* data, bool deep = true)
    34                                         const;
    35         */
    36 
    37     virtual void                    DrawItemColumn(BView* owner,
    38                                         BRect columnRect,
    39                                         int32 columnIndex,
    40                                         bool columnSelected,
    41                                         bool complete) = 0;
    42         // columnIndex (0-N) is based on the order in which the columns
    43         // were added to the ColumnListView, not the display order.
    44         // An index of -1 indicates that the program needs to draw a blank
    45         // area beyond the last column. The main purpose is to allow the
    46         // highlighting bar to continue all the way to the end of the'
    47         // ColumnListView, even after the end of the last column.
    48 
    49     virtual void                    DrawItem(BView* owner, BRect itemRect,
    50                                         bool complete);
    51         // In general, you don't need or want to override DrawItem().
    52             float                   ExpanderShift(int32 columnIndex,
    53                                         BView* owner);
    54     virtual void                    Update(BView* owner, const BFont* font);
    55             bool                    IsSuperItem() const;
    56             void                    SetSuperItem(bool superitem);
    57             uint32                  OutlineLevel() const;
    58             void                    SetOutlineLevel(uint32 level);
    59 
    60     virtual void                    Pulse(BView* owner);
    61         // Called periodically when this item is selected.
    62 
    63             int32                   GetSelectedColumn() const
    64                                         { return fSelectedColumn; }
    65             void                    SetSelectedColumn(int32 i)
    66                                         { fSelectedColumn = i; }
    67 
    68     private:
    69         friend class ColumnListView;
    70 
    71             bool                    fIsSuperItem;
    72             uint32                  fOutlineLevel;
    73             float                   fMinHeight;
    74             BRect                   fExpanderButtonRect;
    75             BRect                   fExpanderColumnRect;
    76             BList*                  fSortingContextBList;
    77             ColumnListView*         fSortingContextCLV;
    78             int32                   fSelectedColumn;
    79 };
    80 
    81 
    82 #endif  // CLV_LIST_ITEM_H
  • deleted file src/preferences/shortcuts/clv/Colors.h

    diff --git a/src/preferences/shortcuts/clv/Colors.h b/src/preferences/shortcuts/clv/Colors.h
    deleted file mode 100644
    index 276607a..0000000
    + -  
    1 /*
    2  * Copyright 1999-2009 Jeremy Friesner
    3  * Copyright 2009-2014 Haiku, Inc. All rights reserved.
    4  * Distributed under the terms of the MIT License.
    5  *
    6  * Authors:
    7  *      Jeremy Friesner
    8  *      John Scipione, jscipione@gmail.com
    9  */
    10 #ifndef J_COLORS_H
    11 #define J_COLORS_H
    12 
    13 // useful until be gets around to making these sorts of things
    14 // globals akin to be_plain_font, etc.
    15 #include <ColorControl.h>
    16 
    17 // Be standard UI colors
    18 const rgb_color BeBackgroundGrey =      { 216, 216, 216, 255 };
    19 const rgb_color BeInactiveControlGrey = { 240, 240, 240, 255 };
    20 const rgb_color BeFocusBlue =           { 0,   0,   229, 255 };
    21 const rgb_color BeHighlight =           { 255, 255, 255, 255 };
    22 const rgb_color BeShadow =              { 152, 152, 152, 255 };
    23 const rgb_color BeDarkShadow =          { 108, 108, 108, 255 };
    24 const rgb_color BeLightShadow =         { 194, 194, 194, 255 };
    25 const rgb_color BeButtonGrey =          { 232, 232, 232, 255 };
    26 const rgb_color BeInactiveGrey =        { 127, 127, 127, 255 };
    27 const rgb_color BeListSelectGrey =      { 178, 178, 178, 255 };
    28 const rgb_color BeTitleBarYellow =      { 255, 203, 0,   255 };
    29 
    30 // Other colors
    31 const rgb_color Black =                 { 0,   0,   0,   255 };
    32 const rgb_color White =                 { 255, 255, 255, 255 };
    33 const rgb_color Red =                   { 255, 0,   0,   255 };
    34 const rgb_color Green =                 { 0,   167, 0,   255 };
    35 const rgb_color LightGreen =            { 90,  240, 90,  255 };
    36 const rgb_color Blue =                  { 49,  61,  225, 255 };
    37 const rgb_color LightBlue =             { 64,  162, 255, 255 };
    38 const rgb_color Purple =                { 144, 64,  221, 255 };
    39 const rgb_color LightPurple =           { 166, 74,  255, 255 };
    40 const rgb_color Lavender =              { 193, 122, 255, 255 };
    41 const rgb_color Yellow =                { 255, 203, 0,   255 };
    42 const rgb_color Orange =                { 255, 163, 0,   255 };
    43 const rgb_color Flesh =                 { 255, 231, 186, 255 };
    44 const rgb_color Tan =                   { 208, 182, 121, 255 };
    45 const rgb_color Brown =                 { 154, 110, 45,  255 };
    46 const rgb_color LightMetallicBlue =     { 143, 166, 240, 255 };
    47 const rgb_color MedMetallicBlue =       { 75,  96,  154, 255 };
    48 const rgb_color DarkMetallicBlue =      { 78,  89,  126, 255 };
    49 
    50 const rgb_color ReallyLightPurple =     { 255, 210, 255, 255 };
    51 const rgb_color LightYellow =           { 255, 255, 210, 255 };
    52 
    53 
    54 #endif  // J_COLORS_H
  • deleted file src/preferences/shortcuts/clv/ColumnListView.cpp

    diff --git a/src/preferences/shortcuts/clv/ColumnListView.cpp b/src/preferences/shortcuts/clv/ColumnListView.cpp
    deleted file mode 100644
    index 9c175ec..0000000
    + -  
    1 /*
    2  * Copyright 1999-2009 Jeremy Friesner
    3  * Copyright 2009-2014 Haiku, Inc. All rights reserved.
    4  * Distributed under the terms of the MIT License.
    5  *
    6  * Authors:
    7  *      Jeremy Friesner
    8  *      John Scipione, jscipione@gmail.com
    9  */
    10 
    11 
    12 #define ColumnListView_CPP
    13 
    14 #include "ColumnListView.h"
    15 #include "CLVColumnLabelView.h"
    16 #include "CLVColumn.h"
    17 #include "CLVListItem.h"
    18 
    19 #include <stdio.h>
    20 #include <interface/Rect.h>
    21 
    22 
    23 uint8 CLVRightArrowData[132] = {
    24     0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    25     0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    26     0xFF, 0xFF, 0xFF, 0x00, 0x12, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    27     0xFF, 0xFF, 0xFF, 0x00, 0x12, 0x12, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    28     0xFF, 0xFF, 0xFF, 0x00, 0x12, 0x12, 0x12, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
    29     0xFF, 0xFF, 0xFF, 0x00, 0x12, 0x12, 0x12, 0x12, 0x00, 0xFF, 0xFF, 0xFF,
    30     0xFF, 0xFF, 0xFF, 0x00, 0x12, 0x12, 0x12, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
    31     0xFF, 0xFF, 0xFF, 0x00, 0x12, 0x12, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    32     0xFF, 0xFF, 0xFF, 0x00, 0x12, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    33     0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    34     0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
    35 };
    36 
    37 uint8 CLVDownArrowData[132] = {
    38     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    39     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    40     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    41     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
    42     0xFF, 0x00, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x00, 0xFF, 0xFF,
    43     0xFF, 0xFF, 0x00, 0x12, 0x12, 0x12, 0x12, 0x12, 0x00, 0xFF, 0xFF, 0xFF,
    44     0xFF, 0xFF, 0xFF, 0x00, 0x12, 0x12, 0x12, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
    45     0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x12, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    46     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    47     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    48     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
    49 };
    50 
    51 
    52 class CLVContainerView : public BScrollView
    53 {
    54 public:
    55                             CLVContainerView(char* name, BView* target,
    56                                 uint32 resizingMode, uint32 flags,
    57                                 bool horizontal, bool vertical,
    58                                 border_style border);
    59     virtual                 ~CLVContainerView();
    60 
    61             bool            IsBeingDestroyed() const
    62                                 { return fIsBeingDestroyed; };
    63 
    64 private:
    65             bool            fIsBeingDestroyed;
    66 };
    67 
    68 
    69 CLVContainerView::CLVContainerView(char* name, BView* target,
    70     uint32 resizingMode, uint32 flags, bool horizontal, bool vertical,
    71     border_style border)
    72     :
    73     BScrollView(name, target, resizingMode, flags, horizontal, vertical,
    74         border)
    75 {
    76     fIsBeingDestroyed = false;
    77 }
    78 
    79 
    80 CLVContainerView::~CLVContainerView()
    81 {
    82     fIsBeingDestroyed = true;
    83 }
    84 
    85 
    86 ColumnListView::ColumnListView(BRect frame, BScrollView** containerView,
    87     const char* name, uint32 resizingMode, uint32 flags, list_view_type type,
    88     bool hierarchical, bool horizontal, bool vertical, border_style border,
    89     const BFont* labelFont)
    90     :
    91     BListView(frame, name, type, B_FOLLOW_ALL_SIDES, flags | B_PULSE_NEEDED),
    92     fHierarchical(hierarchical),
    93     fColumnList(6),
    94     fColumnDisplayList(6),
    95     fDataWidth(0),
    96     fDataHeight(0),
    97     fPageWidth(0),
    98     fPageHeight(0),
    99     fSortKeyList(6),
    100     fRightArrow(BRect(0, 0, 10, 10), B_RGBA32, CLVRightArrowData, false, false),
    101     fDownArrow(BRect(0, 0, 10, 10), B_RGBA32, CLVDownArrowData, false, false),
    102     fFullItemList(32),
    103     fSelectedColumn(-1),
    104     fEditMessage(NULL)
    105 {
    106     // create the column titles bar view
    107     font_height fontAttributes;
    108     labelFont->GetHeight(&fontAttributes);
    109     float fLabelFontHeight = ceil(fontAttributes.ascent)
    110         + ceil(fontAttributes.descent);
    111     float columnLabelViewBottom = frame.top + 1 + fLabelFontHeight + 3;
    112     fColumnLabelView = new CLVColumnLabelView(BRect(frame.left, frame.top,
    113         frame.right, columnLabelViewBottom), this, labelFont);
    114 
    115     // create the container view
    116     CreateContainer(horizontal, vertical, border, resizingMode, flags);
    117     *containerView = fScrollView;
    118 
    119     // complete the setup
    120     ShiftDragGroup();
    121     fColumnLabelView->UpdateDragGroups();
    122     fExpanderColumn = -1;
    123     fCompareFunction = NULL;
    124 }
    125 
    126 
    127 ColumnListView::~ColumnListView()
    128 {
    129     // delete all list columns
    130     int32 ColumnCount = fColumnList.CountItems();
    131     for (int32 i = ColumnCount - 1; i >= 0; i--) {
    132         CLVColumn* item = (CLVColumn*)fColumnList.RemoveItem(i);
    133         if (item != NULL)
    134             delete item;
    135     }
    136 
    137     // remove and delete the container view if necessary
    138     if (!fScrollView->IsBeingDestroyed()) {
    139         fScrollView->RemoveChild(this);
    140         delete fScrollView;
    141     }
    142 
    143     delete fEditMessage;
    144 }
    145 
    146 
    147 void
    148 ColumnListView::CreateContainer(bool horizontal, bool vertical,
    149     border_style border, uint32 resizingMode, uint32 flags)
    150 {
    151     BRect frame = Frame();
    152     BRect labelsFrame = fColumnLabelView->Frame();
    153 
    154     fScrollView = new CLVContainerView(NULL, this, resizingMode, flags,
    155         horizontal, vertical, border);
    156     BRect newFrame = Frame();
    157     // resize the main view to make room for the CLVColumnLabelView
    158     ResizeTo(frame.right - frame.left, frame.bottom -
    159         labelsFrame.bottom - 1.0);
    160     MoveTo(newFrame.left, newFrame.top
    161         + (labelsFrame.bottom - labelsFrame.top + 1.0));
    162     fColumnLabelView->MoveTo(newFrame.left, newFrame.top);
    163 
    164     // add the ColumnLabelView
    165     fScrollView->AddChild(fColumnLabelView);
    166 
    167     // remove and re-add the BListView so that it will draw after
    168     // the CLVColumnLabelView
    169     fScrollView->RemoveChild(this);
    170     fScrollView->AddChild(this);
    171 
    172     fFillerView = NULL;
    173 }
    174 
    175 
    176 void
    177 ColumnListView::AddScrollViewCorner()
    178 {
    179     BPoint farCorner = fScrollView->Bounds().RightBottom();
    180     fFillerView = new ScrollViewCorner(farCorner.x - B_V_SCROLL_BAR_WIDTH,
    181         farCorner.y - B_H_SCROLL_BAR_HEIGHT);
    182     fScrollView->AddChild(fFillerView);
    183 }
    184 
    185 
    186 void
    187 ColumnListView::ShiftDragGroup()
    188 {
    189     // figure out the width
    190     float columnBegin;
    191     float columnEnd = -1.0;
    192     fDataWidth = 0.0;
    193     bool nextPushedByExpander = false;
    194     int32 columnCount = fColumnDisplayList.CountItems();
    195     for (int32 i = 0; i < columnCount; i++) {
    196         CLVColumn* column = (CLVColumn*)fColumnDisplayList.ItemAt(i);
    197         if (nextPushedByExpander)
    198             column->fPushedByExpander = true;
    199         else
    200             column->fPushedByExpander = false;
    201 
    202         if (column->IsShown()) {
    203             float columnWidth = column->Width();
    204             columnBegin = columnEnd + 1.0;
    205             columnEnd = columnBegin + columnWidth;
    206             column->fColumnBegin = columnBegin;
    207             column->fColumnEnd = columnEnd;
    208             fDataWidth = column->fColumnEnd;
    209             if (nextPushedByExpander && !(column->fFlags & CLV_PUSH_PASS))
    210                 nextPushedByExpander = false;
    211 
    212             if (column->fFlags & CLV_EXPANDER) {
    213                 // set the next column to be pushed
    214                 nextPushedByExpander = true;
    215             }
    216         }
    217     }
    218 
    219     // figure out the height
    220     fDataHeight = 0.0;
    221     int32 itemCount = CountItems();
    222     for (int32 i = 0; i < itemCount; i++)
    223         fDataHeight += ItemAt(i)->Height() + 1.0;
    224 
    225     if (itemCount > 0)
    226         fDataHeight -= 1.0;
    227 
    228     // update the scroll bars
    229     UpdateScrollBars();
    230 }
    231 
    232 
    233 void
    234 ColumnListView::UpdateScrollBars()
    235 {
    236     if (fScrollView != NULL) {
    237         // figure out the bounds and scroll if necessary
    238         BRect bounds;
    239         float deltaX;
    240         float deltaY;
    241         do {
    242             bounds = Bounds();
    243             //Figure out the width of the page rectangle
    244             fPageWidth = fDataWidth;
    245             fPageHeight = fDataHeight;
    246             //If view runs past the end, make more visible at the beginning
    247             deltaX = 0.0;
    248             if (bounds.right > fDataWidth && bounds.left > 0) {
    249                 deltaX = bounds.right - fDataWidth;
    250                 if (deltaX > bounds.left)
    251                     deltaX = bounds.left;
    252             }
    253             deltaY = 0.0;
    254             if (bounds.bottom > fDataHeight && bounds.top > 0) {
    255                 deltaY = bounds.bottom - fDataHeight;
    256                 if (deltaY > bounds.top)
    257                     deltaY = bounds.top;
    258             }
    259             if (deltaX != 0.0 || deltaY != 0.0) {
    260                 ScrollTo(BPoint(bounds.left - deltaX, bounds.top - deltaY));
    261                 bounds = Bounds();
    262             }
    263             if (bounds.right-bounds.left > fDataWidth)
    264                 fPageWidth = bounds.right;
    265 
    266             if (bounds.bottom-bounds.top > fDataHeight)
    267                 fPageHeight = bounds.bottom;
    268         } while (deltaX != 0.0 || deltaY != 0.0);
    269 
    270         // figure out the ratio of the bounds rectangle width or height
    271         // to the page rectangle width or height
    272         float widthRatio = (bounds.right - bounds.left) / fPageWidth;
    273         float heightRatio = (bounds.bottom - bounds.top) / fPageHeight;
    274 
    275         BScrollBar* horizontalScrollBar = fScrollView->ScrollBar(B_HORIZONTAL);
    276         BScrollBar* verticalScrollBar = fScrollView->ScrollBar(B_VERTICAL);
    277         // set the scroll bar ranges and proportions.  If the whole document
    278         // is visible, inactivate the slider
    279         if (horizontalScrollBar != NULL) {
    280             if (widthRatio >= 1.0 && bounds.left == 0.0)
    281                 horizontalScrollBar->SetRange(0.0, 0.0);
    282             else {
    283                 horizontalScrollBar->SetRange(0.0, fPageWidth
    284                     - (bounds.right - bounds.left));
    285             }
    286             horizontalScrollBar->SetProportion(widthRatio);
    287             // set the step values
    288             horizontalScrollBar->SetSteps(20.0, bounds.right - bounds.left);
    289         }
    290 
    291         if (verticalScrollBar != NULL) {
    292             if (heightRatio >= 1.0 && bounds.top == 0.0) {
    293                 verticalScrollBar->SetRange(0.0, 0.0);
    294                 if (fFillerView)
    295                     fFillerView->SetViewColor(BeInactiveControlGrey);
    296             } else {
    297                 verticalScrollBar->SetRange(0.0,
    298                     fPageHeight - (bounds.bottom-bounds.top));
    299                 if (fFillerView != NULL)
    300                     fFillerView->SetViewColor(BeBackgroundGrey);
    301             }
    302             verticalScrollBar->SetProportion(heightRatio);
    303         }
    304     }
    305 }
    306 
    307 
    308 void
    309 ColumnListView::ColumnsChanged()
    310 {
    311     // any previous column dragging/resizing will get corrupted, so deselect
    312     if (fColumnLabelView->fColumnClicked)
    313         fColumnLabelView->fColumnClicked = NULL;
    314 
    315     // update the internal sizes and grouping of the columns and sizes
    316     // of drag groups
    317     ShiftDragGroup();
    318     fColumnLabelView->UpdateDragGroups();
    319     fColumnLabelView->Invalidate();
    320     Invalidate();
    321 }
    322 
    323 
    324 // Adds a column to the ColumnListView at the end of the list.
    325 // Returns true if successful.
    326 bool
    327 ColumnListView::AddColumn(CLVColumn* column)
    328 {
    329     int32 columnCount = fColumnList.CountItems();
    330     int32 displayIndex = columnCount;
    331 
    332     // make sure a second Expander is not being added
    333     if ((column->fFlags & CLV_EXPANDER) != 0) {
    334         if (!fHierarchical)
    335             return false;
    336 
    337         for (int32 i = 0; i < columnCount; i++) {
    338             if ((((CLVColumn*)fColumnList.ItemAt(i))->fFlags & CLV_EXPANDER)
    339                     != 0) {
    340                 return false;
    341             }
    342         }
    343 
    344         if (column->IsShown())
    345             fExpanderColumn = columnCount;
    346     }
    347 
    348     // make sure this column hasn't already been added to another ColumnListView
    349     if (column->fParent != NULL)
    350         return false;
    351 
    352     BWindow* parentWindow = Window();
    353     if (parentWindow != NULL)
    354         parentWindow->Lock();
    355 
    356     // check if this should be locked at the beginning or end, and adjust
    357     // its position if necessary
    358     if ((column->Flags() & CLV_LOCK_AT_END) == 0) {
    359         bool shouldRepeat;
    360         if ((column->Flags() & CLV_LOCK_AT_BEGINNING) != 0) {
    361             // move it to the beginning, after the last
    362             // CLV_LOCK_AT_BEGINNING item
    363             displayIndex = 0;
    364             shouldRepeat = true;
    365             while (shouldRepeat && displayIndex < columnCount) {
    366                 shouldRepeat = false;
    367                 CLVColumn* lastColumn
    368                     = (CLVColumn*)fColumnDisplayList.ItemAt(displayIndex);
    369                 if ((lastColumn->Flags() & CLV_LOCK_AT_BEGINNING) != 0) {
    370                     displayIndex++;
    371                     shouldRepeat = true;
    372                 }
    373             }
    374         } else {
    375             // make sure it isn't after a CLV_LOCK_AT_END item
    376             shouldRepeat = true;
    377             while (shouldRepeat && displayIndex > 0)
    378             {
    379                 shouldRepeat = false;
    380                 CLVColumn* lastColumn
    381                     = (CLVColumn*)fColumnDisplayList.ItemAt(displayIndex - 1);
    382                 if ((lastColumn->Flags() & CLV_LOCK_AT_END) != 0) {
    383                     displayIndex--;
    384                     shouldRepeat = true;
    385                 }
    386             }
    387         }
    388     }
    389 
    390     // add the column to the display list in the appropriate position
    391     fColumnDisplayList.AddItem(column, displayIndex);
    392 
    393     // add the column to the end of the column list
    394     fColumnList.AddItem(column);
    395 
    396     // tell the column it belongs to me now
    397     column->fParent = this;
    398 
    399     // set the scroll bars and tell views to update
    400     ColumnsChanged();
    401     if (parentWindow != NULL)
    402         parentWindow->Unlock();
    403 
    404     return true;
    405 }
    406 
    407 
    408 // Adds a BList of CLVColumn's to the ColumnListView at the position specified,
    409 // or at the end of the list if AtIndex == -1.  Returns true if successful.
    410 bool
    411 ColumnListView::AddColumnList(BList* newColumns)
    412 {
    413     int32 columnCount = int32(fColumnList.CountItems());
    414     int32 columnCountToAdd = int32(newColumns->CountItems());
    415 
    416     // make sure a second CLVExpander is not being added
    417     int32 expanderCount = 0;
    418     for (int32 i = 0; i < columnCount; i++) {
    419         if ((((CLVColumn*)fColumnList.ItemAt(i))->fFlags & CLV_EXPANDER) != 0)
    420             expanderCount++;
    421     }
    422 
    423     int32 expandercolumnIndex = -1;
    424     for (int32 i = 0; i < columnCountToAdd; i++) {
    425         CLVColumn* current = (CLVColumn*)newColumns->ItemAt(i);
    426         if ((current->fFlags & CLV_EXPANDER) != 0) {
    427             expanderCount++;
    428             if (current->IsShown())
    429                 expandercolumnIndex = columnCount + i;
    430         }
    431     }
    432 
    433     if (expanderCount != 0 && !fHierarchical)
    434         return false;
    435 
    436     if (expanderCount > 1)
    437         return false;
    438 
    439     if (expandercolumnIndex != -1)
    440         fExpanderColumn = expandercolumnIndex;
    441 
    442     // make sure none of these columns have already been added
    443     // to a ColumnListView
    444     for (int32 i = 0; i < columnCountToAdd; i++) {
    445         if (((CLVColumn*)newColumns->ItemAt(i))->fParent != NULL)
    446             return false;
    447     }
    448 
    449     // make sure none of these columns are being added twice
    450     for (int32 i = 0; i < columnCountToAdd - 1; i++) {
    451         for (int32 j = i + 1; j < columnCountToAdd; j++) {
    452             if (newColumns->ItemAt(i) == newColumns->ItemAt(j))
    453                 return false;
    454         }
    455     }
    456 
    457     BWindow* parentWindow = Window();
    458     if (parentWindow != NULL)
    459         parentWindow->Lock();
    460 
    461     for (int32 i = 0; i < columnCountToAdd; i++) {
    462         CLVColumn* column = (CLVColumn*)newColumns->ItemAt(i);
    463         // check if this should be locked at the beginning or end,
    464         // and adjust its position if necessary
    465         int32 displayIndex = columnCount;
    466         if ((column->Flags() & CLV_LOCK_AT_END) == 0) {
    467             bool shouldRepeat;
    468             if ((column->Flags() & CLV_LOCK_AT_BEGINNING) != 0) {
    469                 // move it to the beginning, after the last
    470                 // CLV_LOCK_AT_BEGINNING item
    471                 displayIndex = 0;
    472                 shouldRepeat = true;
    473                 while (shouldRepeat && displayIndex < columnCount) {
    474                     shouldRepeat = false;
    475                     CLVColumn* lastColumn
    476                         = (CLVColumn*)fColumnDisplayList.ItemAt(displayIndex);
    477                     if ((lastColumn->Flags() & CLV_LOCK_AT_BEGINNING) != 0) {
    478                         displayIndex++;
    479                         shouldRepeat = true;
    480                     }
    481                 }
    482             } else {
    483                 // make sure it isn't after a CLV_LOCK_AT_END item
    484                 shouldRepeat = true;
    485                 while (shouldRepeat && displayIndex > 0) {
    486                     shouldRepeat = false;
    487                     CLVColumn* lastColumn
    488                         = (CLVColumn*)fColumnDisplayList.ItemAt(
    489                             displayIndex - 1);
    490                     if ((lastColumn->Flags() & CLV_LOCK_AT_END) != 0) {
    491                         displayIndex--;
    492                         shouldRepeat = true;
    493                     }
    494                 }
    495             }
    496         }
    497 
    498         // add the column to the display list in the appropriate position
    499         fColumnDisplayList.AddItem(column, displayIndex);
    500 
    501         // tell the column it belongs to me now
    502         column->fParent = this;
    503 
    504         columnCount++;
    505     }
    506 
    507     // add the columns to the end of the column list
    508     fColumnList.AddList(newColumns);
    509 
    510     // set the scroll bars and tell views to update
    511     ColumnsChanged();
    512     if (parentWindow != NULL)
    513         parentWindow->Unlock();
    514 
    515     return true;
    516 }
    517 
    518 
    519 // Removes a CLVColumn from the ColumnListView.
    520 // Returns true if successful.
    521 bool
    522 ColumnListView::RemoveColumn(CLVColumn* column)
    523 {
    524     if (!fColumnList.HasItem(column))
    525         return false;
    526 
    527     int32 columnIndex = fSortKeyList.IndexOf(column);
    528     if (columnIndex >= 0)
    529         fSortKeyList.RemoveItem(columnIndex);
    530 
    531     if ((column->fFlags & CLV_EXPANDER) != 0)
    532         fExpanderColumn = -1;
    533 
    534     BWindow* parentWindow = Window();
    535     if (parentWindow != NULL)
    536         parentWindow->Lock();
    537 
    538     // remove column from the column and display lists
    539     fColumnDisplayList.RemoveItem(column);
    540     fColumnList.RemoveItem(column);
    541 
    542     //tell the column it has been removed
    543     column->fParent = NULL;
    544 
    545     // set the scroll bars and tell views to update
    546     ColumnsChanged();
    547     if (parentWindow != NULL)
    548         parentWindow->Unlock();
    549 
    550     return true;
    551 }
    552 
    553 
    554 // Finds column in columnList and removes Count columns and their data
    555 // from the view and its items.
    556 bool
    557 ColumnListView::RemoveColumns(CLVColumn* column, int32 count)
    558 {
    559     BWindow* parentWindow = Window();
    560     if (parentWindow != NULL)
    561         parentWindow->Lock();
    562 
    563     int32 columnIndex = fColumnList.IndexOf(column);
    564     if (columnIndex < 0) {
    565         if (parentWindow != NULL)
    566             parentWindow->Unlock();
    567 
    568         return false;
    569     }
    570 
    571     if (columnIndex + count >= fColumnList.CountItems()) {
    572         if (parentWindow != NULL)
    573             parentWindow->Unlock();
    574 
    575         return false;
    576     }
    577 
    578     for (int32 i = columnIndex; i < columnIndex + count; i++) {
    579         // remove columns from the column and display lists
    580         CLVColumn* current = (CLVColumn*)fColumnList.ItemAt(i);
    581         fColumnDisplayList.RemoveItem(current);
    582 
    583         int32 sortIndex = fSortKeyList.IndexOf(column);
    584         if (sortIndex >= 0)
    585             fSortKeyList.RemoveItem(sortIndex);
    586 
    587         if ((current->fFlags & CLV_EXPANDER) != 0)
    588             fExpanderColumn = -1;
    589 
    590         // tell the column it has been removed
    591         current->fParent = NULL;
    592     }
    593     fColumnList.RemoveItems(columnIndex, count);
    594 
    595     // set the scroll bars and tell views to update
    596     ColumnsChanged();
    597     if (parentWindow != NULL)
    598         parentWindow->Unlock();
    599 
    600     return true;
    601 }
    602 
    603 void
    604 ColumnListView::SetEditMessage(BMessage* message, BMessenger target)
    605 {
    606     delete fEditMessage;
    607     fEditMessage = message;
    608     fEditTarget = target;
    609 }
    610 
    611 
    612 void
    613 ColumnListView::KeyDown(const char* bytes, int32 numBytes)
    614 {
    615     int colDiff = 0;
    616     bool metaKeysPressed = false;
    617 
    618     // find out if any meta-keys are pressed
    619     int32 q;
    620     if (Window()->CurrentMessage()->FindInt32("modifiers", &q) == B_NO_ERROR) {
    621         metaKeysPressed = ((q & (B_SHIFT_KEY | B_COMMAND_KEY | B_CONTROL_KEY
    622             | B_OPTION_KEY)) != 0);
    623     }
    624 
    625     if (numBytes > 0) {
    626         switch (*bytes)
    627         {
    628             case B_LEFT_ARROW:
    629             if (metaKeysPressed == false)
    630             {
    631                 colDiff = -1;
    632                 break;
    633             }
    634 
    635             case B_RIGHT_ARROW:
    636             if (metaKeysPressed == false)
    637             {
    638                 colDiff = 1;
    639                 break;
    640             }
    641 
    642             case B_UP_ARROW:
    643             case B_DOWN_ARROW:
    644             if (metaKeysPressed == false)
    645             {
    646                 BListView::KeyDown(bytes, numBytes);
    647                 break;
    648             }
    649 
    650             default:
    651             if (fEditMessage != NULL)
    652             {
    653                 BMessage temp(*fEditMessage);
    654                 temp.AddInt32("column", fSelectedColumn);
    655                 temp.AddInt32("row", CurrentSelection());
    656                 temp.AddString("bytes", bytes);
    657 
    658                 int32 key;
    659                 if (Window()->CurrentMessage()->FindInt32("key", &key)
    660                         == B_NO_ERROR) {
    661                     temp.AddInt32("key", key);
    662                 }
    663 
    664                 fEditTarget.SendMessage(&temp);
    665             }
    666             break;
    667         }
    668     }
    669 
    670     if (colDiff != 0) {
    671         // we need to move the highlighted column by (colDiff) columns
    672         // if possible.
    673         int displayColumnCount = fColumnDisplayList.CountItems();
    674         int currentColumn = fSelectedColumn;
    675             // currentColumn is an ACTUAL index.
    676         if (currentColumn == -1) {
    677             // no current column selected?
    678             currentColumn = (colDiff > 0) ? GetActualIndexOf(0)
    679                 : GetActualIndexOf(displayColumnCount-1);
    680                 // go to an edge
    681         } else {
    682             // go to the display column adjacent to the current column's
    683             // display column.
    684             int32 currentDisplayIndex = GetDisplayIndexOf(currentColumn);
    685             if (currentDisplayIndex < 0)
    686                 currentDisplayIndex = 0;
    687 
    688             currentDisplayIndex += colDiff;
    689 
    690             if (currentDisplayIndex < 0)
    691                 currentDisplayIndex = displayColumnCount - 1;
    692 
    693             if (currentDisplayIndex >= displayColumnCount)
    694                 currentDisplayIndex = 0;
    695 
    696             currentColumn = GetActualIndexOf(currentDisplayIndex);
    697         }
    698 
    699         SetSelectedColumnIndex(currentColumn);
    700     }
    701 }
    702 
    703 
    704 int32
    705 ColumnListView::CountColumns() const
    706 {
    707     return fColumnList.CountItems();
    708 }
    709 
    710 
    711 int32
    712 ColumnListView::IndexOfColumn(CLVColumn* column) const
    713 {
    714     return fColumnList.IndexOf(column);
    715 }
    716 
    717 
    718 CLVColumn*
    719 ColumnListView::ColumnAt(int32 columnIndex) const
    720 {
    721     return (CLVColumn*)fColumnList.ItemAt(columnIndex);
    722 }
    723 
    724 
    725 CLVColumn*
    726 ColumnListView::ColumnAt(BPoint point) const
    727 {
    728     int32 columnCount = fColumnList.CountItems();
    729     for (int32 i = 0; i < columnCount; i++) {
    730         CLVColumn* col = (CLVColumn*)fColumnList.ItemAt(i);
    731         if ((point.x >= col->fColumnBegin) && (point.x <= col->fColumnEnd))
    732             return col;
    733     }
    734 
    735     return NULL;
    736 }
    737 
    738 
    739 //Sets the display order using a BList of CLVColumn's
    740 bool
    741 ColumnListView::SetDisplayOrder(const int32* ColumnOrder)
    742 {
    743     BWindow* parentWindow = Window();
    744     if (parentWindow != NULL)
    745         parentWindow->Lock();
    746 
    747     // add the items to the display list in order
    748     fColumnDisplayList.MakeEmpty();
    749     int32 columnCount = fColumnList.CountItems();
    750     for (int32 i = 0; i < columnCount; i++) {
    751         if (ColumnOrder[i] >= columnCount) {
    752             if (parentWindow != NULL)
    753                 parentWindow->Unlock();
    754 
    755             return false;
    756         }
    757 
    758         for (int32 j = 0; j < i; j++) {
    759             if (ColumnOrder[i] == ColumnOrder[j]) {
    760                 if (parentWindow != NULL)
    761                     parentWindow->Unlock();
    762 
    763                 return false;
    764             }
    765         }
    766         fColumnDisplayList.AddItem(fColumnList.ItemAt(ColumnOrder[i]));
    767     }
    768 
    769     // update everything about the columns
    770     ColumnsChanged();
    771 
    772     // let the program know that the display order changed.
    773     if (parentWindow != NULL)
    774         parentWindow->Unlock();
    775 
    776     DisplayOrderChanged(ColumnOrder);
    777 
    778     return true;
    779 }
    780 
    781 
    782 void
    783 ColumnListView::ColumnWidthChanged(int32 columnIndex, float newWidth)
    784 {
    785     Invalidate();
    786 }
    787 
    788 
    789 void
    790 ColumnListView::DisplayOrderChanged(const int32* order)
    791 {
    792 }
    793 
    794 
    795 int32*
    796 ColumnListView::DisplayOrder() const
    797 {
    798     int32 columnCount = fColumnList.CountItems();
    799     int32* list = new int32[columnCount];
    800     BWindow* parentWindow = Window();
    801     if (parentWindow != NULL)
    802         parentWindow->Lock();
    803 
    804     for (int32 i = 0; i < columnCount; i++)
    805         list[i] = int32(fColumnList.IndexOf(fColumnDisplayList.ItemAt(i)));
    806 
    807     if (parentWindow != NULL)
    808         parentWindow->Unlock();
    809 
    810     return list;
    811 }
    812 
    813 
    814 void
    815 ColumnListView::SetSortKey(int32 columnIndex)
    816 {
    817     CLVColumn* column;
    818     if (columnIndex >= 0) {
    819         column = (CLVColumn*)fColumnList.ItemAt(columnIndex);
    820         if ((column->Flags() & CLV_SORT_KEYABLE) == 0)
    821             return;
    822     } else
    823         column = NULL;
    824 
    825     if (fSortKeyList.ItemAt(0) != column || column == NULL) {
    826         BWindow* parentWindow = Window();
    827         if (parentWindow != NULL)
    828             parentWindow->Lock();
    829 
    830         BRect labelBounds = fColumnLabelView->Bounds();
    831         // need to remove old sort keys and erase all the old underlines
    832         int32 sortKeyCount = fSortKeyList.CountItems();
    833         for (int32 i = 0; i < sortKeyCount; i++) {
    834             CLVColumn* underlineColumn = (CLVColumn*)fSortKeyList.ItemAt(i);
    835             if (underlineColumn->fSortMode != SORT_MODE_NONE) {
    836                 fColumnLabelView->Invalidate(
    837                 BRect(underlineColumn->fColumnBegin,
    838                     labelBounds.top, underlineColumn->fColumnEnd,
    839                     labelBounds.bottom));
    840             }
    841         }
    842         fSortKeyList.MakeEmpty();
    843 
    844         if (column != NULL) {
    845             fSortKeyList.AddItem(column);
    846             if (column->fSortMode == SORT_MODE_NONE)
    847                 SetSortMode(columnIndex, SORT_MODE_ASCENDING);
    848 
    849             SortItems();
    850             // need to draw new underline
    851             fColumnLabelView->Invalidate(BRect(column->fColumnBegin,
    852                 labelBounds.top, column->fColumnEnd, labelBounds.bottom));
    853         }
    854         if (parentWindow != NULL)
    855             parentWindow->Unlock();
    856     }
    857 }
    858 
    859 
    860 void
    861 ColumnListView::AddSortKey(int32 columnIndex)
    862 {
    863     CLVColumn* column;
    864     if (columnIndex >= 0) {
    865         column = (CLVColumn*)fColumnList.ItemAt(columnIndex);
    866         if ((column->Flags() & CLV_SORT_KEYABLE) == 0)
    867             return;
    868     } else
    869         column = NULL;
    870 
    871     if (column != NULL && !fSortKeyList.HasItem(column)) {
    872         BWindow* parentWindow = Window();
    873         if (parentWindow != NULL)
    874             parentWindow->Lock();
    875 
    876         BRect labelBounds = fColumnLabelView->Bounds();
    877         fSortKeyList.AddItem(column);
    878         if (column->fSortMode == SORT_MODE_NONE)
    879             SetSortMode(columnIndex, SORT_MODE_ASCENDING);
    880 
    881         SortItems();
    882 
    883         // need to draw new underline
    884         fColumnLabelView->Invalidate(BRect(column->fColumnBegin,
    885             labelBounds.top, column->fColumnEnd, labelBounds.bottom));
    886 
    887         if (parentWindow != NULL)
    888             parentWindow->Unlock();
    889     }
    890 }
    891 
    892 
    893 void
    894 ColumnListView::SetSortMode(int32 columnIndex, CLVSortMode sortMode)
    895 {
    896     CLVColumn* column;
    897     if (columnIndex >= 0) {
    898         column = (CLVColumn*)fColumnList.ItemAt(columnIndex);
    899         if ((column->Flags() & CLV_SORT_KEYABLE) == 0)
    900             return;
    901     } else
    902         return;
    903 
    904     if (column->fSortMode != sortMode) {
    905         BWindow* parentWindow = Window();
    906         if (parentWindow != NULL)
    907             parentWindow->Lock();
    908 
    909         BRect labelBounds = fColumnLabelView->Bounds();
    910         column->fSortMode = sortMode;
    911         if (sortMode == SORT_MODE_NONE && fSortKeyList.HasItem(column))
    912             fSortKeyList.RemoveItem(column);
    913 
    914         SortItems();
    915         // need to draw or erase underline
    916 
    917         fColumnLabelView->Invalidate(BRect(column->fColumnBegin,
    918             labelBounds.top, column->fColumnEnd, labelBounds.bottom));
    919         if (parentWindow != NULL)
    920             parentWindow->Unlock();
    921     }
    922 }
    923 
    924 
    925 void
    926 ColumnListView::ReverseSortMode(int32 columnIndex)
    927 {
    928     CLVColumn* column;
    929     if (columnIndex >= 0) {
    930         column = (CLVColumn*)fColumnList.ItemAt(columnIndex);
    931         if ((column->Flags() & CLV_SORT_KEYABLE) == 0)
    932             return;
    933     } else
    934         return;
    935 
    936     if (column->fSortMode == SORT_MODE_ASCENDING)
    937         SetSortMode(columnIndex, SORT_MODE_DESCENDING);
    938     else if (column->fSortMode == SORT_MODE_DESCENDING)
    939         SetSortMode(columnIndex, SORT_MODE_NONE);
    940     else if (column->fSortMode == SORT_MODE_NONE)
    941         SetSortMode(columnIndex, SORT_MODE_ASCENDING);
    942 }
    943 
    944 
    945 int32
    946 ColumnListView::Sorting(int32* sortKeys, CLVSortMode* sortModes) const
    947 {
    948     BWindow* parentWindow = Window();
    949     if (parentWindow != NULL)
    950         parentWindow->Lock();
    951 
    952     int32 keyCount = fSortKeyList.CountItems();
    953     for (int32 i = 0; i < keyCount; i++) {
    954         CLVColumn* Column = (CLVColumn*)fSortKeyList.ItemAt(i);
    955         sortKeys[i] = IndexOfColumn(Column);
    956         sortModes[i] = Column->SortMode();
    957     }
    958 
    959     if (parentWindow != NULL)
    960         parentWindow->Unlock();
    961 
    962     return keyCount;
    963 }
    964 
    965 void
    966 ColumnListView::Pulse()
    967 {
    968     int32 curSel = CurrentSelection();
    969     if (curSel >= 0) {
    970         CLVListItem* item = (CLVListItem*) ItemAt(curSel);
    971         item->Pulse(this);
    972     }
    973 }
    974 
    975 
    976 void
    977 ColumnListView::SetSorting(int32 keyCount, int32* sortKeys,
    978     CLVSortMode* sortModes)
    979 {
    980     BWindow* parentWindow = Window();
    981     if (parentWindow != NULL)
    982         parentWindow->Lock();
    983 
    984     // need to remove old sort keys and erase all the old underlines
    985     BRect labelBounds = fColumnLabelView->Bounds();
    986     int32 sortKeyCount = fSortKeyList.CountItems();
    987     for (int32 i = 0; i < sortKeyCount; i++) {
    988         CLVColumn* underlineColumn = (CLVColumn*)fSortKeyList.ItemAt(i);
    989         if (underlineColumn->fSortMode != SORT_MODE_NONE) {
    990             fColumnLabelView->Invalidate(BRect(underlineColumn->fColumnBegin,
    991                 labelBounds.top, underlineColumn->fColumnEnd,
    992                 labelBounds.bottom));
    993         }
    994     }
    995     fSortKeyList.MakeEmpty();
    996 
    997     for (int32 i = 0; i < keyCount; i++) {
    998         if (i == 0)
    999             SetSortKey(sortKeys[0]);
    1000         else
    1001             AddSortKey(sortKeys[i]);
    1002 
    1003         SetSortMode(sortKeys[i], sortModes[i]);
    1004     }
    1005 
    1006     if (parentWindow != NULL)
    1007         parentWindow->Unlock();
    1008 }
    1009 
    1010 
    1011 void
    1012 ColumnListView::FrameResized(float newWidth, float newHeight)
    1013 {
    1014     ShiftDragGroup();
    1015     uint32 itemCount = CountItems();
    1016     BFont font;
    1017     GetFont(&font);
    1018     for (uint32 i = 0; i < itemCount; i++)
    1019         ItemAt(i)->Update(this, &font);
    1020 
    1021     BListView::FrameResized(newWidth, newHeight);
    1022 }
    1023 
    1024 
    1025 void
    1026 ColumnListView::AttachedToWindow()
    1027 {
    1028     // Hack to work around app_server bug
    1029     BListView::AttachedToWindow();
    1030     ShiftDragGroup();
    1031 }
    1032 
    1033 
    1034 void
    1035 ColumnListView::ScrollTo(BPoint point)
    1036 {
    1037     BListView::ScrollTo(point);
    1038     fColumnLabelView->ScrollTo(BPoint(point.x, 0.0));
    1039 }
    1040 
    1041 int32
    1042 ColumnListView::GetActualIndexOf(int32 displayIndex) const
    1043 {
    1044     if ((displayIndex < 0) || (displayIndex >= fColumnDisplayList.CountItems()))
    1045         return -1;
    1046 
    1047     return (int32)fColumnList.IndexOf(fColumnDisplayList.ItemAt(displayIndex));
    1048 }
    1049 
    1050 
    1051 int32
    1052 ColumnListView::GetDisplayIndexOf(int32 realIndex) const
    1053 {
    1054     if ((realIndex < 0) || (realIndex >= fColumnList.CountItems()))
    1055         return -1;
    1056 
    1057     return (int32)fColumnDisplayList.IndexOf(fColumnList.ItemAt(realIndex));
    1058 }
    1059 
    1060 
    1061 // Set a new (actual) column index as the selected index.
    1062 // Call with arg -1 to unselect all.
    1063 // Gotta change the fSelectedColumn on all entries.
    1064 // There is undoubtedly a more efficient way to do this!  --jaf
    1065 void
    1066 ColumnListView :: SetSelectedColumnIndex(int32 col)
    1067 {
    1068     if (fSelectedColumn != col) {
    1069         fSelectedColumn = col;
    1070 
    1071         int32 numRows = fFullItemList.CountItems();
    1072         for (int32 j = 0; j < numRows; j++) {
    1073             ((CLVListItem *)fFullItemList.ItemAt(j))->fSelectedColumn
    1074                 = fSelectedColumn;
    1075         }
    1076 
    1077         // update current row if necessary
    1078         int32 selectedIndex = CurrentSelection();
    1079         if (selectedIndex != -1)
    1080             InvalidateItem(selectedIndex);
    1081    }
    1082 }
    1083 
    1084 
    1085 void
    1086 ColumnListView::MouseDown(BPoint point)
    1087 {
    1088     int prevColumn = fSelectedColumn;
    1089     int32 columnCount = fColumnDisplayList.CountItems();
    1090     float xleft = point.x;
    1091     for (int32 i = 0; i < columnCount; i++) {
    1092         CLVColumn* column = (CLVColumn*)fColumnDisplayList.ItemAt(i);
    1093         if (column->IsShown()) {
    1094             if (xleft > 0) {
    1095                 xleft -= column->Width();
    1096                 if (xleft <= 0) {
    1097                     SetSelectedColumnIndex(GetActualIndexOf(i));
    1098                     break;
    1099                 }
    1100             }
    1101         }
    1102     }
    1103 
    1104     int32 itemIndex = IndexOf(point);
    1105     if (itemIndex >= 0) {
    1106         CLVListItem* clickedItem = (CLVListItem*)BListView::ItemAt(itemIndex);
    1107         if (clickedItem->fIsSuperItem) {
    1108             if (clickedItem->fExpanderButtonRect.Contains(point)) {
    1109                 if (clickedItem->IsExpanded())
    1110                     Collapse(clickedItem);
    1111                 else
    1112                     Expand(clickedItem);
    1113 
    1114                 return;
    1115             }
    1116         }
    1117     }
    1118 
    1119 
    1120     // if secondary mouse click, hoist up the popup-menu
    1121     const char* selectedText = NULL;
    1122     CLVColumn* column = ColumnAt(fSelectedColumn);
    1123     if (column != NULL) {
    1124         BPopUpMenu* popup = column->GetPopup();
    1125         if (popup != NULL) {
    1126             BMessage* message = Window()->CurrentMessage();
    1127             int32 buttons;
    1128             if ((message->FindInt32("buttons", &buttons) == B_NO_ERROR)
    1129                 && (buttons == B_SECONDARY_MOUSE_BUTTON)) {
    1130                 BPoint where(point);
    1131                 Select(IndexOf(where));
    1132                 ConvertToScreen(&where);
    1133                 BMenuItem* result = popup->Go(where, false);
    1134                 if (result != NULL)
    1135                     selectedText = result->Label();
    1136             }
    1137         }
    1138     }
    1139 
    1140     int32 previousRow = CurrentSelection();
    1141     BListView::MouseDown(point);
    1142 
    1143     int32 currentRow = CurrentSelection();
    1144     if ((fEditMessage != NULL) && (selectedText != NULL
    1145         || (fSelectedColumn == prevColumn && currentRow == previousRow))) {
    1146         // send mouse message...
    1147         BMessage temp(*fEditMessage);
    1148         temp.AddInt32("column", fSelectedColumn);
    1149         temp.AddInt32("row", CurrentSelection());
    1150         if (selectedText)
    1151             temp.AddString("text", selectedText);
    1152         else
    1153             temp.AddInt32("mouseClick", 0);
    1154 
    1155         fEditTarget.SendMessage(&temp);
    1156     }
    1157 }
    1158 
    1159 
    1160 bool
    1161 ColumnListView::AddUnder(CLVListItem* item, CLVListItem* superitem)
    1162 {
    1163     if (!fHierarchical)
    1164         return false;
    1165 
    1166     // find the superitem in the full list and display list (if shown)
    1167     int32 superItemPosition = fFullItemList.IndexOf(superitem);
    1168     if (superItemPosition < 0)
    1169         return false;
    1170 
    1171     uint32 SuperitemLevel = superitem->fOutlineLevel;
    1172 
    1173     // add the item under the superitem in the full list
    1174     int32 itemPosition = superItemPosition + 1;
    1175     item->fOutlineLevel = SuperitemLevel + 1;
    1176     while (true) {
    1177         CLVListItem* temp = (CLVListItem*)fFullItemList.ItemAt(itemPosition);
    1178         if (temp) {
    1179             if (temp->fOutlineLevel > SuperitemLevel)
    1180                 itemPosition++;
    1181             else
    1182                 break;
    1183         }
    1184         else
    1185             break;
    1186     }
    1187 
    1188     return AddItemPrivate(item, itemPosition);
    1189 }
    1190 
    1191 
    1192 bool
    1193 ColumnListView::AddItem(CLVListItem* item, int32 fullListIndex)
    1194 {
    1195     return AddItemPrivate(item, fullListIndex);
    1196 }
    1197 
    1198 
    1199 bool
    1200 ColumnListView::AddItem(CLVListItem* item)
    1201 {
    1202     if (fHierarchical)
    1203         return AddItemPrivate(item, fFullItemList.CountItems());
    1204     else
    1205         return AddItemPrivate(item, CountItems());
    1206 }
    1207 
    1208 
    1209 bool
    1210 ColumnListView::AddItem(BListItem* item, int32 fullListIndex)
    1211 {
    1212     return BListView::AddItem(item, fullListIndex);
    1213 }
    1214 
    1215 
    1216 bool
    1217 ColumnListView::AddItem(BListItem* item)
    1218 {
    1219     return BListView::AddItem(item);
    1220 }
    1221 
    1222 
    1223 bool
    1224 ColumnListView::AddItemPrivate(CLVListItem* item, int32 fullListIndex)
    1225 {
    1226     item->fSelectedColumn = fSelectedColumn;
    1227 
    1228     if (fHierarchical) {
    1229         uint32 itemLevel = item->OutlineLevel();
    1230 
    1231         // figure out whether it is visible (should it be added to visible list)
    1232         bool isVisible = true;
    1233 
    1234         // find the item that contains it in the full list
    1235         int32 superItemPosition;
    1236         if (itemLevel == 0)
    1237             superItemPosition = -1;
    1238         else
    1239             superItemPosition = fullListIndex - 1;
    1240 
    1241         CLVListItem* superItem;
    1242         while (superItemPosition >= 0) {
    1243             superItem = (CLVListItem*)fFullItemList.ItemAt(superItemPosition);
    1244             if (superItem != NULL) {
    1245                 if (superItem->fOutlineLevel >= itemLevel)
    1246                     superItemPosition--;
    1247                 else
    1248                     break;
    1249             } else
    1250                 return false;
    1251         }
    1252 
    1253         if (superItemPosition >= 0 && superItem != NULL) {
    1254             if (!superItem->IsExpanded()) {
    1255                 // superItem's contents aren't visible
    1256                 isVisible = false;
    1257             }
    1258             if (!HasItem(superItem)) {
    1259                 // superItem itself isn't showing
    1260                 isVisible = false;
    1261             }
    1262         }
    1263 
    1264         // add the item to the full list
    1265         if (!fFullItemList.AddItem(item, fullListIndex))
    1266             return false;
    1267         else {
    1268             // add the item to the display list
    1269             if (isVisible) {
    1270                 // find the previous item, or -1 if the item I'm adding
    1271                 // will be the first one
    1272                 int32 PreviousitemPosition = fullListIndex - 1;
    1273                 CLVListItem* previousItem;
    1274                 while (PreviousitemPosition >= 0) {
    1275                     previousItem
    1276                         = (CLVListItem*)fFullItemList.ItemAt(
    1277                             PreviousitemPosition);
    1278                     if (previousItem != NULL && HasItem(previousItem))
    1279                         break;
    1280                     else
    1281                         PreviousitemPosition--;
    1282                 }
    1283 
    1284                 // add the item after the previous item, or first on the list
    1285                 bool itemAdded;
    1286                 if (PreviousitemPosition >= 0)
    1287                     itemAdded = BListView::AddItem((BListItem*)item,
    1288                         IndexOf(previousItem) + 1);
    1289                 else
    1290                     itemAdded = BListView::AddItem((BListItem*)item, 0);
    1291 
    1292                 if (itemAdded == false)
    1293                     fFullItemList.RemoveItem(item);
    1294 
    1295                 return itemAdded;
    1296             }
    1297 
    1298             return true;
    1299         }
    1300     } else
    1301         return BListView::AddItem(item, fullListIndex);
    1302 }
    1303 
    1304 
    1305 bool
    1306 ColumnListView::AddList(BList* newItems)
    1307 {
    1308     if (fHierarchical)
    1309         return AddListPrivate(newItems, fFullItemList.CountItems());
    1310     else
    1311         return AddListPrivate(newItems, CountItems());
    1312 }
    1313 
    1314 
    1315 bool
    1316 ColumnListView::AddList(BList* newItems, int32 fullListIndex)
    1317 {
    1318     return AddListPrivate(newItems, fullListIndex);
    1319 }
    1320 
    1321 
    1322 bool
    1323 ColumnListView::AddListPrivate(BList* newItems, int32 fullListIndex)
    1324 {
    1325     int32 itemCount = newItems->CountItems();
    1326     for (int32 count = 0; count < itemCount; count++) {
    1327         if (!AddItemPrivate((CLVListItem*)newItems->ItemAt(count),
    1328                 fullListIndex + count)) {
    1329             return false;
    1330         }
    1331     }
    1332 
    1333     return true;
    1334 }
    1335 
    1336 
    1337 bool
    1338 ColumnListView::RemoveItem(CLVListItem* item)
    1339 {
    1340     if (item == NULL || !fFullItemList.HasItem(item))
    1341         return false;
    1342 
    1343     if (fHierarchical) {
    1344         int32 itemsToRemove = 1 + FullListNumberOfSubitems(item);
    1345         return RemoveItems(fFullItemList.IndexOf(item), itemsToRemove);
    1346     } else
    1347         return BListView::RemoveItem((BListItem*)item);
    1348 }
    1349 
    1350 
    1351 BListItem*
    1352 ColumnListView::RemoveItem(int32 fullListIndex)
    1353 {
    1354     if (fHierarchical) {
    1355         CLVListItem* item = (CLVListItem*)fFullItemList.ItemAt(fullListIndex);
    1356         if (item)
    1357         {
    1358             int32 itemsToRemove = 1 + FullListNumberOfSubitems(item);
    1359             if (RemoveItems(fullListIndex, itemsToRemove))
    1360                 return item;
    1361             else
    1362                 return NULL;
    1363         }
    1364         else
    1365             return NULL;
    1366     } else
    1367         return BListView::RemoveItem(fullListIndex);
    1368 }
    1369 
    1370 
    1371 bool
    1372 ColumnListView::RemoveItems(int32 fullListIndex, int32 count)
    1373 {
    1374     CLVListItem* item;
    1375     if (fHierarchical) {
    1376         uint32 LastSuperitemLevel = UINT32_MAX;
    1377         int32 i;
    1378         int32 DisplayitemsToRemove = 0;
    1379         int32 firstDisplayItemToRemove = -1;
    1380 
    1381         for (i = fullListIndex; i < fullListIndex + count; i++) {
    1382             item = FullListItemAt(i);
    1383             if (item->fOutlineLevel < LastSuperitemLevel)
    1384                 LastSuperitemLevel = item->fOutlineLevel;
    1385 
    1386             if (BListView::HasItem((BListItem*)item)) {
    1387                 DisplayitemsToRemove++;
    1388                 if (firstDisplayItemToRemove == -1)
    1389                     firstDisplayItemToRemove = BListView::IndexOf(item);
    1390             }
    1391         }
    1392 
    1393         while (true) {
    1394             item = FullListItemAt(i);
    1395             if (item != NULL && item->fOutlineLevel > LastSuperitemLevel) {
    1396                 count++;
    1397                 i++;
    1398                 if (BListView::HasItem((BListItem*)item)) {
    1399                     DisplayitemsToRemove++;
    1400                     if (firstDisplayItemToRemove == -1) {
    1401                         firstDisplayItemToRemove
    1402                             = BListView::IndexOf((BListItem*)item);
    1403                     }
    1404                 }
    1405             } else
    1406                 break;
    1407         }
    1408 
    1409         while (DisplayitemsToRemove > 0) {
    1410             if (BListView::RemoveItem(firstDisplayItemToRemove) == NULL)
    1411                 return false;
    1412 
    1413             DisplayitemsToRemove--;
    1414         }
    1415 
    1416         return fFullItemList.RemoveItems(fullListIndex, count);
    1417     } else
    1418         return BListView::RemoveItems(fullListIndex, count);
    1419 }
    1420 
    1421 
    1422 bool
    1423 ColumnListView::RemoveItem(BListItem* item)
    1424 {
    1425     return BListView::RemoveItem(item);
    1426 }
    1427 
    1428 
    1429 CLVListItem*
    1430 ColumnListView::FullListItemAt(int32 fullListIndex) const
    1431 {
    1432     return (CLVListItem*)fFullItemList.ItemAt(fullListIndex);
    1433 }
    1434 
    1435 
    1436 int32
    1437 ColumnListView::FullListIndexOf(const CLVListItem* item) const
    1438 {
    1439     return fFullItemList.IndexOf((CLVListItem*)item);
    1440 }
    1441 
    1442 
    1443 int32
    1444 ColumnListView::FullListIndexOf(BPoint point) const
    1445 {
    1446     int32 DisplayListIndex = IndexOf(point);
    1447     CLVListItem* item = (CLVListItem*)ItemAt(DisplayListIndex);
    1448 
    1449     return item != NULL ? FullListIndexOf(item) : -1;
    1450 }
    1451 
    1452 
    1453 CLVListItem*
    1454 ColumnListView::FullListFirstItem() const
    1455 {
    1456     return (CLVListItem*)fFullItemList.FirstItem();
    1457 }
    1458 
    1459 
    1460 CLVListItem*
    1461 ColumnListView::FullListLastItem() const
    1462 {
    1463     return (CLVListItem*)fFullItemList.LastItem();
    1464 }
    1465 
    1466 
    1467 bool
    1468 ColumnListView::FullListHasItem(const CLVListItem* item) const
    1469 {
    1470     return fFullItemList.HasItem((CLVListItem*)item);
    1471 }
    1472 
    1473 
    1474 int32
    1475 ColumnListView::FullListCountItems() const
    1476 {
    1477     return fFullItemList.CountItems();
    1478 }
    1479 
    1480 
    1481 void
    1482 ColumnListView::MakeEmpty()
    1483 {
    1484     fFullItemList.MakeEmpty();
    1485     BListView::MakeEmpty();
    1486 }
    1487 
    1488 
    1489 void
    1490 ColumnListView::MakeEmptyPrivate()
    1491 {
    1492     fFullItemList.MakeEmpty();
    1493     BListView::MakeEmpty();
    1494 }
    1495 
    1496 
    1497 bool
    1498 ColumnListView::FullListIsEmpty() const
    1499 {
    1500     return fFullItemList.IsEmpty();
    1501 }
    1502 
    1503 
    1504 int32
    1505 ColumnListView::FullListCurrentSelection(int32 index) const
    1506 {
    1507     return FullListIndexOf((CLVListItem*)ItemAt(CurrentSelection(index)));
    1508 }
    1509 
    1510 
    1511 void
    1512 ColumnListView::FullListDoForEach(bool (*func)(CLVListItem*))
    1513 {
    1514     int32 itemCount = fFullItemList.CountItems();
    1515     for (int32 i = 0; i < itemCount; i++) {
    1516         if (func((CLVListItem*)fFullItemList.ItemAt(i)) == true)
    1517             return;
    1518     }
    1519 }
    1520 
    1521 
    1522 void
    1523 ColumnListView::FullListDoForEach(bool (*func)(CLVListItem*, void*),
    1524     void* arg2)
    1525 {
    1526     int32 itemCount = fFullItemList.CountItems();
    1527     for (int32 i = 0; i < itemCount; i++) {
    1528         if (func((CLVListItem*)fFullItemList.ItemAt(i), arg2) == true)
    1529             return;
    1530     }
    1531 }
    1532 
    1533 
    1534 CLVListItem*
    1535 ColumnListView::Superitem(const CLVListItem* item) const
    1536 {
    1537     int32 superItemPosition;
    1538     uint32 itemLevel = item->fOutlineLevel;
    1539 
    1540     if (itemLevel == 0)
    1541         superItemPosition = -1;
    1542     else
    1543         superItemPosition = fFullItemList.IndexOf((CLVListItem*)item) - 1;
    1544 
    1545     CLVListItem* superItem = NULL;
    1546     while (superItemPosition >= 0) {
    1547         superItem = (CLVListItem*)fFullItemList.ItemAt(superItemPosition);
    1548         if (superItem != NULL) {
    1549             if (superItem->fOutlineLevel >= itemLevel)
    1550                 superItemPosition--;
    1551             else
    1552                 break;
    1553         } else
    1554             return NULL;
    1555     }
    1556 
    1557     return superItemPosition >= 0 ? superItem : NULL;
    1558 }
    1559 
    1560 
    1561 int32
    1562 ColumnListView::FullListNumberOfSubitems(const CLVListItem* item) const
    1563 {
    1564     if (!fHierarchical)
    1565         return 0;
    1566 
    1567     int32 itemPosition = FullListIndexOf(item);
    1568     int32 subitemPosition;
    1569     uint32 SuperitemLevel = item->fOutlineLevel;
    1570     if (itemPosition >= 0) {
    1571         for (subitemPosition = itemPosition + 1; subitemPosition >= 1;
    1572             subitemPosition++) {
    1573             CLVListItem* item = FullListItemAt(subitemPosition);
    1574             if (item == NULL || item->fOutlineLevel <= SuperitemLevel)
    1575                 break;
    1576         }
    1577     } else
    1578         return 0;
    1579 
    1580     return subitemPosition - itemPosition - 1;
    1581 }
    1582 
    1583 
    1584 void
    1585 ColumnListView::Expand(CLVListItem* item)
    1586 {
    1587     BWindow* parentWindow = Window();
    1588     if (parentWindow != NULL)
    1589         parentWindow->Lock();
    1590 
    1591     if (!item->fIsSuperItem)
    1592         item->fIsSuperItem = true;
    1593 
    1594     if (item->IsExpanded()) {
    1595         if (parentWindow != NULL)
    1596             parentWindow->Unlock();
    1597 
    1598         return;
    1599     }
    1600 
    1601     item->SetExpanded(true);
    1602     if (!fHierarchical) {
    1603         if (parentWindow != NULL)
    1604             parentWindow->Unlock();
    1605 
    1606         return;
    1607     }
    1608 
    1609     int32 displayIndex = IndexOf(item);
    1610     if (displayIndex >= 0) {
    1611         if (fExpanderColumn >= 0) {
    1612             // change the state of the arrow
    1613             item->DrawItemColumn(this, item->fExpanderColumnRect,
    1614                 fExpanderColumn, (fExpanderColumn == fSelectedColumn), true);
    1615             SetDrawingMode(B_OP_OVER);
    1616             DrawBitmap(&fDownArrow, BRect(0.0, 0.0,
    1617                 item->fExpanderButtonRect.right -
    1618                     item->fExpanderButtonRect.left, 10.0),
    1619                 item->fExpanderButtonRect);
    1620             SetDrawingMode(B_OP_COPY);
    1621         }
    1622 
    1623         // add the items under it
    1624         int32 fullListIndex = fFullItemList.IndexOf(item);
    1625         uint32 itemLevel = item->fOutlineLevel;
    1626         int32 i = fullListIndex + 1;
    1627         int32 addPosition = displayIndex + 1;
    1628         while (true) {
    1629             CLVListItem* nextItem = (CLVListItem*)fFullItemList.ItemAt(i);
    1630             if (nextItem == NULL)
    1631                 break;
    1632 
    1633             if (nextItem->fOutlineLevel > itemLevel) {
    1634                 BListView::AddItem((BListItem*)nextItem, addPosition++);
    1635                 if (nextItem->fIsSuperItem && !nextItem->IsExpanded()) {
    1636                     // the item I just added is collapsed, so skip over all
    1637                     // its children
    1638                     uint32 SkipLevel = nextItem->fOutlineLevel + 1;
    1639                     while (true) {
    1640                         i++;
    1641                         nextItem = (CLVListItem*)fFullItemList.ItemAt(i);
    1642                         if (nextItem == NULL)
    1643                             break;
    1644 
    1645                         if (nextItem->fOutlineLevel < SkipLevel)
    1646                             break;
    1647                     }
    1648                 } else
    1649                     i++;
    1650             } else
    1651                 break;
    1652         }
    1653     }
    1654 
    1655     if (parentWindow != NULL)
    1656         parentWindow->Unlock();
    1657 }
    1658 
    1659 
    1660 void
    1661 ColumnListView::Collapse(CLVListItem* item)
    1662 {
    1663     BWindow* parentWindow = Window();
    1664     if (parentWindow != NULL)
    1665         parentWindow->Lock();
    1666 
    1667     if (!item->fIsSuperItem)
    1668         item->fIsSuperItem = true;
    1669 
    1670     if (!(item->IsExpanded())) {
    1671         if (parentWindow != NULL)
    1672             parentWindow->Unlock();
    1673 
    1674         return;
    1675     }
    1676 
    1677     item->SetExpanded(false);
    1678     if (!fHierarchical) {
    1679         if (parentWindow != NULL)
    1680             parentWindow->Unlock();
    1681         return;
    1682     }
    1683 
    1684     int32 displayIndex = IndexOf((BListItem*)item);
    1685     if (displayIndex >= 0) {
    1686         if (fExpanderColumn >= 0) {
    1687             // change the state of the arrow
    1688             item->DrawItemColumn(this, item->fExpanderColumnRect,
    1689                 fExpanderColumn, (fExpanderColumn == fSelectedColumn), true);
    1690             SetDrawingMode(B_OP_OVER);
    1691             DrawBitmap(&fRightArrow, BRect(0.0, 0.0,
    1692                 item->fExpanderButtonRect.right -
    1693                     item->fExpanderButtonRect.left,
    1694                 10.0), item->fExpanderButtonRect);
    1695             SetDrawingMode(B_OP_COPY);
    1696         }
    1697 
    1698         // remove the items under it
    1699         uint32 itemLevel = item->fOutlineLevel;
    1700         int32 nextItemIndex = displayIndex + 1;
    1701         while (true) {
    1702             CLVListItem* nextItem = (CLVListItem*)ItemAt(nextItemIndex);
    1703             if (nextItem != NULL) {
    1704                 if (nextItem->fOutlineLevel > itemLevel)
    1705                     BListView::RemoveItem(nextItemIndex);
    1706                 else
    1707                     break;
    1708             } else
    1709                 break;
    1710         }
    1711     }
    1712 
    1713     if (parentWindow != NULL)
    1714         parentWindow->Unlock();
    1715 }
    1716 
    1717 
    1718 bool
    1719 ColumnListView::IsExpanded(int32 fullListIndex) const
    1720 {
    1721     BListItem* item = (BListItem*)fFullItemList.ItemAt(fullListIndex);
    1722     return item != NULL ? item->IsExpanded() : false;
    1723 }
    1724 
    1725 
    1726 void
    1727 ColumnListView::SetSortFunction(CLVCompareFuncPtr compare)
    1728 {
    1729     fCompareFunction = compare;
    1730 }
    1731 
    1732 
    1733 void
    1734 ColumnListView::SortItems()
    1735 {
    1736     BWindow* parentWindow = Window();
    1737     if (parentWindow != NULL)
    1738         parentWindow->Lock();
    1739 
    1740     BList newList;
    1741     int32 itemCount;
    1742     if (!fHierarchical)
    1743         itemCount = CountItems();
    1744     else
    1745         itemCount = fFullItemList.CountItems();
    1746 
    1747     if (itemCount == 0) {
    1748         if (parentWindow != NULL)
    1749             parentWindow->Unlock();
    1750 
    1751         return;
    1752     }
    1753 
    1754     int32 i;
    1755     if (!fHierarchical) {
    1756         // plain sort, remember the list context for each item
    1757         for (i = 0; i < itemCount; i++)
    1758             ((CLVListItem*)ItemAt(i))->fSortingContextCLV = this;
    1759         // do the actual sort
    1760         BListView::SortItems((int (*)(const void*,
    1761             const void*))ColumnListView::PlainBListSortFunc);
    1762     } else {
    1763         // block-by-block sort
    1764         SortFullListSegment(0, 0, &newList);
    1765         fFullItemList = newList;
    1766         // remember the list context for each item
    1767         for (i = 0; i < itemCount; i++) {
    1768             ((CLVListItem*)fFullItemList.ItemAt(i))->fSortingContextBList
    1769                 = &newList;
    1770         }
    1771         // do the actual sort
    1772         BListView::SortItems((int (*)(const void*,
    1773             const void*))ColumnListView::HierarchicalBListSortFunc);
    1774     }
    1775 
    1776     if (parentWindow != NULL)
    1777         parentWindow->Unlock();
    1778 }
    1779 
    1780 
    1781 int
    1782 ColumnListView::PlainBListSortFunc(BListItem** firstItem,
    1783     BListItem** secondItem)
    1784 {
    1785     CLVListItem* item1 = (CLVListItem*)*firstItem;
    1786     CLVListItem* item2 = (CLVListItem*)*secondItem;
    1787     ColumnListView* sortingContext = item1->fSortingContextCLV;
    1788     int32 sortDepth = sortingContext->fSortKeyList.CountItems();
    1789     int compareResult = 0;
    1790 
    1791     if (sortingContext->fCompareFunction) {
    1792         for (int32 SortIteration = 0;
    1793                 SortIteration < sortDepth && compareResult == 0;
    1794                 SortIteration++) {
    1795             CLVColumn* column = (CLVColumn*)sortingContext->fSortKeyList.ItemAt(
    1796                 SortIteration);
    1797             compareResult = sortingContext->fCompareFunction(item1, item2,
    1798                 sortingContext->fColumnList.IndexOf(column));
    1799             if (column->fSortMode == SORT_MODE_DESCENDING)
    1800                 compareResult = 0 - compareResult;
    1801         }
    1802     }
    1803 
    1804     return compareResult;
    1805 }
    1806 
    1807 
    1808 int
    1809 ColumnListView::HierarchicalBListSortFunc(BListItem** firstItem,
    1810     BListItem** secondItem)
    1811 {
    1812     CLVListItem* item1 = (CLVListItem*)*firstItem;
    1813     CLVListItem* item2 = (CLVListItem*)*secondItem;
    1814     if (item1->fSortingContextBList->IndexOf(item1)
    1815             < item1->fSortingContextBList->IndexOf(item2)) {
    1816         return -1;
    1817     } else
    1818         return 1;
    1819 }
    1820 
    1821 
    1822 void
    1823 ColumnListView::SortFullListSegment(int32 originalListStartIndex,
    1824     int32 insertionPoint, BList* newList)
    1825 {
    1826     // identify and sort the items at this level
    1827     BList* itemCount = SortItemCount(originalListStartIndex);
    1828     int32 newItemsStopIndex = insertionPoint + itemCount->CountItems();
    1829     newList->AddList(itemCount, insertionPoint);
    1830     delete itemCount;
    1831 
    1832     // identify and sort the subitems
    1833     for (int32 i = insertionPoint; i < newItemsStopIndex; i++) {
    1834         CLVListItem* item = (CLVListItem*)newList->ItemAt(i);
    1835         CLVListItem* nextItem = (CLVListItem*)fFullItemList.ItemAt(
    1836             fFullItemList.IndexOf(item) + 1);
    1837         if (item->fIsSuperItem && nextItem != NULL
    1838             && item->fOutlineLevel < nextItem->fOutlineLevel) {
    1839             int32 OldListSize = newList->CountItems();
    1840             SortFullListSegment(fFullItemList.IndexOf(item) + 1,
    1841                 i + 1, newList);
    1842             int32 newListSize = newList->CountItems();
    1843             newItemsStopIndex += newListSize - OldListSize;
    1844             i += newListSize - OldListSize;
    1845         }
    1846     }
    1847 }
    1848 
    1849 
    1850 BList*
    1851 ColumnListView::SortItemCount(int32 originalListStartIndex)
    1852 {
    1853     uint32 level = ((CLVListItem*)fFullItemList.ItemAt(
    1854         originalListStartIndex))->fOutlineLevel;
    1855 
    1856     // create a new BList of the items in this level
    1857     int32 i = originalListStartIndex;
    1858     int32 itemCount = 0;
    1859     BList* itemsList = new BList(16);
    1860     while (true) {
    1861         CLVListItem* item = (CLVListItem*)fFullItemList.ItemAt(i);
    1862         if (item == NULL)
    1863             break;
    1864 
    1865         uint32 itemLevel = item->fOutlineLevel;
    1866         if (itemLevel == level) {
    1867             itemsList->AddItem(item);
    1868             itemCount++;
    1869         } else if (itemLevel < level)
    1870             break;
    1871 
    1872         i++;
    1873     }
    1874 
    1875     // sort the BList of the items in this level
    1876     CLVListItem** sortArray = new CLVListItem*[itemCount];
    1877     CLVListItem** levelListItems = (CLVListItem**)itemsList->Items();
    1878     for (i = 0; i < itemCount; i++)
    1879         sortArray[i] = levelListItems[i];
    1880 
    1881     itemsList->MakeEmpty();
    1882     SortListArray(sortArray, itemCount);
    1883     for (i = 0; i < itemCount; i++)
    1884         itemsList->AddItem(sortArray[i]);
    1885 
    1886     delete[] sortArray;
    1887 
    1888     return itemsList;
    1889 }
    1890 
    1891 
    1892 void
    1893 ColumnListView::SortListArray(CLVListItem** sortArray, int32 itemCount)
    1894 {
    1895     int32 sortDepth = fSortKeyList.CountItems();
    1896     for (int32 i = 0; i < itemCount - 1; i++) {
    1897         for (int32 j = i + 1; j < itemCount; j++) {
    1898             int compareResult = 0;
    1899             if (fCompareFunction) {
    1900                 for (int32 SortIteration = 0;
    1901                     SortIteration < sortDepth && compareResult == 0;
    1902                     SortIteration++) {
    1903                     CLVColumn* Column = (CLVColumn*)fSortKeyList.ItemAt(
    1904                         SortIteration);
    1905                     compareResult = fCompareFunction(sortArray[i],
    1906                         sortArray[j], fColumnList.IndexOf(Column));
    1907                     if (Column->fSortMode == SORT_MODE_DESCENDING)
    1908                         compareResult = 0 - compareResult;
    1909                 }
    1910             }
    1911 
    1912             if (compareResult == 1) {
    1913                 CLVListItem* Temp = sortArray[i];
    1914                 sortArray[i] = sortArray[j];
    1915                 sortArray[j] = Temp;
    1916             }
    1917         }
    1918     }
    1919 }
    1920 
    1921 
    1922 void
    1923 ColumnListView::MessageReceived(BMessage* message)
    1924 {
    1925     switch(message->what) {
    1926         case B_UNMAPPED_KEY_DOWN:
    1927             if (fEditMessage != NULL) {
    1928                 BMessage temp(*fEditMessage);
    1929                 temp.AddInt32("column", fSelectedColumn);
    1930                 temp.AddInt32("row", CurrentSelection());
    1931 
    1932                 int32 key;
    1933                 if (message->FindInt32("key", &key) == B_NO_ERROR)
    1934                     temp.AddInt32("unmappedkey", key);
    1935                 fEditTarget.SendMessage(&temp);
    1936             }
    1937             break;
    1938 
    1939         default:
    1940             BListView::MessageReceived(message);
    1941     }
    1942 }
  • deleted file src/preferences/shortcuts/clv/ColumnListView.h

    diff --git a/src/preferences/shortcuts/clv/ColumnListView.h b/src/preferences/shortcuts/clv/ColumnListView.h
    deleted file mode 100644
    index 4392e79..0000000
    + -  
    1 /*
    2  * Copyright 1999-2009 Jeremy Friesner
    3  * Copyright 2009-2014 Haiku, Inc. All rights reserved.
    4  * Distributed under the terms of the MIT License.
    5  *
    6  * Authors:
    7  *      Jeremy Friesner
    8  *      John Scipione, jscipione@gmail.com
    9  */
    10 #ifndef COLUMN_LIST_VIEW_H
    11 #define COLUMN_LIST_VIEW_H
    12 
    13 
    14 #include <ListView.h>
    15 
    16 #include "Colors.h"
    17 #include "CLVColumn.h"
    18 #include "PrefilledBitmap.h"
    19 #include "ScrollViewCorner.h"
    20 
    21 
    22 class CLVListItem;
    23 class CLVColumnLabelView;
    24 class CLVFillerView;
    25 class CLVContainerView;
    26 
    27 
    28 typedef int (*CLVCompareFuncPtr)(const CLVListItem* item1,
    29     const CLVListItem* item2, int32 sort_key);
    30 
    31 
    32 class ColumnListView : public BListView {
    33 public:
    34                                 ColumnListView(BRect frame,
    35                                     BScrollView** containerView,
    36     // Used to get back a pointer to the container
    37     // view that will hold the ColumnListView, the
    38     // the CLVColumnLabelView, and the scrollbars.
    39     // If no scroll bars or border are asked for,
    40     // this will act like a plain BView container.
    41                                     const char* name = NULL,
    42                                     uint32 resizingMode
    43                                         = B_FOLLOW_LEFT | B_FOLLOW_TOP,
    44                                     uint32 flags
    45                                         = B_WILL_DRAW | B_FRAME_EVENTS
    46                                             | B_NAVIGABLE,
    47                                     list_view_type type
    48                                         = B_SINGLE_SELECTION_LIST,
    49                                     bool hierarchical = false,
    50                                     bool horizontal = true,
    51     // which scroll bars should I add, if any
    52                                     bool vertical = true,
    53                                     border_style border = B_NO_BORDER,
    54     // what type of border to add, if any
    55                                     const BFont* labelFont = be_plain_font);
    56 
    57     virtual                         ~ColumnListView();
    58 
    59             void                    AddScrollViewCorner();
    60 
    61     //Archival stuff
    62     /*** Not implemented yet
    63                                     ColumnListView(BMessage* archive);
    64     static                          ColumnListView* Instantiate(BMessage* data);
    65     virtual status_t                Archive(BMessage* data, bool deep = true)
    66                                         const;
    67     ***/
    68 
    69     virtual void                    MessageReceived(BMessage* message);
    70 
    71         // column setup functions
    72     virtual bool                    AddColumn(CLVColumn* column);
    73         // Note that a column may only be added to
    74         // one ColumnListView at a time, and may not
    75         // be added more than once to the same
    76         // ColumnListView without removing it
    77         // inbetween
    78     virtual bool                    AddColumnList(BList* newColumns);
    79     virtual bool                    RemoveColumn(CLVColumn* column);
    80     virtual bool                    RemoveColumns(CLVColumn* column,
    81                                         int32 Count);
    82         // Finds Column in ColumnList and removes Count columns and
    83         // their data from the view and its items
    84             int32                   CountColumns() const;
    85             int32                   IndexOfColumn(CLVColumn* column) const;
    86         CLVColumn*              ColumnAt(BPoint point) const;
    87         // Returns column located at point on screen --added by jaf
    88             CLVColumn*              ColumnAt(int32 columnIndex) const;
    89     virtual bool                    SetDisplayOrder(const int32* order);
    90         // Sets the display order: each int32 in the Order list specifies
    91         // the column index of the next column to display.  Note that this
    92         // DOES NOT get called if the user drags a column, so overriding
    93         // it will not inform you of user changes. If you need that info,
    94         // override DisplayOrderChanged instead. Also note that
    95         // SetDisplayOrder does call DisplayOrderChanged(false).
    96     virtual void                    ColumnWidthChanged(int32 columnIndex,
    97                                         float newWidth);
    98     virtual void                    DisplayOrderChanged(const int32* order);
    99         // Override this if you want to find out when the display order changed.
    100             int32*                  DisplayOrder() const;
    101         // Gets the display order in the same format as that used by
    102         // SetDisplayOrder. The returned array belongs to the caller and
    103         // must be delete[]'d when done with it.
    104     virtual void                    SetSortKey(int32 columnIndex);
    105         // Set it to -1 to remove the sort key.
    106     virtual void                    AddSortKey(int32 columnIndex);
    107             void                    ReverseSortMode(int32 columnIndex);
    108     virtual void                    SetSortMode(int32 columnIndex,
    109                                         CLVSortMode Mode);
    110             int32                   Sorting(int32* SortKeys,
    111                                         CLVSortMode* SortModes) const;
    112         // Returns the number of used sort keys, and fills the provided
    113         // arrays with the sort keys by column index and sort modes,
    114         // in priority order.  The pointers should point to an array
    115         // int32 SortKeys[n], and an array CLVSortMode SortModes[n] where
    116         // n is the number of sortable columns in the ColumnListView.
    117         // Note: sorting will only occur if the key column is shown.
    118             void                    SetSorting(int32 NumberOfKeys,
    119                                         int32* SortKeys,
    120                                         CLVSortMode* SortModes);
    121         // Sets the sorting parameters using the same format returned by sorting
    122 
    123         // BView overrides
    124     virtual void                    FrameResized(float newWidth,
    125                                         float newHeight);
    126     virtual void                    AttachedToWindow();
    127     virtual void                    ScrollTo(BPoint point);
    128     virtual void                    MouseDown(BPoint point);
    129 
    130         // List functions
    131     virtual bool                    AddUnder(CLVListItem*,
    132                                         CLVListItem* superitem);
    133     virtual bool                    AddItem(CLVListItem*,
    134                                         int32 fullListIndex);
    135     virtual bool                    AddItem(CLVListItem*);
    136     virtual bool                    AddList(BList* newItems);
    137         // This must be a BList of CLVListItem*'s, NOT BListItem*'s
    138     virtual bool                    AddList(BList* newItems,
    139                                         int32 fullListIndex);
    140         //This must be a BList of CLVListItem*'s, NOT BListItem*'s
    141     virtual bool                    AddItem(BListItem*, int32 fullListIndex);
    142         // unhide
    143     virtual bool                    AddItem(BListItem*);
    144         // unhide
    145     virtual bool                    RemoveItem(CLVListItem* item);
    146     virtual BListItem*              RemoveItem(int32 fullListIndex);
    147         // actually returns CLVListItem
    148     virtual bool                    RemoveItems(int32 fullListIndex,
    149                                         int32 count);
    150     virtual bool                    RemoveItem(BListItem* item);
    151         // unhide
    152     virtual void                    MakeEmpty();
    153             CLVListItem*            FullListItemAt(int32 fullListIndex) const;
    154             int32                   FullListIndexOf(const CLVListItem* item)
    155                                         const;
    156             int32                   FullListIndexOf(BPoint point) const;
    157             CLVListItem*            FullListFirstItem() const;
    158             CLVListItem*            FullListLastItem() const;
    159             bool                    FullListHasItem(const CLVListItem* item)
    160                                         const;
    161             int32                   FullListCountItems() const;
    162             bool                    FullListIsEmpty() const;
    163             int32                   FullListCurrentSelection(int32 index = 0)
    164                                         const;
    165             void                    FullListDoForEach(
    166                                         bool (*func)(CLVListItem*));
    167             void                    FullListDoForEach(bool (*func)(
    168                                         CLVListItem*, void*), void* arg2);
    169             CLVListItem*            Superitem(const CLVListItem* item) const;
    170             int32                   FullListNumberOfSubitems(
    171                                         const CLVListItem* item) const;
    172     virtual void                    Expand(CLVListItem* item);
    173     virtual void                    Collapse(CLVListItem* item);
    174             bool                    IsExpanded(int32 fullListIndex) const;
    175             void                    SetSortFunction(CLVCompareFuncPtr compare);
    176             void                    SortItems();
    177 
    178     virtual void                    KeyDown(const char* bytes, int32 numBytes);
    179 
    180             void                    SetEditMessage(BMessage* message,
    181                                         BMessenger target);
    182         // Sets a BMessage that will be sent every time a key is pressed,
    183         // or the mouse is clicked in the active cell. (message) becomes
    184         // property of this ColumnListView.
    185         // Copies of (message) will be sent to (target).
    186 
    187     virtual void                    Pulse();
    188         // Used to make the cursor blink on the string column...
    189 
    190             int32                   GetSelectedColumn() const
    191                                         { return fSelectedColumn; }
    192 
    193     private:
    194         friend class CLVMainView;
    195         friend class CLVColumn;
    196         friend class CLVColumnLabelView;
    197         friend class CLVListItem;
    198 
    199             int32                   GetActualIndexOf(int32 displayIndex) const;
    200         // Returns the "real" index of the given display index,
    201         // or -1 if there is none.
    202 
    203             int32                   GetDisplayIndexOf(int32 actualIndex) const;
    204         // Returns the display index of the given "real" index,
    205         // or -1 if there is none.
    206 
    207             void                    SetSelectedColumnIndex(
    208                                         int32 selectedcolumnIndex);
    209         // Call this to change fSelectedColumn to a new value properly.
    210 
    211             void                    ShiftDragGroup();
    212             void                    UpdateScrollBars();
    213             void                    ColumnsChanged();
    214             void                    CreateContainer(bool horizontal,
    215                                         bool vertical, border_style border,
    216                                         uint32 resizingMode, uint32 flags);
    217             void                    SortListArray(CLVListItem** sortArray,
    218                                         int32 itemCount);
    219             void                    MakeEmptyPrivate();
    220             bool                    AddListPrivate(BList* newItems,
    221                                         int32 fullListIndex);
    222             bool                    AddItemPrivate(CLVListItem* item,
    223                                         int32 fullListIndex);
    224             void                    SortFullListSegment(
    225                                         int32 originalListStartIndex,
    226                                         int32 insertionPoint, BList* newList);
    227             BList*                  SortItemCount(
    228                                         int32 originalListStartIndex);
    229     static  int                     PlainBListSortFunc(BListItem** firstItem,
    230                                         BListItem** secondItem);
    231     static  int                     HierarchicalBListSortFunc(
    232                                         BListItem** firstItem,
    233                                         BListItem** secondItem);
    234 
    235             CLVColumnLabelView*     fColumnLabelView;
    236             CLVContainerView*       fScrollView;
    237             ScrollViewCorner*       fFillerView;
    238             bool                    fHierarchical;
    239             BList                   fColumnList;
    240             BList                   fColumnDisplayList;
    241             float                   fDataWidth;
    242             float                   fDataHeight;
    243             float                   fPageWidth;
    244             float                   fPageHeight;
    245             BList                   fSortKeyList;
    246         // list contains CLVColumn pointers
    247             PrefilledBitmap         fRightArrow;
    248             PrefilledBitmap         fDownArrow;
    249             BList                   fFullItemList;
    250             int32                   fExpanderColumn;
    251             CLVCompareFuncPtr       fCompareFunction;
    252         // added by jaf
    253             int32                   fSelectedColumn;
    254         // actual index of the column that contains the active cell.
    255             BMessage*               fEditMessage;
    256         // if non-NULL, sent on keypress or when active cell is clicked.
    257             BMessenger              fEditTarget;
    258         // target for fEditMessage.
    259 };
    260 
    261 
    262 #endif  // COLUMN_LIST_VIEW_H
  • deleted file src/preferences/shortcuts/clv/MouseWatcher.cpp

    diff --git a/src/preferences/shortcuts/clv/MouseWatcher.cpp b/src/preferences/shortcuts/clv/MouseWatcher.cpp
    deleted file mode 100644
    index 6259895..0000000
    + -  
    1 /*
    2  * Copyright 1999-2009 Jeremy Friesner
    3  * Copyright 2009-2014 Haiku, Inc. All rights reserved.
    4  * Distributed under the terms of the MIT License.
    5  *
    6  * Authors:
    7  *      Jeremy Friesner
    8  *      John Scipione, jscipione@gmail.com
    9  */
    10 
    11 
    12 #include "MouseWatcher.h"
    13 
    14 #include <Messenger.h>
    15 #include <InterfaceKit.h>
    16 
    17 
    18 int32 MouseWatcher(void* data);
    19 
    20 
    21 thread_id
    22 StartMouseWatcher(BView* target)
    23 {
    24     thread_id MouseWatcherThread = spawn_thread(MouseWatcher,
    25         "MouseWatcher", B_NORMAL_PRIORITY, new BMessenger(target));
    26     if (MouseWatcherThread != B_NO_MORE_THREADS
    27         && MouseWatcherThread != B_NO_MEMORY) {
    28         resume_thread(MouseWatcherThread);
    29     }
    30 
    31     return MouseWatcherThread;
    32 }
    33 
    34 
    35 int32
    36 MouseWatcher(void* data)
    37 {
    38     BMessenger* messenger = (BMessenger*)data;
    39     BPoint previousPosition;
    40     uint32 previousbuttons = 0xFFFFFFFF;
    41     bool isFirstCheck = true;
    42     BMessage messageToSend;
    43     messageToSend.AddPoint("where", BPoint(0, 0));
    44     messageToSend.AddInt32("buttons", 0);
    45     messageToSend.AddInt32("modifiers", 0);
    46 
    47     while(true) {
    48         if (!messenger->LockTarget()) {
    49             // window is dead so exit
    50             delete messenger;
    51             return 0;
    52         }
    53         BLooper* looper;
    54         BView* view = (BView*)messenger->Target(&looper);
    55         BPoint where;
    56         uint32 buttons;
    57         view->GetMouse(&where, &buttons, false);
    58         if (isFirstCheck) {
    59             previousPosition = where;
    60             previousbuttons = buttons;
    61             isFirstCheck = false;
    62         }
    63         bool shouldSend = false;
    64         if (buttons != previousbuttons || buttons == 0
    65             || where != previousPosition) {
    66             if (buttons == 0)
    67                 messageToSend.what = MW_MOUSE_UP;
    68             else if (buttons != previousbuttons)
    69                 messageToSend.what = MW_MOUSE_DOWN;
    70             else
    71                 messageToSend.what = MW_MOUSE_MOVED;
    72 
    73             messageToSend.ReplacePoint("where", where);
    74             messageToSend.ReplaceInt32("buttons", buttons);
    75             messageToSend.ReplaceInt32("modifiers", modifiers());
    76             shouldSend = true;
    77         }
    78 
    79         looper->Unlock();
    80         if (shouldSend)
    81             messenger->SendMessage(&messageToSend);
    82 
    83         if (buttons == 0) {
    84             // mouse button was released
    85             delete messenger;
    86             return 0;
    87         }
    88 
    89         snooze(50000);
    90     }
    91 }
  • deleted file src/preferences/shortcuts/clv/MouseWatcher.h

    diff --git a/src/preferences/shortcuts/clv/MouseWatcher.h b/src/preferences/shortcuts/clv/MouseWatcher.h
    deleted file mode 100644
    index 2ad65f5..0000000
    + -  
    1 /*
    2  * Copyright 1999-2009 Jeremy Friesner
    3  * Copyright 2009-2014 Haiku, Inc. All rights reserved.
    4  * Distributed under the terms of the MIT License.
    5  *
    6  * Authors:
    7  *      Jeremy Friesner
    8  *      John Scipione, jscipione@gmail.com
    9  */
    10 #ifndef MOUSE_WATCHER_H
    11 #define MOUSE_WATCHER_H
    12 
    13 
    14 /**** DOCUMENTATION
    15  *
    16  * Once started, MouseWatcher will watch the mouse until the mouse buttons
    17  * are all released, sendin messages to the target BView (TargetView is
    18  * specified as the target handler in the BMessenger used to send the messages.
    19  * The BLooper == window of the target view is determined automatically by the
    20  * BMessenger)
    21  *
    22  * If the mouse moves, a MW_MOUSE_MOVED message is sent.
    23  * If the mouse buttons are changed, but not released, a MW_MOUSE_DOWN
    24  * message is sent.
    25  * If the mouse button(s) are released, a MW_MOUSE_UP message is sent.
    26  *
    27  * These messages will have three data entries:
    28  *
    29  * "where" (B_POINT_TYPE)       - The position of the mouse in TargetView's
    30  *                            coordinate system.
    31  * "buttons" (B_INT32_TYPE) - The mouse buttons.  See BView::GetMouse().
    32  * "modifiers" (B_INT32_TYPE)   - The modifier keys held down at the time.
    33  *                            See modifiers().
    34  *
    35  * Once it is started, you can't stop it, but that shouldn't matter - the user
    36  * will most likely releas the buttons soon, and you can interpret the events
    37  * however you want.
    38  *
    39  * StartMouseWatcher returns a valid thread ID, or it returns an error code:
    40  *  B_NO_MORE_THREADS All thread_id numbers are currently in use.
    41  *  B_NO_MEMORY Not enough memory to allocate the resources for another
    42  *              thread.
    43  */
    44 
    45 
    46 #include <SupportDefs.h>
    47 #include <OS.h>
    48 
    49 
    50 const uint32 MW_MOUSE_DOWN = 'Mw-D';
    51 const uint32 MW_MOUSE_UP = 'Mw-U';
    52 const uint32 MW_MOUSE_MOVED = 'Mw-M';
    53 
    54 
    55 class BView;
    56 
    57 thread_id StartMouseWatcher(BView* target);
    58 
    59 
    60 #endif  // MOUSE_WATCHER_H
  • deleted file src/preferences/shortcuts/clv/PrefilledBitmap.cpp

    diff --git a/src/preferences/shortcuts/clv/PrefilledBitmap.cpp b/src/preferences/shortcuts/clv/PrefilledBitmap.cpp
    deleted file mode 100644
    index 14cc956..0000000
    + -  
    1 /*
    2  * Copyright 1999-2009 Jeremy Friesner
    3  * Copyright 2009-2014 Haiku, Inc. All rights reserved.
    4  * Distributed under the terms of the MIT License.
    5  *
    6  * Authors:
    7  *      Jeremy Friesner
    8  *      John Scipione, jscipione@gmail.com
    9  */
    10 
    11 
    12 #include "PrefilledBitmap.h"
    13 
    14 
    15 PrefilledBitmap::PrefilledBitmap(BRect bounds, color_space space,
    16     const void* data, bool acceptsViews, bool needsContiguousMemory)
    17     :
    18     BBitmap(bounds, space, acceptsViews, needsContiguousMemory)
    19 {
    20     int32 length = ((int32(bounds.right - bounds.left) + 3) / 4) * 4;
    21     length *= int32(bounds.bottom - bounds.top) + 1;
    22     SetBits(data, length, 0, space);
    23 }
    24 
    25 
    26 PrefilledBitmap::~PrefilledBitmap()
    27 {
    28 }
  • deleted file src/preferences/shortcuts/clv/PrefilledBitmap.h

    diff --git a/src/preferences/shortcuts/clv/PrefilledBitmap.h b/src/preferences/shortcuts/clv/PrefilledBitmap.h
    deleted file mode 100644
    index 9284d5d..0000000
    + -  
    1 /*
    2  * Copyright 1999-2009 Jeremy Friesner
    3  * Copyright 2009-2014 Haiku, Inc. All rights reserved.
    4  * Distributed under the terms of the MIT License.
    5  *
    6  * Authors:
    7  *      Jeremy Friesner
    8  *      John Scipione, jscipione@gmail.com
    9  */
    10 #ifndef PREFILLED_BITMAP_H
    11 #define PREFILLED_BITMAP_H
    12 
    13 
    14 #include <interface/Bitmap.h>
    15 
    16 
    17 class PrefilledBitmap : public BBitmap
    18 {
    19 public:
    20                                 PrefilledBitmap(BRect bounds,
    21                                     color_space space, const void* data,
    22                                     bool acceptsViews,
    23                                     bool needsContiguousMemory);
    24     virtual                     ~PrefilledBitmap();
    25 };
    26 
    27 
    28 #endif  // PREFILLED_BITMAP_H
  • deleted file src/preferences/shortcuts/clv/ScrollViewCorner.cpp

    diff --git a/src/preferences/shortcuts/clv/ScrollViewCorner.cpp b/src/preferences/shortcuts/clv/ScrollViewCorner.cpp
    deleted file mode 100644
    index 360ac869d6..0000000
    + -  
    1 /*
    2  * Copyright 1999-2009 Jeremy Friesner
    3  * Copyright 2009-2014 Haiku, Inc. All rights reserved.
    4  * Distributed under the terms of the MIT License.
    5  *
    6  * Authors:
    7  *      Jeremy Friesner
    8  *      John Scipione, jscipione@gmail.com
    9  */
    10 
    11 
    12 #include "Colors.h"
    13 #include "ScrollViewCorner.h"
    14 
    15 #include <InterfaceKit.h>
    16 
    17 
    18 ScrollViewCorner::ScrollViewCorner(float left, float top)
    19     :
    20     BView(BRect(left, top, left + B_V_SCROLL_BAR_WIDTH,
    21         top + B_H_SCROLL_BAR_HEIGHT), NULL,
    22         B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM, B_WILL_DRAW)
    23 {
    24     SetHighColor(BeShadow);
    25     SetViewColor(BeInactiveGrey);
    26 }
    27 
    28 
    29 ScrollViewCorner::~ScrollViewCorner()
    30 {
    31 }
    32 
    33 
    34 void
    35 ScrollViewCorner::Draw(BRect updateRect)
    36 {
    37     if (updateRect.bottom >= B_H_SCROLL_BAR_HEIGHT) {
    38         StrokeLine(BPoint(0.0, B_H_SCROLL_BAR_HEIGHT),
    39             BPoint(B_V_SCROLL_BAR_WIDTH, B_H_SCROLL_BAR_HEIGHT));
    40     }
    41     if (updateRect.right >= B_V_SCROLL_BAR_WIDTH) {
    42         StrokeLine(BPoint(B_V_SCROLL_BAR_WIDTH, 0.0),
    43             BPoint(B_V_SCROLL_BAR_WIDTH, B_H_SCROLL_BAR_HEIGHT - 1.0));
    44     }
    45 }
  • deleted file src/preferences/shortcuts/clv/ScrollViewCorner.h

    diff --git a/src/preferences/shortcuts/clv/ScrollViewCorner.h b/src/preferences/shortcuts/clv/ScrollViewCorner.h
    deleted file mode 100644
    index 39e819b..0000000
    + -  
    1 /*
    2  * Copyright 1999-2009 Jeremy Friesner
    3  * Copyright 2009-2014 Haiku, Inc. All rights reserved.
    4  * Distributed under the terms of the MIT License.
    5  *
    6  * Authors:
    7  *      Jeremy Friesner
    8  *      John Scipione, jscipione@gmail.com
    9  */
    10 #ifndef SCROLL_VIEW_CORNER_H
    11 #define SCROLL_VIEW_CORNER_H
    12 
    13 
    14 /*
    15  * If you have a BScrollView with horizontal and vertical sliders that isn't
    16  * seated to the lower-right corner of a B_DOCUMENT_WINDOW, there's a "hole"
    17  * between the sliders that needs to be filled.  You can use this to fill it.
    18  * In general, it looks best to set the ScrollViewCorner color to
    19  * BeInactiveControlGrey if the vertical BScrollBar is inactive, and the color
    20  * to BeBackgroundGrey if the vertical BScrollBar is active.  Have a look at
    21  * Demo3 of ColumnListView to see what I mean if this is unclear.
    22  */
    23 
    24 
    25 class ScrollViewCorner : public BView
    26 {
    27 public:
    28                                 ScrollViewCorner(float left, float top);
    29     virtual                     ~ScrollViewCorner();
    30 
    31     virtual void                Draw(BRect updateRect);
    32 };
    33 
    34 
    35 #endif  // SCROLL_VIEW_CORNER_H