Ticket #1347: drivessetup_fix.diff

File drivessetup_fix.diff, 46.5 KB (added by jamesu, 17 years ago)

Patch to fix up DriveSetup so that it is usable for mounting volumes & ejecting devices

  • src/preferences/drivesetup/MainWindow.h

     
    77#define MAIN_WINDOW_H
    88
    99    #define MOUNT_MOUNT_ALL_MSG                 'mall'
    10     #define MOUNT_MOUNT_SELECTED_MSG            'msel'
    11     #define UNMOUNT_UNMOUNT_SELECTED_MSG    'usel'
     10    #define MOUNT_TOGGLE_SELECTED_MSG           'msel'
    1211    #define SETUP_FORMAT_MSG                            'sfor'
    1312    #define SETUP_PARTITION_SELECTED_MSG        'spsl'
    1413    #define SETUP_INITIALIZE_MSG                            'sini'
     
    1716    #define RESCAN_IDE_MSG                              'ride'
    1817    #define RESCAN_SCSI_MSG                             'rscs'
    1918
     19    #define PARTITION_SELECTION_CHANGE_MSG                      'pchg'
     20    #define MOUNT_TOGGLE                                'musl'
     21    #define UNMOUNT_UNMOUNT_UNMOUNTMENU_SELECTED_MSG                    'mmsl'
     22
    2023    #include <interface/Window.h>
    2124    #include <storage/DiskDeviceRoster.h>
    2225
     
    2528    class BPartition;
    2629    class BDiskDevice;
    2730    class PartitionListView;
     31    class DiskSystemMenu;
    2832   
    2933    /**
    3034     * The main window of the app.
     
    3539    class MainWindow : public BWindow
    3640    {
    3741        private:
     42            void ScanDevices();
     43            void MountAllVisible();
     44           
     45            void UpdateMenus();
     46
     47            bool DoEject(BDiskDevice *disk);
     48            void DoTest(BPartition *partition);
     49            bool DoToggleMount(BPartition *partition, bool only_mount=false);
     50
     51            void HandlePartition(BMessage *message);
     52            void HandleFormat(BMessage *message);
     53            void HandleInitialize(BMessage *message);
     54
     55            void HandleMenuActions(BMessage *message);
     56            void HandleMenuMounting(BMessage *message);
     57            void HandleSelectionMounting(BMessage *message);
     58
    3859            PosSettings*                fSettings;
    3960            BDiskDeviceRoster       fDDRoster;
    4061            PartitionListView*      fListView;
     62
     63            BMenu*              fMountMenu;
     64            BMenu*              fUnMountMenu;
     65            BMenu*              fSingleMountMenu;
     66
     67            BMenu*              fSetupMenu;
     68            BMenu*              fOptionsMenu;
     69            DiskSystemMenu*         fPartitionMenu;
     70            DiskSystemMenu*         fInitializeMenu;
     71
     72            BMenuItem*          fEjectItem;
     73            BMenuItem*          fTestItem;
     74            BMenuItem*          fFormatItem;
     75
    4176        public:
    4277            MainWindow(BRect frame, PosSettings *fSettings);
    4378           
  • src/preferences/drivesetup/PosSettings.cpp

     
    2121PosSettings::PosSettings()
    2222{
    2323    BPath path;
     24        fWindowFrame.Set(32,64,760,240);
     25
    2426    if (find_directory(B_USER_SETTINGS_DIRECTORY,&path) == B_OK)
    2527    {
    2628        path.Append(kSettingsFile);
    2729        BFile file(path.Path(), B_READ_ONLY);
    28         if (file.InitCheck() != B_OK)
    29             be_app->PostMessage(B_QUIT_REQUESTED);
    30         // Now read in the data
    31         if (file.Read(&fcorner, sizeof(BPoint)) != sizeof(BPoint))
    32             be_app->PostMessage(B_QUIT_REQUESTED);
    33         if (file.Read(&brCorner, sizeof(BPoint)) != sizeof(BPoint))
    34             be_app->PostMessage(B_QUIT_REQUESTED);
     30        if (file.InitCheck())
     31        {
     32            // Now read in the data
     33            if (    file.Read(&fcorner, sizeof(BPoint)) == sizeof(BPoint) &&
     34                file.Read(&brCorner, sizeof(BPoint)) == sizeof(BPoint) )
     35            {
     36                fWindowFrame.left=fcorner.x;
     37                fWindowFrame.top=fcorner.y;
     38                fWindowFrame.right=brCorner.x;
     39                fWindowFrame.bottom=brCorner.y;
     40            }
     41        }
    3542    }
    36     printf("settings file read.\n");
    37     printf("=========================\n");
    38     printf("fcorner read in as ");
    39     fcorner.PrintToStream();
    40     printf("brCorner read in as ");
    41     brCorner.PrintToStream();
    42 
    43     fWindowFrame.left=fcorner.x;
    44     fWindowFrame.top=fcorner.y;
    45     fWindowFrame.right=brCorner.x;
    46     fWindowFrame.bottom=brCorner.y;
    4743   
    4844    //Check to see if the co-ords of the window are in the range of the Screen
    4945    BScreen screen;
    5046        if (screen.Frame().right >= fWindowFrame.right
    5147            && screen.Frame().bottom >= fWindowFrame.bottom)
    5248        return;
     49
    5350    // If they are not, lets just stick the window in the middle
    5451    // of the screen.
    5552
     
    8178    fcorner.y=f.top;
    8279    brCorner.x=f.right;
    8380    brCorner.y=f.bottom;
    84 brCorner.PrintToStream();
    8581}
  • src/preferences/drivesetup/PartitionList.cpp

     
     1/*! \file PartitionList.cpp
     2 *  \brief Code for the PartitionListView class and its relatives.
     3 * 
     4 *  This file contains the code for the PartitionListView, BBitmapStringField,
     5 *  PartitionColumn, PartitionListRow and DiskSystemMenu classes.
     6 *
     7*/
    18#include "PartitionList.h"
     9#include "MainWindow.h"
    210
     11#include <interface/Alert.h>
     12
    313#include <interface/ColumnTypes.h>
     14#include <interface/PopUpMenu.h>
     15#include <interface/MenuItem.h>
     16
    417#include <storage/Path.h>
     18#include <storage/DiskDeviceVisitor.h>
     19#include <storage/DiskSystem.h>
     20#include <storage/DiskDevice.h>
    521
     22#include <storage/Volume.h>
     23#include <storage/VolumeRoster.h>
     24
     25#define kTEXT_MARGIN    8 // also in ColumnListView.cpp
     26
    627extern const char*
    728    SizeAsString(off_t size, char *string);; //FIXME: from MainWindow.cpp
    829
    930
     31const rgb_color kWhite          = { 255, 255, 255, 255 };
     32const rgb_color kNormalColor = {150, 150, 150, 255};
     33const rgb_color kHighlightColor = {100, 100, 0, 255};
     34const rgb_color kSelectionColor = {182, 182, 182, 255};
     35const rgb_color kBorderColor = {99, 154, 206, 255};
     36
     37BBitmapStringField::BBitmapStringField(BBitmap* bitmap, const char *string)
     38    : Inherited(string),
     39    fBitmap(bitmap)
     40{
     41
     42}
     43
     44const BBitmap*
     45BBitmapStringField::Bitmap()
     46{
     47    return fBitmap;
     48}
     49
     50void
     51BBitmapStringField::SetBitmap(BBitmap* bitmap)
     52{
     53    fBitmap = bitmap;
     54}
     55
     56
     57PartitionMenuItem::PartitionMenuItem(const char *label, BMessage *message,
     58                     char shortcut, uint32 modifier,
     59                     BPartition *partition, bool unmount)
     60    : Inherited(label, message, shortcut, modifier),
     61    fPartitionID(partition->ID()),
     62    fUnmount(unmount)
     63{
     64    BPath path;
     65   
     66    // Unmount items should show the mount point, whereas
     67    // Mount items should show the content type & name,
     68    // falling back to the device path if neccesary...
     69
     70    if (fUnmount)
     71    {
     72        partition->GetMountPoint(&path);
     73        SetLabel(path.Path());
     74
     75        // See if this is the boot volume
     76        BVolume volume;
     77        BVolume boot_volume;
     78        if (BVolumeRoster().GetBootVolume(&boot_volume) == B_OK)
     79        {
     80            partition->GetVolume(&volume);
     81            SetEnabled(volume != boot_volume);
     82        }
     83    }
     84    else
     85    {       
     86        char mountname[1024];
     87
     88        const char *real_name = partition->ContentName();
     89        if (real_name)
     90        {
     91            sprintf(mountname, "%s (%s)", partition->ContentType(), partition->ContentName());
     92            real_name = mountname;
     93        }
     94        else
     95        {
     96            // Its path will do
     97            partition->GetPath(&path);
     98            real_name = path.Path();
     99        }
     100
     101        SetLabel(real_name);
     102        SetEnabled(!partition->IsMounted());
     103    }
     104}
     105
     106
     107DiskSystemMenu::DiskSystemMenu( const char *title,
     108                bool partitionSystems,
     109                menu_layout layout = B_ITEMS_IN_COLUMN)
     110    : Inherited(title, layout),
     111      fIteratePartitionSystems(partitionSystems)
     112{
     113}
     114
     115void
     116DiskSystemMenu::UpdateSystems(partition_id id)
     117{
     118    BDiskSystem diskSystem;
     119    BDiskDeviceRoster diskRoster;
     120
     121    RemoveItems(0, CountItems());
     122
     123    diskRoster.RewindDiskSystems();
     124
     125    while(diskRoster.GetNextDiskSystem(&diskSystem) == B_OK)
     126    {
     127        // If we can't initialize it, there's no point in having it
     128        if (!diskSystem.SupportsInitializing())
     129            continue;
     130
     131        if (fIteratePartitionSystems && !diskSystem.IsPartitioningSystem())
     132            continue;
     133
     134        if (!fIteratePartitionSystems && !diskSystem.IsFileSystem())
     135            continue;
     136
     137        BString string;
     138        string << diskSystem.PrettyName() << B_UTF8_ELLIPSIS;
     139
     140        BMessage* msg = new BMessage(fIteratePartitionSystems ? SETUP_PARTITION_SELECTED_MSG : SETUP_INITIALIZE_MSG);
     141        msg->AddString("bdisksystem:name", diskSystem.Name());
     142        AddItem(new BMenuItem(string.String(), msg));
     143    }
     144}
     145
     146
     147PartitionColumn::PartitionColumn(const char* title, float width, float minWidth,
     148        float maxWidth, uint32 truncate, alignment align)
     149    : Inherited(title, width, minWidth, maxWidth, align),
     150    fTruncate(truncate)
     151{
     152    SetWantsEvents(true);
     153}
     154
     155void    PartitionColumn::MouseDown(BColumnListView *parent, BRow *row, BField *field,
     156                       BRect field_rect, BPoint point, uint32 buttons)
     157{
     158    // Only accept right button clicks
     159    BMessage *pmsg = parent->Window()->CurrentMessage();
     160    int32 button = pmsg->FindInt32("buttons");
     161    if (button != B_SECONDARY_MOUSE_BUTTON)
     162        return;
     163
     164    // Now we can show the pop-up menu!
     165    PartitionListView* partition_view = dynamic_cast<PartitionListView*>(parent);
     166    PartitionListRow* partition_row = dynamic_cast<PartitionListRow*>(row);
     167    if (partition_view && partition_row)
     168    {
     169        partition_view->ShowPartitionMenu(point, partition_row->ID());
     170    }
     171}
     172
     173void
     174PartitionColumn::DrawField(BField* field, BRect rect, BView* parent)
     175{
     176    BBitmapStringField *bitmapField = dynamic_cast<BBitmapStringField *>(field);
     177    BStringField *stringField = dynamic_cast<BStringField *>(field);
     178
     179    if (bitmapField)
     180    {
     181        const BBitmap *bitmap = bitmapField->Bitmap();
     182   
     183        if (bitmap != NULL) {
     184            float x = 0.0;
     185            BRect r = bitmap->Bounds();
     186            float y = rect.top + ((rect.Height() - r.Height()) / 2);
     187            float width = 0.0;
     188   
     189            switch (Alignment()) {
     190                default:
     191                case B_ALIGN_LEFT:
     192                case B_ALIGN_CENTER:
     193
     194                    x = rect.left + kTEXT_MARGIN;
     195                    width = rect.right - (x + r.Width()) - (2 * kTEXT_MARGIN);
     196                    r.Set(x+r.Width(),rect.top,rect.right-width,rect.bottom);
     197
     198                    break;
     199   
     200                case B_ALIGN_RIGHT:
     201
     202                    x = rect.right - kTEXT_MARGIN - r.Width();
     203                    width = (x - rect.left - (2 * kTEXT_MARGIN));
     204                    r.Set(rect.left,rect.top,rect.left+width,rect.bottom);
     205
     206                    break;
     207            }
     208
     209            if (width != bitmapField->Width()) {
     210                BString out_string(bitmapField->String());
     211   
     212                parent->TruncateString(&out_string, fTruncate, width + 2);
     213                bitmapField->SetClippedString(out_string.String());
     214                bitmapField->SetWidth(width);
     215            }
     216
     217            // Draw the bitmap
     218
     219            parent->SetDrawingMode(B_OP_ALPHA);
     220            parent->DrawBitmap(bitmap, BPoint(x, y));
     221            parent->SetDrawingMode(B_OP_OVER);
     222
     223            // Now we can draw the string
     224
     225            DrawString(bitmapField->ClippedString(), parent, r);
     226        }
     227    }
     228    else if (stringField)
     229    {
     230        float width = rect.Width() - (2 * kTEXT_MARGIN);
     231   
     232        if (width != stringField->Width()) {
     233            BString out_string(stringField->String());
     234
     235            parent->TruncateString(&out_string, fTruncate, width + 2);
     236            stringField->SetClippedString(out_string.String());
     237            stringField->SetWidth(width);
     238        }
     239        DrawString(stringField->ClippedString(), parent, rect);
     240    }
     241
     242    // Draw a nice vertical line on the end
     243    //parent->StrokeLine(BPoint(rect.right, rect.top), BPoint(rect.right, rect.bottom));
     244}
     245
     246int
     247PartitionColumn::CompareFields(BField* field1, BField* field2)
     248{
     249    return ICompare(((BStringField*)field1)->String(),
     250               (((BStringField*)field2)->String()));
     251}
     252
     253bool
     254PartitionColumn::AcceptsField(const BField *field) const
     255{
     256    return static_cast<bool>(dynamic_cast<const BStringField*>(field));
     257}
     258
     259
    10260PartitionListRow::PartitionListRow(BPartition* partition)
    11261    : Inherited(),
    12262    fPartitionID(partition->ID())
    13263{
    14264    BPath path;
    15265    char size[1024];
     266        BBitmap *icon;
     267    const char *realpath;
    16268
     269    // Device path & associated icon (if applicable)
     270
    17271    partition->GetPath(&path);
     272    if (partition->IsDevice()) // Only show device path for actual devices (so only for /dev/disk/..../raw entries)
     273        realpath = path.Path();
     274    else
     275        realpath = "";
    18276
    19     SetField(new BBitmapField(NULL), 0);
     277#ifdef __HAIKU 
     278    icon = new BBitmap(BRect(0, 0, B_MINI_ICON - 1, B_MINI_ICON - 1), B_RGB32);
     279#else
     280    icon = new BBitmap(BRect(0, 0, B_MINI_ICON - 1, B_MINI_ICON - 1), B_CMAP8);
     281#endif
     282    if (partition->IsDevice() && partition->GetIcon(icon, B_MINI_ICON) == B_OK)
     283        SetField(new BBitmapStringField(icon, realpath), 0);
     284    else
     285    {
     286        SetField(new BBitmapStringField(NULL, realpath), 0);
     287        delete icon;
     288    }
    20289
    21     if (partition->IsDevice()) // Only show device path for actual devices (so only for /dev/disk/..../raw entries)
    22         SetField(new BStringField(path.Path()), 1);
     290    // Partition map style field (doubles as media status)
     291
     292    if (partition->ContainsPartitioningSystem())
     293        SetField(new BStringField(partition->ContentType()), 1);
     294    else if (partition->IsDevice())
     295    {
     296        BDiskDevice *device = partition->Device();
     297        if (device->IsRemovableMedia() && !device->HasMedia())
     298            SetField(new BStringField("no media"), 1);
     299        else if (device->ContainsFileSystem())
     300            SetField(new BStringField("none"), 1);
     301        else
     302            SetField(new BStringField("unreadable"), 1);
     303    }
    23304    else
    24305        SetField(new BStringField(""), 1);
    25306
    26     if (partition->ContainsPartitioningSystem()) {
    27         SetField(new BStringField(partition->ContentType()), 2);
    28     } else {
    29         SetField(new BStringField("n/a"), 2);
    30     }
     307    // Type seems to always be ""...
     308    SetField(new BStringField(partition->Type()), 2);
    31309
    32     // For now, Partition type is always empty (as we do not care)
    33     SetField(new BStringField(""), 3);
     310    // FileSystem & Volume details
    34311
    35312    if (partition->ContainsFileSystem()) {
    36             SetField(new BStringField(partition->ContentType()), 4); // Filesystem
    37             SetField(new BStringField(partition->ContentName()), 5);    // Volume Name
     313            SetField(new BStringField(partition->ContentType()), 3); // Filesystem
     314            SetField(new BStringField(partition->ContentName()), 4);    // Volume Name
    38315    } else {
     316        SetField(new BStringField(""), 3);
    39317        SetField(new BStringField(""), 4);
    40         SetField(new BStringField(""), 5);
    41318    }
     319
     320    // Mount path
    42321   
    43322    if (partition->IsMounted() && partition->GetMountPoint(&path) == B_OK) {
    44         SetField(new BStringField(path.Path()),  6);
     323        SetField(new BStringField(path.Path()),  5);
    45324    } else {
    46         SetField(new BStringField(""), 6);
     325        SetField(new BStringField(""), 5);
    47326    }
    48327
    49     SetField(new BStringField(SizeAsString(partition->Size(), size)), 7);
     328    // Size of device or partition
     329
     330    SetField(new BStringField(SizeAsString(partition->Size(), size)), 6);
    50331}
    51332
     333
    52334PartitionListView::PartitionListView(const BRect& frame)
    53335    : Inherited(frame, "storagelist", B_FOLLOW_ALL, 0, B_PLAIN_BORDER, true)
    54336{
    55     AddColumn(new BBitmapColumn("", 20, 20, 100, B_ALIGN_CENTER), 0);
    56     AddColumn(new BStringColumn("Device", 100, 50, 500, B_TRUNCATE_MIDDLE), 1);
    57     AddColumn(new BStringColumn("Map style", 100, 50, 500, B_TRUNCATE_MIDDLE), 2);
    58     AddColumn(new BStringColumn("Partition Type", 100, 50, 500, B_TRUNCATE_MIDDLE), 3);
    59     AddColumn(new BStringColumn("Filesystem", 100, 50, 500, B_TRUNCATE_MIDDLE), 4);
    60     AddColumn(new BStringColumn("Volume Name", 100, 50, 500, B_TRUNCATE_MIDDLE), 5);
    61     AddColumn(new BStringColumn("Mounted At", 100, 50, 500, B_TRUNCATE_MIDDLE), 6);
    62     AddColumn(new BStringColumn("Size", 100, 50, 500, B_TRUNCATE_END), 7);
     337    // The default font is a smidge too big
     338
     339    BFont font(be_plain_font);
     340    font.SetSize(9);
     341    SetFont(&font);
     342
     343    //SetFont(B_FONT_ROW, &font);
     344    SetFont(B_FONT_HEADER, &font);
     345
     346    // The default colors are pretty much horrific, so lets change them!
     347
     348    SetColor(B_COLOR_ROW_DIVIDER, kWhite);
     349    SetColor(B_COLOR_SEPARATOR_LINE, kBorderColor); // or maybe B_COLOR_SEPARATOR_BORDER
     350    SetColor(B_COLOR_BACKGROUND, kWhite);
     351    SetColor(B_COLOR_SELECTION, kSelectionColor);
     352
     353    // All the column's we'll ever need
     354
     355    AddColumn(new PartitionColumn("Device", 140, 50, 500, B_TRUNCATE_END), 0);
     356    AddColumn(new PartitionColumn("Map style", 70, 50, 500, B_TRUNCATE_END), 1);
     357    AddColumn(new PartitionColumn("Partition Type", 100, 50, 500, B_TRUNCATE_END), 2);
     358    AddColumn(new PartitionColumn("Filesystem", 80, 50, 500, B_TRUNCATE_END), 3);
     359    AddColumn(new PartitionColumn("Volume Name", 140, 50, 500, B_TRUNCATE_END), 4);
     360    AddColumn(new PartitionColumn("Mounted At", 100, 50, 500, B_TRUNCATE_END), 5);
     361    AddColumn(new PartitionColumn("Size", 80, 50, 500, B_TRUNCATE_END, B_ALIGN_RIGHT), 6);
     362
     363    SetSelectionMode(B_SINGLE_SELECTION_LIST);
     364
     365    // Setup PopUp Menu
     366
     367    fPopUpMenu = new BPopUpMenu("Partitions", false, true, B_ITEMS_IN_COLUMN);;
     368
     369    // Setup Mount menu
     370    fMountMenu = new BMenu("Mount");
     371    fPopUpMenu->AddItem(fMountMenu);
     372   
     373    //Setup Unmount menu
     374    fUnMountMenu = new BMenu("Unmount");
     375    fPopUpMenu->AddItem(fUnMountMenu);
     376
     377    fFormatItem = new BMenuItem("Format", new BMessage(SETUP_FORMAT_MSG), 'F');
     378
     379    //Setup Setup menu
     380    fSetupMenu = new BMenu("Setup");
     381        fSetupMenu->AddItem(fFormatItem);
     382        fPartitionMenu = new DiskSystemMenu("Partition", true);
     383        fSetupMenu->AddItem(fPartitionMenu);
     384        fInitializeMenu = new DiskSystemMenu("Initialize", false);
     385        //add menu for formats
     386        fSetupMenu->AddItem(fInitializeMenu);
     387    fPopUpMenu->AddItem(fSetupMenu);
     388   
     389    //Setup Options menu
     390
     391    fEjectItem = new BMenuItem("Eject", new BMessage(OPTIONS_EJECT_MSG), 'E');
     392    fTestItem = new BMenuItem("Surface Test", new BMessage(OPTIONS_SURFACE_TEST_MSG), 'T');
     393
     394    fOptionsMenu = new BMenu("Options");
     395        fOptionsMenu->AddItem(fEjectItem);
     396        fOptionsMenu->AddItem(fTestItem);
     397    fPopUpMenu->AddItem(fOptionsMenu);
    63398}
    64399
     400PartitionListView::~PartitionListView()
     401{
     402    delete fPopUpMenu;
     403}
     404
     405void
     406PartitionListView::UpdatePartitionMenu()
     407{
     408    PartitionListRow* selected_item = dynamic_cast<PartitionListRow*>(CurrentSelection());
     409
     410    // Clean out the old...
     411
     412    fMountMenu->RemoveItems(0, fMountMenu->CountItems());
     413    fUnMountMenu->RemoveItems(0, fUnMountMenu->CountItems());
     414
     415    // Determine the enabled status of the menu's
     416
     417    bool mountVisible = false;
     418    bool unmountVisible = false;
     419    bool setupVisible = false;
     420    bool optionsVisible = false;
     421    bool formatVisible = false;
     422    bool initializeVisible = false;
     423    bool partitionVisible = false;
     424    bool ejectVisible = false;
     425    bool testVisible = false;
     426
     427    PartitionListView::GetMenuStatus(selected_item,
     428              mountVisible,
     429              unmountVisible,
     430              setupVisible,
     431              optionsVisible,
     432              formatVisible,
     433              initializeVisible,
     434              partitionVisible,
     435              ejectVisible,
     436              testVisible);
     437
     438    fMountMenu->SetEnabled(mountVisible);
     439    fUnMountMenu->SetEnabled(unmountVisible);
     440
     441    fSetupMenu->SetEnabled(setupVisible);
     442    fOptionsMenu->SetEnabled(optionsVisible);
     443
     444    fPartitionMenu->SetEnabled(partitionVisible);
     445    fInitializeMenu->SetEnabled(initializeVisible);
     446
     447    fFormatItem->SetEnabled(formatVisible);
     448    fEjectItem->SetEnabled(ejectVisible);
     449    fTestItem->SetEnabled(testVisible);
     450
     451    // Re-populate menu's
     452
     453    PopulateMountMenus(fMountMenu, fUnMountMenu, selected_item);
     454
     455    if (partitionVisible)
     456        fPartitionMenu->UpdateSystems(selected_item ? selected_item->ID() : NULL);
     457    if (initializeVisible)
     458        fInitializeMenu->UpdateSystems(selected_item ? selected_item->ID() : NULL);
     459
     460    // Associate pop-up & items with Window()
     461    BWindow *window = Window();
     462
     463    fMountMenu->SetTargetForItems(window);
     464    fUnMountMenu->SetTargetForItems(window);
     465
     466    fSetupMenu->SetTargetForItems(window);
     467    fOptionsMenu->SetTargetForItems(window);
     468
     469    fPartitionMenu->SetTargetForItems(window);
     470    fInitializeMenu->SetTargetForItems(window);
     471}
     472
     473void
     474PartitionListView::PopulateMountMenus(BMenu* mount, BMenu* unmount, PartitionListRow *current)
     475{
     476    int32 collected = RecursePopulateMountMenus(mount, unmount, current);
     477
     478    if (collected > 1)
     479    {
     480        // More than 1 possible partition to choose from!
     481
     482        mount->AddItem(new BMenuItem("Mount All Partitions", new BMessage(MOUNT_MOUNT_ALL_MSG), 'M'), 0);
     483        mount->AddItem(new BSeparatorItem(), 1);
     484    }
     485    else if (collected == 1)
     486    {
     487        // Only 1 possible partition to choose from
     488        // e.g. when you select a device with no partitions
     489
     490        BMenuItem *item = mount->ItemAt(0);
     491        if (item)
     492            item->SetLabel("Mount");
     493    }
     494}
     495
     496int32
     497PartitionListView::RecursePopulateMountMenus(BMenu* mount, BMenu* unmount, PartitionListRow *current)
     498{
     499    int32 cur_collected = 1;
     500
     501    if (current)
     502    {
     503        PartitionMenuItem *item;
     504        BPartition *partition;
     505        BDiskDevice device;
     506   
     507        if (BDiskDeviceRoster().GetPartitionWithID(current->ID(), &device, &partition) != B_OK)
     508            return cur_collected;
     509   
     510        if (device.IsRemovableMedia() && !device.HasMedia())
     511            return cur_collected;
     512   
     513        if (partition->ContainsFileSystem())
     514        {
     515            if (partition->IsMounted())
     516            {
     517                BMessage *message = new BMessage(MOUNT_TOGGLE);
     518                message->AddInt32("PartitionID", partition->ID());
     519           
     520                item = new PartitionMenuItem("UNKNOWN", message, 0, 0, partition, true);
     521                unmount->AddItem(item);
     522            }
     523       
     524            BMessage *message = new BMessage(MOUNT_TOGGLE);
     525            message->AddInt32("PartitionID", partition->ID());
     526       
     527            item = new PartitionMenuItem("UNKNOWN", message, 0, 0, partition, false);
     528            mount->AddItem(item);
     529        }
     530    }
     531    else
     532    {
     533        cur_collected = 0;
     534    }
     535
     536    for (int32 idx=0; idx < CountRows(current); idx++)
     537    {
     538        // Recurse!
     539        PartitionListRow* row = dynamic_cast<PartitionListRow*>(RowAt(idx, current));
     540        if (row != NULL)
     541            cur_collected += RecursePopulateMountMenus(mount, unmount, row);
     542    }
     543
     544    return cur_collected;
     545}
     546
     547void
     548PartitionListView::DrawLatch(BView *view, BRect rect, LatchType position, BRow *)
     549{
     550    view->SetHighColor(0, 0, 0);
     551
     552    // Center the latch
     553    rect.OffsetBy(((uint32)LatchWidth() - 10) / 2,
     554              ((rect.bottom-rect.top) - 10) / 2);
     555    rect.right = rect.left + 10;
     556    rect.bottom = rect.top + 10;
     557
     558    DrawLatchInState(position, true, view, rect);
     559
     560}
     561
     562void
     563PartitionListView::DrawLatchInState(LatchType state, bool leftAligned, BView *view, const BRect &rect)
     564{
     565    rgb_color outlineColor = {0, 0, 0, 255};
     566    rgb_color middleColor = state == B_PRESSED_LATCH ? kHighlightColor : kNormalColor;
     567
     568    view->SetDrawingMode(B_OP_COPY);
     569
     570    switch (state) {
     571        case B_CLOSED_LATCH:
     572            view->BeginLineArray(6);
     573           
     574            if (leftAligned) {
     575                view->AddLine(BPoint(rect.left + 3, rect.top + 1),
     576                    BPoint(rect.left + 3, rect.bottom - 1), outlineColor);
     577                view->AddLine(BPoint(rect.left + 3, rect.top + 1),
     578                    BPoint(rect.left + 7, rect.top + 5), outlineColor);
     579                view->AddLine(BPoint(rect.left + 7, rect.top + 5),
     580                    BPoint(rect.left + 3, rect.bottom - 1), outlineColor);
     581
     582                view->AddLine(BPoint(rect.left + 4, rect.top + 3),
     583                    BPoint(rect.left + 4, rect.bottom - 3), middleColor);
     584                view->AddLine(BPoint(rect.left + 5, rect.top + 4),
     585                    BPoint(rect.left + 5, rect.bottom - 4), middleColor);
     586                view->AddLine(BPoint(rect.left + 5, rect.top + 5),
     587                    BPoint(rect.left + 6, rect.top + 5), middleColor);
     588            } else {
     589                view->AddLine(BPoint(rect.right - 3, rect.top + 1),
     590                    BPoint(rect.right - 3, rect.bottom - 1), outlineColor);
     591                view->AddLine(BPoint(rect.right - 3, rect.top + 1),
     592                    BPoint(rect.right - 7, rect.top + 5), outlineColor);
     593                view->AddLine(BPoint(rect.right - 7, rect.top + 5),
     594                    BPoint(rect.right - 3, rect.bottom - 1), outlineColor);
     595
     596                view->AddLine(BPoint(rect.right - 4, rect.top + 3),
     597                    BPoint(rect.right - 4, rect.bottom - 3), middleColor);
     598                view->AddLine(BPoint(rect.right - 5, rect.top + 4),
     599                    BPoint(rect.right - 5, rect.bottom - 4), middleColor);
     600                view->AddLine(BPoint(rect.right - 5, rect.top + 5),
     601                    BPoint(rect.right - 6, rect.top + 5), middleColor);
     602            }
     603            view->EndLineArray();
     604            break;
     605
     606        case B_PRESSED_LATCH:
     607            view->BeginLineArray(7);
     608            if (leftAligned) {
     609                view->AddLine(BPoint(rect.left + 1, rect.top + 7),
     610                    BPoint(rect.left + 7, rect.top + 7), outlineColor);
     611                view->AddLine(BPoint(rect.left + 7, rect.top + 1),
     612                    BPoint(rect.left + 7, rect.top + 7), outlineColor);
     613                view->AddLine(BPoint(rect.left + 1, rect.top + 7),
     614                    BPoint(rect.left + 7, rect.top + 1), outlineColor);
     615
     616                view->AddLine(BPoint(rect.left + 3, rect.top + 6),
     617                    BPoint(rect.left + 6, rect.top + 6), middleColor);
     618                view->AddLine(BPoint(rect.left + 4, rect.top + 5),
     619                    BPoint(rect.left + 6, rect.top + 5), middleColor);
     620                view->AddLine(BPoint(rect.left + 5, rect.top + 4),
     621                    BPoint(rect.left + 6, rect.top + 4), middleColor);
     622                view->AddLine(BPoint(rect.left + 6, rect.top + 3),
     623                    BPoint(rect.left + 6, rect.top + 4), middleColor);
     624            } else {
     625                view->AddLine(BPoint(rect.right - 1, rect.top + 7),
     626                    BPoint(rect.right - 7, rect.top + 7), outlineColor);
     627                view->AddLine(BPoint(rect.right - 7, rect.top + 1),
     628                    BPoint(rect.right - 7, rect.top + 7), outlineColor);
     629                view->AddLine(BPoint(rect.right - 1, rect.top + 7),
     630                    BPoint(rect.right - 7, rect.top + 1), outlineColor);
     631
     632                view->AddLine(BPoint(rect.right - 3, rect.top + 6),
     633                    BPoint(rect.right - 6, rect.top + 6), middleColor);
     634                view->AddLine(BPoint(rect.right - 4, rect.top + 5),
     635                    BPoint(rect.right - 6, rect.top + 5), middleColor);
     636                view->AddLine(BPoint(rect.right - 5, rect.top + 4),
     637                    BPoint(rect.right - 6, rect.top + 4), middleColor);
     638                view->AddLine(BPoint(rect.right - 6, rect.top + 3),
     639                    BPoint(rect.right - 6, rect.top + 4), middleColor);
     640            }
     641            view->EndLineArray();
     642            break;
     643
     644        case B_OPEN_LATCH:
     645            view->BeginLineArray(6);
     646            view->AddLine(BPoint(rect.left + 1, rect.top + 3),
     647                BPoint(rect.right - 1, rect.top + 3), outlineColor);
     648            view->AddLine(BPoint(rect.left + 1, rect.top + 3),
     649                BPoint(rect.left + 5, rect.top + 7), outlineColor);
     650            view->AddLine(BPoint(rect.left + 5, rect.top + 7),
     651                BPoint(rect.right - 1, rect.top + 3), outlineColor);
     652
     653            view->AddLine(BPoint(rect.left + 3, rect.top + 4),
     654                BPoint(rect.right - 3, rect.top + 4), middleColor);
     655            view->AddLine(BPoint(rect.left + 4, rect.top + 5),
     656                BPoint(rect.right - 4, rect.top + 5), middleColor);
     657            view->AddLine(BPoint(rect.left + 5, rect.top + 5),
     658                BPoint(rect.left + 5, rect.top + 6), middleColor);
     659            view->EndLineArray();
     660            break;
     661
     662        case B_NO_LATCH:
     663        break;
     664    }
     665}
     666
     667void
     668PartitionListView::ShowPartitionMenu(BPoint point, partition_id id)
     669{
     670    ConvertToScreen(&point);
     671    fPopUpMenu->Go(point, true);
     672}
     673
     674partition_id
     675PartitionListView::GetSelectedPartition()
     676{
     677    PartitionListRow* row = dynamic_cast<PartitionListRow*>(CurrentSelection());
     678    if (row)
     679        return row->ID();
     680
     681    return NULL;
     682}
     683
    65684PartitionListRow*
    66 PartitionListView::FindRow(partition_id id)
     685PartitionListView::FindRow(partition_id id, PartitionListRow* current)
    67686{
    68     for (int32 idx=0; idx < CountRows(); idx++) {
    69         PartitionListRow* item = dynamic_cast<PartitionListRow*>(RowAt(idx));
    70         if (item != NULL && item->ID() == id)
    71             return item;
     687    if (current && current->ID() == id)
     688        return current;
     689
     690    for (int32 idx=0; idx < CountRows(current); idx++)
     691    {
     692        PartitionListRow* row = dynamic_cast<PartitionListRow*>(RowAt(idx, current));
     693        if (row != NULL)
     694        {
     695            row = FindRow(id, row);
     696            if (row)
     697                return row;
     698        }
    72699    }
    73700
    74701    return NULL;
     
    103730   
    104731    return partitionrow;
    105732}
     733
     734void
     735PartitionListView::GetMenuStatus(PartitionListRow *selected_item,
     736                      bool& mountVisible,
     737                      bool& unmountVisible,
     738                      bool& setupVisible,
     739                      bool& optionsVisible,
     740                      bool& formatVisible,
     741                      bool& initializeVisible,
     742                      bool& partitionVisible,
     743                      bool& ejectVisible,
     744                      bool& testVisible)
     745{
     746    testVisible = true;
     747
     748    if (!selected_item)
     749    {
     750        // Obviously not selected anything!
     751
     752        mountVisible = true;
     753        unmountVisible = true;
     754        setupVisible = false;
     755        optionsVisible = false;
     756
     757        return;
     758    }
     759
     760    // Selected something, lets see what it is...
     761
     762    BPartition *currentPartition;
     763    BDiskDevice currentDevice;
     764    partition_id id = selected_item->ID();
     765
     766    if (BDiskDeviceRoster().GetPartitionWithID(id, &currentDevice, &currentPartition) == B_OK && (!(currentDevice.IsRemovableMedia() && !currentDevice.HasMedia())))
     767    {
     768        // Selected something we can work with
     769
     770        if (currentDevice.IsReadOnlyMedia())
     771        {
     772            setupVisible = false;
     773        }
     774
     775        if (currentPartition->IsMounted())
     776        {
     777            ejectVisible = currentDevice.IsRemovableMedia();
     778            initializeVisible = false;
     779            partitionVisible = false;
     780        }
     781        else if (currentDevice.IsRemovableMedia())
     782        {
     783            ejectVisible = currentDevice.HasMedia();
     784            initializeVisible = currentDevice.HasMedia();
     785            partitionVisible = (currentPartition->IsDevice() && currentDevice.HasMedia());
     786        }
     787        else
     788        {
     789            ejectVisible = false;
     790            initializeVisible = true;
     791            partitionVisible = currentPartition->IsDevice();
     792        }
     793   
     794        formatVisible = false; // not 100% sure what this equates to
     795
     796        mountVisible = true;
     797        unmountVisible = true;
     798        setupVisible = true;
     799        optionsVisible = true;
     800    }
     801    else
     802    {
     803        // Selected something we can't work with!
     804
     805        mountVisible = false;
     806        unmountVisible = false;
     807        setupVisible = false;
     808        optionsVisible = false;
     809    }
     810}
     811
  • src/preferences/drivesetup/PartitionList.h

     
     1/*! \file MainWindow.h
     2    \brief Header for the PartitionListView class and its relatives.
     3   
     4*/
    15#ifndef PARTITIONLIST_H
    26#define PARTITIONLIST_H
    37
     
    48class PartitionListRow;
    59class PartitionListView;
    610
     11#include <interface/ColumnTypes.h>
    712#include <interface/ColumnListView.h>
     13#include <interface/Menu.h>
     14#include <interface/MenuItem.h>
    815#include <storage/Partition.h>
    916
    1017// Forward declarations
    1118class BPartition;
    1219
     20
     21// A bitmap *and* a string!
     22class BBitmapStringField : public BStringField
     23{
     24typedef BStringField Inherited;
     25    public:
     26        BBitmapStringField  (BBitmap* bitmap, const char *string);
     27
     28        const BBitmap*      Bitmap  ();
     29        void    SetBitmap   (BBitmap* bitmap);
     30
     31    private:
     32        BBitmap*        fBitmap;
     33};
     34
     35
     36// Specialized menu item for the mount/unmount menu's
     37class PartitionMenuItem : public BMenuItem
     38{
     39typedef BMenuItem Inherited;
     40public:
     41    PartitionMenuItem(const char *label, BMessage *message,
     42              char shortcut, uint32 modifier, BPartition *partition, bool unmount);
     43
     44    partition_id ID() { return fPartitionID; }
     45private:
     46    partition_id fPartitionID;
     47    bool         fUnmount;
     48};
     49
     50
     51// Menu which lists iterated DiskSystem's
     52class DiskSystemMenu : public BMenu
     53{
     54typedef BMenu Inherited;
     55public:
     56    DiskSystemMenu( const char *title,
     57            bool partitionSystems,
     58            menu_layout layout = B_ITEMS_IN_COLUMN);
     59
     60    void UpdateSystems(partition_id id);
     61
     62private:
     63    bool fIteratePartitionSystems;
     64};
     65
     66
     67// Column for PartitionListView
     68class PartitionColumn : public BTitledColumn
     69{
     70typedef BTitledColumn Inherited;
     71public:
     72    PartitionColumn(const char* title, float width, float minWidth,
     73        float maxWidth, uint32 truncate, alignment align = B_ALIGN_LEFT);
     74
     75    virtual void    MouseDown(BColumnListView *parent, BRow *row, BField *field,
     76                      BRect field_rect, BPoint point, uint32 buttons);
     77
     78    virtual void    DrawField   (BField* field,
     79                 BRect rect,                         BView* parent);
     80
     81    virtual int     CompareFields       (BField* field1,
     82                             BField* field2);
     83
     84    virtual bool        AcceptsField        (const BField* field) const;
     85
     86    private:
     87        uint32      fTruncate;
     88};
     89
     90
     91// Row for the PartitionListView
    1392class PartitionListRow : public BRow
    1493{
    1594    typedef BRow Inherited;
     
    21100    partition_id fPartitionID;
    22101};
    23102
     103
     104// List which display's all of those BPartition's
    24105class PartitionListView : public BColumnListView
    25106{
    26107    typedef BColumnListView Inherited;
    27108public:
    28109    PartitionListView(const BRect& frame);
     110    ~PartitionListView();
     111
     112    partition_id GetSelectedPartition();
     113
     114    void ShowPartitionMenu(BPoint point, partition_id id);
     115    void UpdatePartitionMenu();
     116
     117    void PopulateMountMenus(BMenu* mount, BMenu* unmount, PartitionListRow *current=NULL);
     118    int32 RecursePopulateMountMenus(BMenu* mount, BMenu* unmount, PartitionListRow *current);
     119
     120    virtual void    DrawLatch(BView*, BRect, LatchType, BRow*);
     121    virtual void DrawLatchInState(LatchType state, bool leftAligned, BView *view, const BRect &rect);
    29122   
    30     PartitionListRow* FindRow(partition_id id);
     123    PartitionListRow* FindRow(partition_id id,  PartitionListRow* current=NULL);
    31124    PartitionListRow* AddPartition(BPartition* partition);
     125
     126    static void GetMenuStatus(PartitionListRow *selected_item,
     127                      bool& mountVisible,
     128                      bool& unmountVisible,
     129                      bool& setupVisible,
     130                      bool& optionsVisible,
     131                      bool& formatVisible,
     132                      bool& initializeVisible,
     133                      bool& partitionVisible,
     134                      bool& ejectVisible,
     135                      bool& testVisible); // Yikes!
     136
     137private:
     138    BPopUpMenu *fPopUpMenu;
     139
     140    BMenu* fMountMenu;
     141    BMenu* fUnMountMenu;
     142    BMenu* fSetupMenu;
     143    BMenu* fOptionsMenu;
     144
     145    BMenuItem* fFormatItem;
     146    BMenuItem* fEjectItem;
     147    BMenuItem* fTestItem;
     148
     149    DiskSystemMenu* fInitializeMenu;
     150    DiskSystemMenu* fPartitionMenu;
    32151};
    33152
    34153#endif /* PARTITIONLIST_H */
  • src/preferences/drivesetup/MainWindow.cpp

     
    99#include "PartitionList.h"
    1010#include "PosSettings.h"
    1111
     12#include <interface/Alert.h>
     13
    1214#include <interface/MenuItem.h>
    1315#include <interface/MenuBar.h>
    1416#include <interface/Menu.h>
     
    2325#include <storage/DiskDevice.h>
    2426#include <storage/Partition.h>
    2527#include <storage/Path.h>
     28#include <storage/Volume.h>
     29#include <storage/VolumeRoster.h>
    2630
    2731class DriveVisitor : public BDiskDeviceVisitor
    2832{
    2933public:
    30     DriveVisitor(PartitionListView* list);
     34    DriveVisitor(PartitionListView* list, BMenu *mountmenu, BMenu *umountmenu);
    3135
    3236    bool Visit(BDiskDevice *device);
    3337    bool Visit(BPartition *partition, int32 level);
     38
     39    void Sync();
    3440private:
     41
    3542    PartitionListView* fPartitionList;
     43    BMenu*         fMountMenu;
     44    BMenu*         fUnMountMenu;
    3645};
    3746
    3847const char*
     
    8897}
    8998#endif
    9099
     100
    91101/**
    92102 * Constructor.
    93103 * @param frame The size to make the window.
     
    95105MainWindow::MainWindow(BRect frame, PosSettings *Settings)
    96106    : BWindow(frame, "DriveSetup", B_DOCUMENT_WINDOW,  B_ASYNCHRONOUS_CONTROLS | B_NOT_ZOOMABLE)
    97107{
    98     BMenu *partitionMenu, *initMenu;
    99108    BMenu *menu;
    100109
    101110    fSettings = Settings;
    102111   
    103112    BMenuBar* rootMenu = new BMenuBar(Bounds(), "root menu");
    104     //Setup Mount menu
    105     menu = new BMenu("Mount");
    106     menu->AddItem(new BMenuItem("Mount All Partitions", new BMessage(MOUNT_MOUNT_ALL_MSG), 'M'));
    107     menu->AddSeparatorItem();
    108     rootMenu->AddItem(menu);
     113
     114    // Setup Mount menu
     115    fMountMenu = new BMenu("Mount");
     116    rootMenu->AddItem(fMountMenu);
    109117   
    110     //Setup Unmount menu
    111     menu = new BMenu("Unmount");
    112     rootMenu->AddItem(menu);
     118    // Setup Unmount menu
     119    fUnMountMenu = new BMenu("Unmount");
     120    rootMenu->AddItem(fUnMountMenu);
    113121   
    114     //Setup Setup menu
    115     menu = new BMenu("Setup");
    116         menu->AddItem(new BMenuItem("Format", new BMessage(SETUP_FORMAT_MSG), 'F'));
    117         partitionMenu = new BMenu("Partition");
    118         menu->AddItem(partitionMenu);
    119         initMenu = new BMenu("Initialize");
     122    fFormatItem = new BMenuItem("Format", new BMessage(SETUP_FORMAT_MSG), 'F');
     123
     124    // Setup Setup menu
     125    fSetupMenu = new BMenu("Setup");
     126        fSetupMenu->AddItem(fFormatItem);
     127        fPartitionMenu = new DiskSystemMenu("Partition", true);
     128        fSetupMenu->AddItem(fPartitionMenu);
     129        fInitializeMenu = new DiskSystemMenu("Initialize", false);
    120130        //add menu for formats
    121         menu->AddItem(initMenu);
    122     rootMenu->AddItem(menu);
     131        fSetupMenu->AddItem(fInitializeMenu);
     132    rootMenu->AddItem(fSetupMenu);
    123133   
    124     //Setup Options menu
    125     menu = new BMenu("Options");
    126         menu->AddItem(new BMenuItem("Eject", new BMessage(OPTIONS_EJECT_MSG), 'E'));
    127         menu->AddItem(new BMenuItem("Surface Test", new BMessage(OPTIONS_SURFACE_TEST_MSG), 'T'));
    128     rootMenu->AddItem(menu);
     134    // Setup Options menu
     135
     136    fEjectItem = new BMenuItem("Eject", new BMessage(OPTIONS_EJECT_MSG), 'E');
     137    fTestItem = new BMenuItem("Surface Test", new BMessage(OPTIONS_SURFACE_TEST_MSG), 'T');
     138
     139    fOptionsMenu = new BMenu("Options");
     140        fOptionsMenu->AddItem(fEjectItem);
     141        fOptionsMenu->AddItem(fTestItem);
     142    rootMenu->AddItem(fOptionsMenu);
    129143   
    130     //Setup Rescan menu
     144    // Setup Rescan menu
    131145    menu = new BMenu("Rescan");
    132146        menu->AddItem(new BMenuItem("IDE", new BMessage(RESCAN_IDE_MSG)));
    133147        menu->AddItem(new BMenuItem("SCSI", new BMessage(RESCAN_SCSI_MSG)));
     
    135149       
    136150    AddChild(rootMenu);
    137151
     152    // Setup partition list
    138153    BRect r(Bounds());
    139154    r.top = rootMenu->Frame().bottom +1;
    140155    fListView = new PartitionListView(r);
    141156    AddChild(fListView);
    142157
    143     // Now update filesystem/partition menus with values
    144     BDiskSystem diskSystem;
    145     fDDRoster.RewindDiskSystems();
    146     while(fDDRoster.GetNextDiskSystem(&diskSystem) == B_OK) {
    147         if (diskSystem.IsPartitioningSystem()) {
    148             BMessage* msg = new BMessage(SETUP_PARTITION_SELECTED_MSG);
    149             msg->AddString("bdisksystem:name", diskSystem.Name());
    150             partitionMenu->AddItem(new BMenuItem(diskSystem.PrettyName(), msg));
    151         } else if (diskSystem.IsFileSystem()) {
    152             BMessage* msg = new BMessage(SETUP_INITIALIZE_MSG);
    153             msg->AddString("bdisksystem:name", diskSystem.Name());
    154             initMenu->AddItem(new BMenuItem(diskSystem.PrettyName(), msg));
    155         }
    156     }
     158    fListView->SetSelectionMessage(new BMessage(PARTITION_SELECTION_CHANGE_MSG));
    157159
    158     // Now visit all disks in the system and show their contents
    159     DriveVisitor driveVisitor(fListView);
    160     BPartition *partition = NULL;
    161     BDiskDevice device;
    162     fDDRoster.VisitEachPartition(&driveVisitor, &device, &partition);
     160    // Finally we can grab our data!
     161   
     162    ScanDevices();
    163163}
    164164
    165165/**
     
    167167 * @param message The message recieved by the window.
    168168 */
    169169void MainWindow::MessageReceived(BMessage *message){
     170    switch(message->what)
     171    {
     172   
     173        case PARTITION_SELECTION_CHANGE_MSG:
    170174
    171     switch(message->what){
    172    
     175            //
     176            UpdateMenus();
     177
     178            break;
     179
    173180        case MOUNT_MOUNT_ALL_MSG:
    174        
    175             printf("MOUNT_MOUNT_ALL_MSG\n");
     181
     182            // Mount all listed partitions
     183            MountAllVisible();
     184            UpdateMenus();
     185
    176186            break;
    177187           
    178         case MOUNT_MOUNT_SELECTED_MSG:
    179        
    180             printf("MOUNT_MOUNT_SELECTED_MSG\n");
    181             break;
     188        case MOUNT_TOGGLE:
    182189           
    183         case UNMOUNT_UNMOUNT_SELECTED_MSG:
    184        
    185             printf("UNMOUNT_UNMOUNT_SELECTED_MSG\n");
     190            HandleMenuMounting(message);
     191
    186192            break;
    187193       
    188194        case SETUP_FORMAT_MSG:
     195
     196            if (fListView->CurrentSelection())
     197                HandleFormat(message);
     198
     199            break;
    189200       
    190             printf("SETUP_FORMAT_MSG\n");
     201        case SETUP_PARTITION_SELECTED_MSG:
     202
     203            if (fListView->CurrentSelection())
     204                HandlePartition(message);
     205
    191206            break;
    192            
     207
    193208        case SETUP_INITIALIZE_MSG:
     209
     210            if (fListView->CurrentSelection())
     211                HandleInitialize(message);
    194212       
    195             printf("SETUP_INITIALIZE_MSG\n");
    196213            break;
    197            
     214
     215        case MOUNT_TOGGLE_SELECTED_MSG:
    198216        case OPTIONS_EJECT_MSG:
    199        
    200             printf("OPTIONS_EJECT_MSG\n");
    201             break;
    202            
    203217        case OPTIONS_SURFACE_TEST_MSG:
    204        
    205             printf("OPTIONS_SURFACE_TEST_MSG\n");
     218
     219            if (fListView->CurrentSelection())
     220                HandleMenuActions(message);
    206221            break;
    207222           
    208223        case RESCAN_IDE_MSG:
    209224       
    210             printf("RESCAN_IDE_MSG\n");
     225            ScanDevices();
    211226            break;
    212227           
    213228        case RESCAN_SCSI_MSG:
    214229       
    215             printf("RESCAN_SCSI_MSG\n");
     230            ScanDevices();
    216231            break;
    217232           
    218233        default:
    219234       
    220235            BWindow::MessageReceived(message);
    221236           
    222     }//switch
     237    }
    223238   
    224239}
    225240
     241void
     242MainWindow::UpdateMenus()
     243{
     244    PartitionListRow *selected_item = dynamic_cast<PartitionListRow*>(fListView->CurrentSelection());
     245
     246    // Clean out the old..
     247
     248    fMountMenu->RemoveItems(0, fMountMenu->CountItems());
     249    fUnMountMenu->RemoveItems(0, fUnMountMenu->CountItems());
     250
     251    // Determine the enabled status of the menu's
     252
     253    bool mountVisible = false;
     254    bool unmountVisible = false;
     255    bool setupVisible = false;
     256    bool optionsVisible = false;
     257    bool formatVisible = false;
     258    bool initializeVisible = false;
     259    bool partitionVisible = false;
     260    bool ejectVisible = false;
     261    bool testVisible = false;
     262
     263    PartitionListView::GetMenuStatus(selected_item,
     264              mountVisible,
     265              unmountVisible,
     266              setupVisible,
     267              optionsVisible,
     268              formatVisible,
     269              initializeVisible,
     270              partitionVisible,
     271              ejectVisible,
     272              testVisible);
     273
     274    fMountMenu->SetEnabled(mountVisible);
     275    fUnMountMenu->SetEnabled(unmountVisible);
     276
     277    fSetupMenu->SetEnabled(setupVisible);
     278    fOptionsMenu->SetEnabled(optionsVisible);
     279
     280    fFormatItem->SetEnabled(formatVisible);
     281
     282    fInitializeMenu->SetEnabled(initializeVisible);
     283    fPartitionMenu->SetEnabled(partitionVisible);
     284
     285    fEjectItem->SetEnabled(ejectVisible);
     286    fTestItem->SetEnabled(testVisible);
     287
     288    // Re-populate menu's
     289
     290    if (partitionVisible)
     291        fPartitionMenu->UpdateSystems(selected_item ? selected_item->ID() : NULL);
     292    if (initializeVisible)
     293        fInitializeMenu->UpdateSystems(selected_item ? selected_item->ID() : NULL);
     294
     295    fListView->PopulateMountMenus(fMountMenu, fUnMountMenu, selected_item);
     296    fListView->UpdatePartitionMenu();
     297}
     298
    226299/**
     300 * Scans for devices & places them in the controls
     301 */
     302void
     303MainWindow::ScanDevices()
     304{
     305    fListView->Clear();
     306
     307    // Now visit all disks in the system and show their contents
     308    DriveVisitor driveVisitor(fListView, fMountMenu, fUnMountMenu);
     309    BPartition *partition = NULL;
     310    BDiskDevice device;
     311    fDDRoster.VisitEachPartition(&driveVisitor, &device, &partition);
     312
     313    UpdateMenus();
     314}
     315
     316
     317bool
     318MainWindow::DoEject(BDiskDevice* disk)
     319{   
     320    status_t status;
     321    BString string;
     322
     323    // Try to eject, giving an error message where neccesary
     324    // and updating everything upon success
     325
     326    if (disk->HasMedia())
     327    {
     328        status = disk->Eject(true);
     329        if (status < B_OK) {
     330            string << "Error ejecting disk. (" << strerror(status) << ")";
     331                (new BAlert("", string.String(), "OK"))->Go(0);
     332        }
     333        else
     334        {
     335            UpdateMenus();
     336            return true;
     337        }
     338    }
     339
     340    return true;
     341}
     342
     343void
     344MainWindow::DoTest(BPartition *partition)
     345{
     346    // InitCheck on DiskDevice? StartWatching*?
     347
     348    // TODO
     349
     350    (new BAlert("", "Not implemented", "OK"))->Go(0);
     351}
     352
     353bool
     354MainWindow::DoToggleMount(BPartition *partition, bool only_mount)
     355{
     356    status_t status;
     357    BString string;
     358
     359    // Try to mount or unmount (only the former if only_mount),
     360    // giving an error message where neccesary and updating everything
     361    // upon success
     362
     363    if (!partition->IsMounted())
     364    {
     365        status = partition->Mount();
     366        if (status < B_OK) {
     367            string << "Error mounting volume. (" << strerror(status) << ")";
     368                (new BAlert("", string.String(), "OK"))->Go(0);
     369        }
     370        else
     371        {
     372            UpdateMenus();
     373            return true;
     374        }
     375    }
     376    else if (!only_mount)
     377    {
     378        status = partition->Unmount();
     379        if (status < B_OK) {
     380            string << "Error unmounting volume. (" << strerror(status) << ")";
     381                (new BAlert("", string.String(), "OK"))->Go(0);
     382        }
     383        else
     384        {
     385            UpdateMenus();
     386            return true;
     387        }
     388    }
     389
     390    return false;
     391}
     392
     393void
     394MainWindow::HandleMenuActions(BMessage *message)
     395{
     396    BPartition *currentPartition;
     397    BDiskDevice currentDevice;
     398
     399    if (fDDRoster.GetPartitionWithID(fListView->GetSelectedPartition(), &currentDevice, &currentPartition) != B_OK)
     400        return;
     401
     402    // These messages all require a BPartition / BDiskDevice,
     403    // so they are all delegated here to eliminate unneccesary
     404    // redundancy
     405
     406    switch(message->what)
     407    {
     408        case MOUNT_TOGGLE_SELECTED_MSG:
     409       
     410            DoToggleMount(currentPartition);
     411
     412            break;
     413
     414        case OPTIONS_EJECT_MSG:
     415       
     416            DoEject(&currentDevice);
     417            UpdateMenus();
     418       
     419            break;
     420           
     421        case OPTIONS_SURFACE_TEST_MSG:
     422
     423            DoTest(currentPartition);
     424
     425            // Defragment ? Repair ?
     426            break;
     427    }
     428
     429    UpdateMenus();
     430}
     431
     432
     433void MainWindow::HandleFormat(BMessage* message)
     434{
     435    // TODO (?)
     436
     437    (new BAlert("", "Not implemented", "OK"))->Go(0);
     438}
     439
     440void MainWindow::HandlePartition(BMessage* message)
     441{
     442    const char *disk_system;
     443    status_t error = B_OK;
     444
     445    if (message->FindString("bdisksystem:name", &disk_system) != B_OK)
     446        return;
     447
     448    // Lets find this disk system!
     449
     450    BDiskSystem diskSystem;
     451    fDDRoster.RewindDiskSystems();
     452    while(fDDRoster.GetNextDiskSystem(&diskSystem) == B_OK)
     453    {
     454        if (!diskSystem.IsPartitioningSystem())
     455            continue;
     456
     457        if (!strcmp(disk_system, diskSystem.Name()))
     458        {
     459            // Found it!
     460           
     461            // TODO
     462            // GetChildCreationParameterEditor...
     463
     464            (new BAlert("", "If this was implemented, we'd show you a nice parameters dialog!", "OK"))->Go(0);
     465
     466            break;
     467        }
     468    }
     469
     470    if (error != B_OK)
     471    {
     472        // Show a nasty error message
     473
     474        BString string;
     475        string << "Error initializing. (" << strerror(error) << ")";
     476            (new BAlert("", string.String(), "OK"))->Go(0);
     477    }
     478}
     479
     480
     481void MainWindow::HandleInitialize(BMessage* message)
     482{
     483    const char *disk_system;
     484    status_t error = B_OK;
     485
     486    if (message->FindString("bdisksystem:name", &disk_system) != B_OK)
     487        return;
     488
     489    // Lets find this disk system!
     490
     491    BDiskSystem diskSystem;
     492    fDDRoster.RewindDiskSystems();
     493    while(fDDRoster.GetNextDiskSystem(&diskSystem) == B_OK)
     494    {
     495        if (!diskSystem.IsFileSystem())
     496            continue;
     497
     498        if (!strcmp(disk_system, diskSystem.Name()))
     499        {
     500            // Now lets see if we can init it...
     501           
     502            BPartition *partition;
     503            BDiskDevice device;
     504   
     505            error = fDDRoster.GetPartitionWithID(fListView->GetSelectedPartition(), &device, &partition);
     506
     507            if (error != B_OK)
     508                break;
     509
     510            // TBD: is Uninitialize() required?
     511            if (partition->CanInitialize(disk_system))
     512            {
     513                // TODO
     514                (new BAlert("", "If this was implemented, we'd show you a nice parameters dialog!", "OK"))->Go(0);
     515
     516                break;
     517/*
     518                BDiskDeviceParameterEditor *editor;
     519                const char *editor_parameters;
     520                const char *editor_name = "TODO";
     521
     522                error = partition->GetInitializationParameterEditor(disk_system, &editor);
     523
     524                if (error != B_OK)
     525                    break;
     526
     527                // TODO: figure out how to invoke the editor and grab the parameters!
     528
     529                error = partition->ValidateInitialize(disk_system, editor_name, editor_parameters);
     530
     531                if (error != B_OK)
     532                    break;
     533
     534                error = partition->Initialize(disk_system, editor_name, editor_parameters);
     535
     536                if (error != B_OK)
     537                    break;
     538*/
     539            }
     540            else
     541            {
     542                error = B_NOT_ALLOWED;
     543            }
     544        }
     545    }
     546
     547    if (error != B_OK)
     548    {
     549        // Show a nasty error message
     550
     551        BString string;
     552        string << "Error initializing. (" << strerror(error) << ")";
     553            (new BAlert("", string.String(), "OK"))->Go(0);
     554    }
     555}
     556
     557void
     558MainWindow::HandleMenuMounting(BMessage *message)
     559{
     560    partition_id id;
     561
     562    if (message->FindInt32("PartitionID", &id) == B_OK)
     563    {
     564        BPartition *partition;
     565        BDiskDevice device;
     566
     567        if (fDDRoster.GetPartitionWithID(id, &device, &partition) == B_OK)
     568        {
     569            DoToggleMount(partition);
     570        }
     571    }
     572}
     573
     574void MainWindow::MountAllVisible()
     575{
     576    // Iterate through fMountMenu mounting all of the associated partitions
     577
     578    for (int32 idx=2; idx < fMountMenu->CountItems(); idx++)
     579    {
     580        PartitionMenuItem *item = dynamic_cast<PartitionMenuItem*>(fMountMenu->ItemAt(idx));
     581        if (item)
     582        {
     583            BPartition *partition;
     584            BDiskDevice device;
     585
     586            if (!fDDRoster.GetPartitionWithID(item->ID(), &device, &partition) == B_OK)
     587                continue;
     588           
     589            DoToggleMount(partition, true);
     590        }
     591    }
     592}
     593
     594/**
    227595 * Quits and Saves settings.
    228596 */
    229597bool
    230598MainWindow::QuitRequested()
    231599{
    232600    bool accepted = BWindow::QuitRequested();
    233     if (accepted) {
     601    if (accepted)
     602    {
    234603        fSettings->SetWindowPosition(Frame());
    235         be_app->PostMessage(B_QUIT_REQUESTED);
     604        be_app->PostMessage(B_QUIT_REQUESTED);
    236605    }
    237606   
    238607    return accepted;
    239608}
    240609
    241 DriveVisitor::DriveVisitor(PartitionListView* list)
    242     : fPartitionList(list)
     610
     611DriveVisitor::DriveVisitor(PartitionListView* list, BMenu *mountmenu, BMenu *unmountmenu)
     612    : fPartitionList(list),
     613      fMountMenu(mountmenu),
     614      fUnMountMenu(unmountmenu)
    243615{
    244616}
    245617
     
    270642
    271643    return false; // Don't stop yet!
    272644}
     645