Ticket #968: resourceedit-part2-1.patch

File resourceedit-part2-1.patch, 73.6 KB (added by TriEdgeAI, 11 years ago)
  • src/apps/resourceedit/Constants.h

    From 710ab9e97e537d706f8227ef6c59cea003f6cbe0 Mon Sep 17 00:00:00 2001
    From: Tri-Edge AI <triedgeai@gmail.com>
    Date: Mon, 14 Jan 2013 06:47:46 +0200
    Subject: [PATCH] Extended ResourceEdit.
    
    ---
     src/apps/resourceedit/Constants.h                  |   21 +-
     src/apps/resourceedit/DefaultTypes.cpp             |   88 +--
     src/apps/resourceedit/DefaultTypes.h               |   77 +-
     src/apps/resourceedit/EditWindow.cpp               |  163 ++++
     src/apps/resourceedit/EditWindow.h                 |   53 ++
     src/apps/resourceedit/ImageButton.cpp              |   67 --
     src/apps/resourceedit/ImageButton.h                |   32 -
     src/apps/resourceedit/Jamfile                      |   35 +-
     src/apps/resourceedit/MainWindow.cpp               |  782 ++++++++++++++++++--
     src/apps/resourceedit/MainWindow.h                 |  111 ++-
     src/apps/resourceedit/ResourceEdit.cpp             |   37 +-
     src/apps/resourceedit/ResourceEdit.h               |    5 +
     src/apps/resourceedit/ResourceEdit.rdef            |    2 +-
     src/apps/resourceedit/ResourceListView.cpp         |   12 +-
     src/apps/resourceedit/ResourceListView.h           |    1 +
     src/apps/resourceedit/ResourceRow.cpp              |   68 +-
     src/apps/resourceedit/ResourceRow.h                |   15 +-
     src/apps/resourceedit/SettingsFile.cpp             |   56 ++
     src/apps/resourceedit/SettingsFile.h               |   33 +
     src/apps/resourceedit/SettingsWindow.cpp           |  120 +++
     src/apps/resourceedit/SettingsWindow.h             |   48 ++
     src/apps/resourceedit/edits/AppFlagsEdit.cpp       |    4 +
     src/apps/resourceedit/edits/AppFlagsEdit.h         |    4 +
     src/apps/resourceedit/edits/BooleanEdit.cpp        |   71 ++
     src/apps/resourceedit/edits/BooleanEdit.h          |   30 +
     src/apps/resourceedit/edits/EditView.cpp           |   52 ++
     src/apps/resourceedit/edits/EditView.h             |   31 +
     src/apps/resourceedit/edits/NormalEdit.cpp         |   64 ++
     src/apps/resourceedit/edits/NormalEdit.h           |   31 +
     src/apps/resourceedit/interface/ImageButton.cpp    |   67 ++
     src/apps/resourceedit/interface/ImageButton.h      |   32 +
     .../resourceedit/settings/GenericSettingsView.cpp  |   60 ++
     .../resourceedit/settings/GenericSettingsView.h    |   37 +
     src/apps/resourceedit/support/UndoContext.cpp      |  175 +++++
     src/apps/resourceedit/support/UndoContext.h        |   55 ++
     35 files changed, 2214 insertions(+), 325 deletions(-)
     create mode 100644 src/apps/resourceedit/EditWindow.cpp
     create mode 100644 src/apps/resourceedit/EditWindow.h
     delete mode 100644 src/apps/resourceedit/ImageButton.cpp
     delete mode 100644 src/apps/resourceedit/ImageButton.h
     create mode 100644 src/apps/resourceedit/SettingsFile.cpp
     create mode 100644 src/apps/resourceedit/SettingsFile.h
     create mode 100644 src/apps/resourceedit/SettingsWindow.cpp
     create mode 100644 src/apps/resourceedit/SettingsWindow.h
     create mode 100644 src/apps/resourceedit/edits/AppFlagsEdit.cpp
     create mode 100644 src/apps/resourceedit/edits/AppFlagsEdit.h
     create mode 100644 src/apps/resourceedit/edits/BooleanEdit.cpp
     create mode 100644 src/apps/resourceedit/edits/BooleanEdit.h
     create mode 100644 src/apps/resourceedit/edits/EditView.cpp
     create mode 100644 src/apps/resourceedit/edits/EditView.h
     create mode 100644 src/apps/resourceedit/edits/NormalEdit.cpp
     create mode 100644 src/apps/resourceedit/edits/NormalEdit.h
     create mode 100644 src/apps/resourceedit/interface/ImageButton.cpp
     create mode 100644 src/apps/resourceedit/interface/ImageButton.h
     create mode 100644 src/apps/resourceedit/settings/GenericSettingsView.cpp
     create mode 100644 src/apps/resourceedit/settings/GenericSettingsView.h
     create mode 100644 src/apps/resourceedit/support/UndoContext.cpp
     create mode 100644 src/apps/resourceedit/support/UndoContext.h
    
    diff --git a/src/apps/resourceedit/Constants.h b/src/apps/resourceedit/Constants.h
    index 4a9766e..1bb2e97 100644
    a b  
    2525#define MSG_CLEAR           'm015'
    2626#define MSG_SELECTALL       'm016'
    2727
    28 #define MSG_ADD             'm020'
    29 #define MSG_REMOVE          'm021'
    30 #define MSG_MOVEUP          'm022'
    31 #define MSG_MOVEDOWN        'm023'
     28#define MSG_ADDAPPRES       'm020'
     29#define MSG_SETTINGS        'm021'
    3230
    33 #define MSG_SELECTION       'm030'
     31#define MSG_ADD             'm030'
     32#define MSG_REMOVE          'm031'
     33#define MSG_MOVEUP          'm032'
     34#define MSG_MOVEDOWN        'm033'
    3435
     36#define MSG_SELECTION       'm040'
     37#define MSG_INVOCATION      'm041'
     38
     39#define MSG_ACCEPT          'm050'
     40#define MSG_CANCEL          'm051'
     41#define MSG_IGNORE          'm052'
     42
     43#define MSG_SETTINGS_APPLY  'm022'
     44#define MSG_SETTINGS_REVERT 'm023'
     45#define MSG_SETTINGS_CLOSED 'm024'
    3546
    3647// TODO: Remove prior to release.
    3748#define DEBUG 1
  • src/apps/resourceedit/DefaultTypes.cpp

    diff --git a/src/apps/resourceedit/DefaultTypes.cpp b/src/apps/resourceedit/DefaultTypes.cpp
    index 9f7de5d..3fed852 100644
    a b  
    99#include <ByteOrder.h>
    1010
    1111
    12 BString
    13 toStringBOOL(const void* data)
    14 {
    15     if (*(bool*)data)
    16         return "✔ true";
    17     else
    18         return "✖ false";
    19 }
    20 
    21 
    22 BString
    23 toStringBYTE(const void* data)
    24 {
    25     return (BString() << *(int8*)data);
    26 }
    27 
    28 
    29 BString
    30 toStringSHRT(const void* data)
    31 {
    32     return (BString() << *(int16*)data);
    33 }
    34 
    35 
    36 BString
    37 toStringLONG(const  void* data)
    38 {
    39     return (BString() << *(int32*)data);
    40 }
    41 
    42 
    43 BString
    44 toStringLLNG(const void* data)
    45 {
    46     return (BString() << *(int64*)data);
    47 }
    48 
    49 
    50 BString
    51 toStringUBYT(const void* data)
    52 {
    53     return (BString() << *(uint8*)data);
    54 }
    55 
    56 
    57 BString
    58 toStringUSHT(const void* data)
    59 {
    60     return (BString() << *(uint16*)data);
    61 }
    62 
    63 
    64 BString
    65 toStringULNG(const void* data)
    66 {
    67     return (BString() << *(uint32*)data);
    68 }
    69 
    70 
    71 BString
    72 toStringULLG(const void* data)
     12int32
     13ResourceType::FindIndex(type_code code)
    7314{
    74     return (BString() << *(uint64*)data);
    75 }
    76 
     15    for (int32 i = 0; kDefaultTypes[i].type != NULL; i++)
     16        if (StringToCode(kDefaultTypes[i].code) == code)
     17            return i;
    7718
    78 BString
    79 toStringRAWT(const void* data)
    80 {
    81     return "[Raw Data]";
     19    return -1;
    8220}
    8321
    8422
    8523int32
    86 FindTypeCodeIndex(type_code code)
     24ResourceType::FindIndex(const char* type)
    8725{
    8826    for (int32 i = 0; kDefaultTypes[i].type != NULL; i++)
    89         if (kDefaultTypes[i].typeCode == code)
     27        if (strcmp(kDefaultTypes[i].type, type) == 0)
    9028            return i;
    9129
    9230    return -1;
    FindTypeCodeIndex(type_code code)  
    9432
    9533
    9634void
    97 TypeCodeToString(type_code code, char* str)
     35ResourceType::CodeToString(type_code code, char* str)
    9836{
    9937    *(type_code*)str = B_HOST_TO_BENDIAN_INT32(code);
    10038    str[4] = '\0';
    10139}
     40
     41
     42type_code
     43ResourceType::StringToCode(const char* code)
     44{
     45    // TODO: Code may be in other formats, too! Ex.: 0x4C4F4E47
     46    return B_BENDIAN_TO_HOST_INT32(*(int32*)code);
     47}
  • src/apps/resourceedit/DefaultTypes.h

    diff --git a/src/apps/resourceedit/DefaultTypes.h b/src/apps/resourceedit/DefaultTypes.h
    index 42ebf87..ef51b66 100644
    a b  
    66#define DEFAULT_TYPES_H
    77
    88
    9 #include <String.h>
     9#include "AppFlagsEdit.h"
     10#include "BooleanEdit.h"
     11#include "EditView.h"
     12#include "NormalEdit.h"
     13#include "ResourceRow.h"
    1014
     15#include <String.h>
    1116
    12 struct ResourceDataType {
    13     const char* type;
    14     type_code   typeCode;
    15     uint32      size;
    16     BString (*toString)(const void*);
    17 };
    1817
    19 // TODO: Rework design of this. This one sucks.
     18struct ResourceType {
     19            const char*     type;
     20            const char*     code;
     21            const char*     data;
     22            uint32          size;
     23            EditView*       edit;
    2024
    21 BString toStringBOOL(const void* data);
    22 BString toStringBYTE(const void* data);
    23 BString toStringSHRT(const void* data);
    24 BString toStringLONG(const void* data);
    25 BString toStringLLNG(const void* data);
    26 BString toStringUBYT(const void* data);
    27 BString toStringUSHT(const void* data);
    28 BString toStringULNG(const void* data);
    29 BString toStringULLG(const void* data);
    30 BString toStringRAWT(const void* data);
     25    static  int32           FindIndex(const char* type);
     26    static  int32           FindIndex(type_code code);
    3127
    32 char * const kDefaultData[] = {
    33     0, 0, 0, 0, 0, 0, 0, 0
     28    static  void            CodeToString(type_code code, char* str);
     29    static  type_code       StringToCode(const char* code);
    3430};
    3531
    36 #define LINE    "", 0, ~0
    37 #define END     NULL, 0, 0
    3832
    39 const ResourceDataType kDefaultTypes[] = {
    40     { "bool",   'BOOL', 1, toStringBOOL },
     33#define LINE    "", "", "", ~0, NULL
     34#define END     NULL, NULL, NULL, 0, NULL
     35
     36const ResourceType kDefaultTypes[] = {
     37    { "app_signature",          "",     "application/MyApp",        18, new NormalEdit()    },
     38    { "app_name_catalog_entry", "",     "MyApp:System name:MyApp",  24, new NormalEdit()    },
     39    //{ "app_flags",                "",     "None",                     4,  NULL },
    4140    { LINE },
    42     { "int8",   'BYTE', 1, toStringBYTE },
    43     { "int16",  'SHRT', 2, toStringSHRT },
    44     { "int32",  'LONG', 4, toStringLONG },
    45     { "int64",  'LLNG', 8, toStringLLNG },
     41    { "bool",                   "BOOL", "false",                    1,  new BooleanEdit()   },
    4642    { LINE },
    47     { "uint8",  'UBYT', 1, toStringUBYT },
    48     { "uint16", 'USHT', 2, toStringUSHT },
    49     { "uint32", 'ULNG', 4, toStringULNG },
    50     { "uint64", 'ULLG', 8, toStringULLG },
     43    { "int8",                   "BYTE", "0",                        1,  new NormalEdit()    },
     44    { "int16",                  "SHRT", "0",                        2,  new NormalEdit()    },
     45    { "int32",                  "LONG", "0",                        4,  new NormalEdit()    },
     46    { "int64",                  "LLNG", "0",                        8,  new NormalEdit()    },
    5147    { LINE },
    52     { "raw",    'RAWT', 0, toStringRAWT },
     48    { "uint8",                  "UBYT", "0",                        1,  new NormalEdit()    },
     49    { "uint16",                 "USHT", "0",                        2,  new NormalEdit()    },
     50    { "uint32",                 "ULNG", "0",                        4,  new NormalEdit()    },
     51    { "uint64",                 "ULLG", "0",                        8,  new NormalEdit()    },
     52    { LINE },
     53    { "string",                 "CSTR", "\"\"",                     0,  NULL },
     54    { "raw",                    "RAWT", "",                         0,  NULL },
     55    { LINE },
     56    { "array",                  "",     "",                         0,  NULL },
     57    { "message",                "",     "",                         0,  NULL },
     58    { "import",                 "",     "",                         0,  NULL },
    5359    { END }
    5460};
    5561
    56 const int32 kDefaultTypeSelected = 4;
     62const int32 kDefaultTypeSelected = 8;
    5763    // int32
    5864
    5965#undef LINE
    6066#undef END
    6167
    62 int32 FindTypeCodeIndex(type_code code);
    63 void TypeCodeToString(type_code code, char* str);
    64 
    6568
    6669#endif
  • new file src/apps/resourceedit/EditWindow.cpp

    diff --git a/src/apps/resourceedit/EditWindow.cpp b/src/apps/resourceedit/EditWindow.cpp
    new file mode 100644
    index 0000000..73b0364
    - +  
     1/*
     2 * Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
     3 * All rights reserved. Distributed under the terms of the MIT license.
     4 */
     5
     6
     7#include "EditWindow.h"
     8
     9#include "Constants.h"
     10#include "DefaultTypes.h"
     11#include "EditView.h"
     12#include "ResourceRow.h"
     13
     14#include <Box.h>
     15#include <Button.h>
     16#include <GroupLayoutBuilder.h>
     17#include <MenuField.h>
     18#include <MenuItem.h>
     19#include <PopUpMenu.h>
     20#include <StringView.h>
     21#include <TextControl.h>
     22#include <View.h>
     23
     24
     25EditWindow::EditWindow(BRect frame, ResourceRow* row)
     26    :
     27    BWindow(frame, "Edit Resource",
     28        B_TITLED_WINDOW_LOOK, B_MODAL_APP_WINDOW_FEEL, 0)
     29{
     30    int32 ix = ResourceType::FindIndex(row->ResourceType());
     31
     32    fRow = row;
     33
     34    fView = new BView(Bounds(), "fView", B_FOLLOW_ALL, 0);
     35    fView->SetLayout(new BGroupLayout(B_VERTICAL));
     36
     37    fIDText = new BTextControl(BRect(0, 0, 0, 0),
     38        "fIDText", "ID:", row->ResourceStringID(), NULL);
     39    fIDText->SetDivider(50);
     40
     41    fNameText = new BTextControl(BRect(0, 0, 0, 0),
     42        "fNameText", "Name:", row->ResourceName(), NULL);
     43    fNameText->SetDivider(50);
     44
     45    fTypePopUp = new BPopUpMenu("(Type)");
     46
     47    // TODO: (Not so) evil redundancy.
     48    for (int32 i = 0; kDefaultTypes[i].type != NULL; i++) {
     49        if (kDefaultTypes[i].size == ~(uint32)0)
     50            fTypePopUp->AddSeparatorItem();
     51        else
     52            fTypePopUp->AddItem(new BMenuItem(kDefaultTypes[i].type,
     53                new BMessage(MSG_SELECTION)));
     54    }
     55    // ---
     56
     57    fTypePopUp->ItemAt(ix)->SetMarked(true);
     58
     59    fTypeMenu = new BMenuField(BRect(0, 0, 0, 0),
     60        "fTypeMenu", "Type:", fTypePopUp);
     61    fTypeMenu->SetDivider(50);
     62
     63    fCodeText = new BTextControl(BRect(0, 0, 0, 0),
     64        "fCodeText", "Code:", row->ResourceStringCode(), NULL);
     65    fCodeText->SetDivider(50);
     66
     67    fEditViewBox = new BBox(BRect(0, 0, 0, 0), "fEditViewBox");
     68    fEditViewBox->SetLayout(new BGroupLayout(B_VERTICAL));
     69
     70    fEditView = kDefaultTypes[ix].edit;
     71    fEditView->AttachTo(fEditViewBox);
     72    fEditView->Edit(fRow);
     73
     74    fErrorString = new BStringView(BRect(0, 0, 0, 0),
     75        "fErrorString", "");
     76
     77    fErrorString->SetHighColor(ui_color(B_FAILURE_COLOR));
     78
     79    fCancelButton = new BButton(BRect(0, 0, 0, 0),
     80        "fCancelButton", "Cancel", new BMessage(MSG_CANCEL));
     81    fOKButton = new BButton(BRect(0, 0, 0, 0),
     82        "fOKButton", "OK", new BMessage(MSG_ACCEPT));
     83
     84    fView->AddChild(BGroupLayoutBuilder(B_VERTICAL, 8)
     85        .Add(fIDText)
     86        .Add(fNameText)
     87        .Add(fTypeMenu)
     88        .Add(fCodeText)
     89        .Add(fEditViewBox)
     90        .Add(fErrorString)
     91        .Add(BGroupLayoutBuilder(B_HORIZONTAL, 8)
     92            .AddGlue()
     93            .Add(fCancelButton)
     94            .Add(fOKButton)
     95            .SetInsets(8, 8, 8, 8)
     96        )
     97        .SetInsets(8, 8, 8, 8)
     98    );
     99
     100    AddChild(fView);
     101    ResizeTo(250, 350);
     102
     103    Show();
     104}
     105
     106
     107EditWindow::~EditWindow()
     108{
     109    fEditView->RemoveSelf();
     110}
     111
     112
     113void
     114EditWindow::MessageReceived(BMessage* msg)
     115{
     116    switch (msg->what) {
     117        case MSG_SELECTION:
     118        {
     119            int32 ix = fTypePopUp->FindMarkedIndex();
     120
     121            fCodeText->SetText(kDefaultTypes[ix].code);
     122
     123            fEditView->RemoveSelf();
     124
     125            fEditView = kDefaultTypes[ix].edit;
     126            fEditView->AttachTo(fEditViewBox);
     127            fEditView->Edit(fRow);
     128
     129            break;
     130        }
     131        case MSG_CANCEL:
     132            PostMessage(B_QUIT_REQUESTED);
     133            break;
     134
     135        case MSG_ACCEPT:
     136        {
     137            if (_Validate()) {
     138                int32 ix = fTypePopUp->FindMarkedIndex();
     139
     140                fRow->SetResourceStringID(fIDText->Text());
     141                fRow->SetResourceName(fNameText->Text());
     142                fRow->SetResourceType(kDefaultTypes[ix].type);
     143                fRow->SetResourceStringCode(fCodeText->Text());
     144                fRow->SetResourceSize(kDefaultTypes[ix].size);
     145
     146                fEditView->Commit();
     147
     148                PostMessage(B_QUIT_REQUESTED);
     149            }
     150
     151            break;
     152        }
     153    }
     154}
     155
     156
     157bool
     158EditWindow::_Validate()
     159{
     160    // TODO: Implement validation of entered data.
     161    fErrorString->SetText("");
     162    return true;
     163}
  • new file src/apps/resourceedit/EditWindow.h

    diff --git a/src/apps/resourceedit/EditWindow.h b/src/apps/resourceedit/EditWindow.h
    new file mode 100644
    index 0000000..d104af9
    - +  
     1/*
     2 * Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
     3 * All rights reserved. Distributed under the terms of the MIT license.
     4 */
     5#ifndef EDIT_WINDOW_H
     6#define EDIT_WINDOW_H
     7
     8
     9#include <Window.h>
     10
     11
     12class EditView;
     13class ResourceRow;
     14
     15class BBox;
     16class BButton;
     17class BMenuField;
     18class BPopUpMenu;
     19class BStringView;
     20class BTextControl;
     21
     22
     23class EditWindow : public BWindow {
     24public:
     25                    EditWindow(BRect frame, ResourceRow* row);
     26                    ~EditWindow();
     27
     28    void            MessageReceived(BMessage* msg);
     29
     30private:
     31    ResourceRow*    fRow;
     32
     33    BView*          fView;
     34
     35    BTextControl*   fIDText;
     36    BTextControl*   fNameText;
     37    BPopUpMenu*     fTypePopUp;
     38    BMenuField*     fTypeMenu;
     39    BTextControl*   fCodeText;
     40
     41    EditView*       fEditView;
     42    BBox*           fEditViewBox;
     43
     44    BStringView*    fErrorString;
     45
     46    BButton*        fCancelButton;
     47    BButton*        fOKButton;
     48
     49    bool            _Validate();
     50};
     51
     52
     53#endif
  • deleted file src/apps/resourceedit/ImageButton.cpp

    diff --git a/src/apps/resourceedit/ImageButton.cpp b/src/apps/resourceedit/ImageButton.cpp
    deleted file mode 100644
    index 7b0b8dd..0000000
    + -  
    1 /*
    2  * Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
    3  * All rights reserved. Distributed under the terms of the MIT license.
    4  */
    5 
    6 
    7 #include "ImageButton.h"
    8 
    9 #include <Bitmap.h>
    10 
    11 
    12 ImageButton::ImageButton(BRect frame, const char* name, BBitmap* image,
    13     BMessage* message, uint32 resizingMode = B_FOLLOW_NONE)
    14     :
    15     BButton(frame, name, "", message, resizingMode)
    16 {
    17     fImage = image;
    18 
    19     fDrawPoint.x = ((frame.RightTop().x - frame.LeftTop().x)
    20         - (image->Bounds().RightBottom().x + 1)) / 2;
    21 
    22     fDrawPoint.y = ((frame.LeftBottom().y - frame.LeftTop().y)
    23         - (image->Bounds().RightBottom().y + 1)) / 2;
    24 
    25     fInnerBounds = Bounds();
    26     fInnerBounds.InsetBy(3, 3);
    27 
    28     SetDrawingMode(B_OP_ALPHA);
    29 }
    30 
    31 
    32 ImageButton::~ImageButton()
    33 {
    34 
    35 }
    36 
    37 
    38 void
    39 ImageButton::Draw(BRect updateRect)
    40 {
    41     BButton::Draw(updateRect);
    42     DrawBitmap(fImage, fDrawPoint);
    43 
    44     if (!IsEnabled()) {
    45         rgb_color tempColor = HighColor();
    46         SetHighColor(255, 255, 255, 155);
    47         FillRect(fInnerBounds, B_SOLID_HIGH);
    48         SetHighColor(tempColor);
    49     }
    50 }
    51 
    52 
    53 void
    54 ImageButton::ResizeTo(float width, float height)
    55 {
    56     BButton::ResizeTo(width, height);
    57     fInnerBounds = Bounds();
    58     fInnerBounds.InsetBy(3, 3);
    59 }
    60 
    61 
    62 void
    63 ImageButton::SetBitmap(BBitmap* image)
    64 {
    65     fImage = image;
    66     Invalidate();
    67 }
  • deleted file src/apps/resourceedit/ImageButton.h

    diff --git a/src/apps/resourceedit/ImageButton.h b/src/apps/resourceedit/ImageButton.h
    deleted file mode 100644
    index e0c3de8..0000000
    + -  
    1 /*
    2  * Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
    3  * All rights reserved. Distributed under the terms of the MIT license.
    4  */
    5 #ifndef IMAGE_BUTTON_H
    6 #define IMAGE_BUTTON_H
    7 
    8 
    9 #include <Button.h>
    10 
    11 
    12 class ImageButton : public BButton
    13 {
    14 public:
    15                 ImageButton(BRect frame, const char* name, BBitmap* image,
    16                     BMessage* message, uint32 resizingMode);
    17                 ~ImageButton();
    18 
    19     void        Draw(BRect updateRect);
    20     void        ResizeTo(float width, float height);
    21 
    22     void        SetBitmap(BBitmap* image);
    23 
    24 private:
    25     BBitmap*    fImage;
    26     BPoint      fDrawPoint;
    27     BRect       fInnerBounds;
    28 
    29 };
    30 
    31 
    32 #endif
  • src/apps/resourceedit/Jamfile

    diff --git a/src/apps/resourceedit/Jamfile b/src/apps/resourceedit/Jamfile
    index 9507e9a..b392f77 100644
    a b SubDir HAIKU_TOP src apps resourceedit ;  
    22
    33UsePrivateHeaders interface shared ;
    44
     5local sourceDirs =
     6    edits
     7    interface
     8    settings
     9    support
     10;
     11
     12local sourceDir ;
     13
     14for sourceDir in $(sourceDirs) {
     15    SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src apps resourceedit $(sourceDir) ] ;
     16}
     17
    518Application ResourceEdit
    619    :
    7         DefaultTypes.cpp
     20        # edits
     21        AppFlagsEdit.cpp
     22        BooleanEdit.cpp
     23        EditView.cpp
     24        NormalEdit.cpp
     25
     26        # interface
    827        ImageButton.cpp
     28
     29        # settings
     30        GenericSettingsView.cpp
     31
     32        # support
     33        UndoContext.cpp
     34
     35        # .
     36        DefaultTypes.cpp
     37        EditWindow.cpp
    938        MainWindow.cpp
    1039        ResourceEdit.cpp
    1140        ResourceListView.cpp
    1241        ResourceRow.cpp
     42        SettingsFile.cpp
     43        SettingsWindow.cpp
     44
    1345        main.cpp
    1446    :
    1547        be
    Application ResourceEdit  
    1749        translation
    1850        libcolumnlistview.a
    1951        $(TARGET_LIBSTDC++)
    20 
    2152    :
    2253        ResourceEdit.rdef
    2354;
  • src/apps/resourceedit/MainWindow.cpp

    diff --git a/src/apps/resourceedit/MainWindow.cpp b/src/apps/resourceedit/MainWindow.cpp
    index d6413e3..1a04e8c 100644
    a b  
    77#include "MainWindow.h"
    88
    99#include "Constants.h"
     10#include "EditWindow.h"
    1011#include "ImageButton.h"
    1112#include "ResourceListView.h"
    1213#include "ResourceRow.h"
     14#include "SettingsFile.h"
     15#include "SettingsWindow.h"
     16#include "UndoContext.h"
    1317
     18#include <Alert.h>
    1419#include <Application.h>
     20#include <Box.h>
    1521#include <ColumnListView.h>
    1622#include <ColumnTypes.h>
    1723#include <Entry.h>
     
    2329#include <Path.h>
    2430#include <PopUpMenu.h>
    2531#include <Resources.h>
    26 #include <StatusBar.h>
    2732#include <String.h>
     33#include <StringView.h>
    2834#include <TextControl.h>
    2935#include <TranslationUtils.h>
    3036
     
    3945using namespace std;
    4046
    4147
    42 MainWindow::MainWindow(BRect frame, BEntry* assocEntry)
     48MainWindow::MainWindow(BRect frame, BEntry* assocEntry, SettingsFile* settings)
    4349    :
    44     BWindow(frame, NULL, B_DOCUMENT_WINDOW, 0)
     50    BWindow(frame, NULL, B_DOCUMENT_WINDOW, B_OUTLINE_RESIZE)
    4551{
    4652    fAssocEntry = assocEntry;
     53    fSettings = settings;
     54
     55    fUndoContext = new UndoContext();
     56
     57    AdaptSettings();
    4758
    4859    fSavePanel = NULL;
     60    fUnsavedChanges = false;
    4961
    5062    fMenuBar = new BMenuBar(BRect(0, 0, 600, 1), "fMenuBar");
    5163
    MainWindow::MainWindow(BRect frame, BEntry* assocEntry)  
    6476
    6577    fEditMenu = new BMenu("Edit", B_ITEMS_IN_COLUMN);
    6678    fUndoItem = new BMenuItem("Undo", new BMessage(MSG_UNDO), 'Z');
     79    fUndoItem->SetEnabled(false);
    6780    fRedoItem = new BMenuItem("Redo", new BMessage(MSG_REDO), 'Y');
     81    fRedoItem->SetEnabled(false);
    6882    fCutItem = new BMenuItem("Cut", new BMessage(MSG_CUT), 'X');
     83    fCutItem->SetEnabled(false);
    6984    fCopyItem = new BMenuItem("Copy", new BMessage(MSG_COPY), 'C');
     85    fCopyItem->SetEnabled(false);
    7086    fPasteItem = new BMenuItem("Paste", new BMessage(MSG_PASTE), 'V');
     87    fPasteItem->SetEnabled(false);
    7188    fClearItem = new BMenuItem("Clear", new BMessage(MSG_CLEAR));
    7289    fSelectAllItem = new BMenuItem("Select All",
    7390        new BMessage(MSG_SELECTALL), 'A');
    7491
     92    fToolsMenu = new BMenu("Tools", B_ITEMS_IN_COLUMN);
     93    fAddAppResourcesItem = new BMenuItem("Add app resources",
     94        new BMessage(MSG_ADDAPPRES));
     95    fSettingsItem = new BMenuItem("Settings", new BMessage(MSG_SETTINGS));
     96
    7597    fHelpMenu = new BMenu("Help", B_ITEMS_IN_COLUMN);
    7698
    7799    fResourceIDText = new BTextControl(BRect(0, 0, 47, 23).OffsetBySelf(8, 24),
    MainWindow::MainWindow(BRect frame, BEntry* assocEntry)  
    127149    fResourceList = new ResourceListView(listRect, "fResourceList",
    128150        B_FOLLOW_ALL, 0);
    129151
    130     fResourceList->AddColumn(new BIntegerColumn("ID", 48, 1, 999,
    131         B_ALIGN_RIGHT), 0);
     152    fResourceList->AddColumn(new BStringColumn("ID", 48, 1, 999,
     153        B_ALIGN_LEFT), 0);
    132154    fResourceList->AddColumn(new BStringColumn("Name", 156, 1, 999,
    133155        B_TRUNCATE_END, B_ALIGN_LEFT), 1);
    134156    fResourceList->AddColumn(new BStringColumn("Type", 56, 1, 999,
    MainWindow::MainWindow(BRect frame, BEntry* assocEntry)  
    140162    fResourceList->AddColumn(new BSizeColumn("Size", 74, 1, 999,
    141163        B_ALIGN_RIGHT), 5);
    142164
    143     fResourceList->SetLatchWidth(0);
     165    //fResourceList->SetLatchWidth(0);
    144166
    145167    fResourceList->SetTarget(this);
    146168    fResourceList->SetSelectionMessage(new BMessage(MSG_SELECTION));
     169    fResourceList->SetInvocationMessage(new BMessage(MSG_INVOCATION));
     170
     171    fStatsString = new BStringView(BRect(3, 2, 150, 13), "fStatsString", "");
     172    fStatsString->SetFontSize(11.0f);
     173
     174    fStatsBox = new BBox(BRect(0, 0, 150, 16), "fStatsBox");
     175    fStatsBox->SetBorder(B_PLAIN_BORDER);
    147176
    148177    AddChild(fMenuBar);
    149178
    MainWindow::MainWindow(BRect frame, BEntry* assocEntry)  
    170199        fEditMenu->AddSeparatorItem();
    171200        fEditMenu->AddItem(fSelectAllItem);
    172201
     202    fMenuBar->AddItem(fToolsMenu);
     203        fToolsMenu->AddItem(fAddAppResourcesItem);
     204        fToolsMenu->AddSeparatorItem();
     205        fToolsMenu->AddItem(fSettingsItem);
     206
    173207    fMenuBar->AddItem(fHelpMenu);
    174208
    175209    fToolbarView->AddChild(fResourceIDText);
    MainWindow::MainWindow(BRect frame, BEntry* assocEntry)  
    183217    AddChild(fToolbarView);
    184218
    185219    AddChild(fResourceList);
     220    fResourceList->AddStatusView(fStatsBox);
     221    fStatsBox->AddChild(fStatsString);
    186222
    187223    if (assocEntry != NULL) {
    188224        _SetTitleFromEntry();
    MainWindow::MainWindow(BRect frame, BEntry* assocEntry)  
    195231
    196232MainWindow::~MainWindow()
    197233{
    198 
     234    delete fUndoContext;
    199235}
    200236
    201237
    202238bool
    203239MainWindow::QuitRequested()
    204240{
    205     // TODO: Check if file is saved.
     241    // CAUTION: Do not read the body of this function if you
     242    //          are known to suffer from gotophobia.
     243
     244    if (fUnsavedChanges) {
     245        Activate();
     246
     247        char nameBuffer[B_FILE_NAME_LENGTH];
    206248
     249        if (fAssocEntry != NULL)
     250            fAssocEntry->GetName(nameBuffer);
     251        else
     252            strcpy(nameBuffer, "Untitled");
     253
     254        BString warning = "";
     255        warning << "Save changse to'";
     256        warning << nameBuffer;
     257        warning << "' before closing?";
     258
     259        BAlert* alert = new BAlert("Save", warning.String(),
     260            "Cancel", "Don't save", "Save",
     261            B_WIDTH_AS_USUAL, B_OFFSET_SPACING, B_WARNING_ALERT);
     262
     263        alert->SetShortcut(0, B_ESCAPE);
     264
     265        int32 result = alert->Go();
     266
     267        switch (result) {
     268            case 0:
     269                return false;
     270            case 1:
     271                goto quit;
     272            case 2:
     273            {
     274                _Save();
     275
     276                if (fUnsavedChanges)
     277                    return false;
     278                else
     279                    goto quit;
     280            }
     281        }
     282    }
     283
     284    quit:
    207285    BMessage* msg = new BMessage(MSG_CLOSE);
    208286    msg->AddPointer("window", (void*)this);
    209287    be_app->PostMessage(msg);
    MainWindow::SelectionChanged()  
    218296        fMoveUpButton->SetEnabled(false);
    219297        fMoveDownButton->SetEnabled(false);
    220298        fRemoveButton->SetEnabled(false);
     299
     300        fCutItem->SetEnabled(false);
     301        fCopyItem->SetEnabled(false);
    221302    } else {
    222303        fRemoveButton->SetEnabled(true);
    223304        fMoveUpButton->SetEnabled(!fResourceList->RowAt(0)->IsSelected());
    224305        fMoveDownButton->SetEnabled(!fResourceList->RowAt(
    225306            fResourceList->CountRows() - 1)->IsSelected());
     307
     308        fCutItem->SetEnabled(true);
     309        fCopyItem->SetEnabled(true);
    226310    }
    227311}
    228312
    229313
    230314void
     315MainWindow::MouseDown(BPoint point)
     316{
     317
     318}
     319
     320
     321void
    231322MainWindow::MessageReceived(BMessage* msg)
    232323{
    233324    switch (msg->what) {
    MainWindow::MessageReceived(BMessage* msg)  
    282373            break;
    283374
    284375        case MSG_UNDO:
    285             // TODO: Implement.
    286             PRINT(("[MSG_UNDO]: Not yet implemented."));
     376            fUndoContext->Undo();
     377            _RefreshUndoRedo();
    287378            break;
    288379
    289380        case MSG_REDO:
    290             // TODO: Implement.
    291             PRINT(("[MSG_REDO]: Not yet implemented."));
     381            fUndoContext->Redo();
     382            _RefreshUndoRedo();
    292383            break;
    293384
    294385        case MSG_CUT:
    MainWindow::MessageReceived(BMessage* msg)  
    307398            break;
    308399
    309400        case MSG_CLEAR:
    310             fResourceList->Clear();
     401        {
     402            BList* rows = new BList();
     403
     404            for (int32 i = 0; i < fResourceList->CountRows(); i++) {
     405                ResourceRow* row = (ResourceRow*)fResourceList->RowAt(i);
     406                row->ActionIndex = i;
     407                rows->AddItem(row);
     408            }
     409
     410            _Do(new RemoveAction("Clear", fResourceList, rows));
     411
    311412            SelectionChanged();
    312413            break;
    313 
     414        }
    314415        case MSG_SELECTALL:
    315416        {
    316417            for (int32 i = 0; i < fResourceList->CountRows(); i++)
    MainWindow::MessageReceived(BMessage* msg)  
    319420            SelectionChanged();
    320421            break;
    321422        }
     423        case MSG_SETTINGS:
     424            be_app->PostMessage(MSG_SETTINGS);
     425            break;
     426
    322427        case MSG_ADD:
    323428        {
    324429            // Thank you, François Claus :D Merry Christmas!
    MainWindow::MessageReceived(BMessage* msg)  
    326431            int32 ix = fResourceTypePopUp->FindMarkedIndex();
    327432
    328433            if (ix != -1) {
     434                BList* rows = new BList();
     435
    329436                ResourceRow* row = new ResourceRow();
    330437                row->SetResourceID(_NextResourceID());
    331438                row->SetResourceType(kDefaultTypes[ix].type);
    332                 row->SetResourceTypeCode(kDefaultTypes[ix].typeCode);
    333                 row->SetResourceRawData(kDefaultData);
     439                row->SetResourceStringCode(kDefaultTypes[ix].code);
     440                row->SetResourceData(kDefaultTypes[ix].data);
    334441                row->SetResourceSize(kDefaultTypes[ix].size);
    335                 fResourceList->AddRow(row);
     442                row->ActionIndex = fResourceList->CountRows(NULL);
     443
     444                rows->AddItem(row);
     445
     446                _Do(new AddAction("Add", fResourceList, rows));
    336447            }
    337448
    338449            break;
    339450        }
    340451        case MSG_REMOVE:
    341452        {
     453            BList* rows = new BList();
     454
    342455            for (int i = 0; i < fResourceList->CountRows(); i++) {
    343                 BRow* row = fResourceList->RowAt(i);
     456                ResourceRow* row = (ResourceRow*)fResourceList->RowAt(i);
    344457
    345458                if (row->IsSelected()) {
    346                     fResourceList->RemoveRow(row);
    347                     i--;
     459                    row->ActionIndex = i;
     460                    rows->AddItem(row);
    348461                }
    349462            }
    350463
     464            if (!rows->IsEmpty())
     465                _Do(new RemoveAction("Remove", fResourceList, rows));
     466            else
     467                delete rows;
     468
    351469            break;
    352470        }
    353471        case MSG_MOVEUP:
    354472        {
    355             for (int i = 1; i < fResourceList->CountRows(); i++) {
    356                 BRow* row = fResourceList->RowAt(i);
     473            BList* rows = new BList();
    357474
    358                 if (row->IsSelected())
    359                     fResourceList->SwapRows(i, i - 1);
     475            for (int i = 1; i < fResourceList->CountRows(); i++) {
     476                ResourceRow* row = (ResourceRow*)fResourceList->RowAt(i);
    360477
     478                if (row->IsSelected()) {
     479                    row->ActionIndex = i;
     480                    rows->AddItem(row);
     481                }
    361482            }
    362483
    363             fResourceList->ClearSortColumns();
    364             SelectionChanged();
     484            _Do(new MoveUpAction("Move Up", fResourceList, rows));
     485
    365486            break;
    366487        }
    367488        case MSG_MOVEDOWN:
    368489        {
    369             for (int i = fResourceList->CountRows() - 1 - 1; i >= 0; i--) {
    370                 BRow* row = fResourceList->RowAt(i);
     490            BList* rows = new BList();
     491
     492            for (int i = 0; i < fResourceList->CountRows() - 1; i++) {
     493                ResourceRow* row = (ResourceRow*)fResourceList->RowAt(i);
    371494
    372                 if (row->IsSelected())
    373                     fResourceList->SwapRows(i, i + 1);
     495                if (row->IsSelected()) {
     496                    row->ActionIndex = i;
     497                    rows->AddItem(row);
     498                }
    374499            }
    375500
    376             fResourceList->ClearSortColumns();
    377             SelectionChanged();
     501            _Do(new MoveDownAction("Move Down", fResourceList, rows));
     502
    378503            break;
    379504        }
    380505        case MSG_SELECTION:
    381506            SelectionChanged();
    382507            break;
    383508
     509        case MSG_INVOCATION:
     510        {
     511            BRect frame = Frame();
     512
     513            new EditWindow(BRect(frame.left + 50, frame.top + 50,
     514                frame.left + 300, frame.top + 350),
     515                (ResourceRow*)fResourceList->CurrentSelection());
     516
     517            break;
     518        }
     519        case MSG_SETTINGS_APPLY:
     520            AdaptSettings();
     521            break;
     522
    384523        default:
    385524            BWindow::MessageReceived(msg);
    386525    }
    MainWindow::MessageReceived(BMessage* msg)  
    388527
    389528
    390529void
     530MainWindow::AdaptSettings()
     531{
     532    fUndoContext->SetLimit(fSettings->UndoLimit);
     533}
     534
     535
     536void
    391537MainWindow::_SetTitleFromEntry()
    392538{
    393539    char nameBuffer[B_FILE_NAME_LENGTH];
    MainWindow::_Save(BEntry* entry)  
    429575        }
    430576    }
    431577
    432     /*BPath path;
     578    BPath path;
    433579    entry->GetPath(&path);
    434580
    435581    // I wouldn't use std:: if BFile had cooler stuff.
    MainWindow::_Save(BEntry* entry)  
    440586    time_t timeNow = time(0);
    441587
    442588
    443     out << "/-" << endl;
    444     out << " - This file is auto-generated by Haiku ResourceEdit." << endl;
    445     out << " - Time: " << ctime((const time_t*)&timeNow);
    446     out << " -\" << endl;
     589    out << "/*" << endl;
     590    out << " * This file is auto-generated by Haiku ResourceEdit." << endl;
     591    out << " * Time: " << ctime((const time_t*)&timeNow);
     592    out << " */" << endl;
    447593
    448594    for (int32 i = 0; i < fResourceList->CountRows(); i++) {
    449595        ResourceRow* row = (ResourceRow*)fResourceList->RowAt(i);
    MainWindow::_Save(BEntry* entry)  
    451597        out << endl;
    452598        out << "resource";
    453599
    454         if (true) {
    455             // TODO: Implement no-ID cases.
    456 
     600        if (row->ResourceStringID()[0] != '\0') {
    457601            out << "(" << row->ResourceID();
    458602
    459             if (row->ResourceName()[0] != '\0') {
    460                 out << ", \"" << row->ResourceName() << "\"" << endl;
    461             }
     603            if (row->ResourceName()[0] != '\0')
     604                out << ", \"" << row->ResourceName() << "\"";
    462605
    463             out << ") ";
     606            out << ")";
     607        } else {
     608            if (row->ResourceName()[0] != '\0')
     609                out << "(\"" << row->ResourceName() << "\")";
    464610        }
    465611
    466         if (row->ResourceTypeCode()[0] != '\0')
    467             out << "#\'" << row->ResourceTypeCode() << "\' ";
     612        out << " ";
     613
     614        if (row->ResourceStringCode()[0] != '\0')
     615            out << "#\'" << row->ResourceStringCode() << "\' ";
    468616
    469617        if (strcmp(row->ResourceType(), "raw") != 0)
    470618            out << row->ResourceType() << ' ' << row->ResourceData();
    MainWindow::_Save(BEntry* entry)  
    475623            out << "}";
    476624        }
    477625
    478         out << endl;
     626        out << ";" << endl;
    479627    }
    480628
    481     out.close();*/
    482 
    483     // Commented out whole output section. Switching to .rsrc files to
    484     // close Part 1 of GCI task.
    485 
    486     // TODO: Implement exporting to .rdef and/or other formats.
     629    out.close();
    487630
     631    // Killed code: Export to .rsrc
    488632
    489     BFile* file = new BFile(entry, B_READ_WRITE | B_CREATE_FILE);
     633    /*BFile* file = new BFile(entry, B_READ_WRITE | B_CREATE_FILE);
    490634    BResources output(file, true);
    491635    delete file;
    492636
    493637    for (int32 i = 0; i < fResourceList->CountRows(); i++) {
    494638        ResourceRow* row = (ResourceRow*)fResourceList->RowAt(i);
    495         output.AddResource(row->ResourceTypeCode(), row->ResourceID(),
     639
     640        output.AddResource(row->ResourceCode(), row->ResourceID(),
    496641            row->ResourceRawData(), row->ResourceSize(), row->ResourceName());
    497642    }
    498643
    499     output.Sync();
     644    output.Sync();*/
     645
     646    fUnsavedChanges = false;
    500647}
    501648
    502649
    503650void
    504651MainWindow::_Load()
    505652{
    506     /*BPath path;
     653    // CAUTION: Here be dragons.
     654
     655    // [Initialization phase]
     656
     657    BPath path;
    507658    struct stat st;
    508659
    509660    fAssocEntry->GetPath(&path);
    510661    fAssocEntry->GetStat(&st);
    511662
    512663    int fd = open(path.Path(), 0);
     664
    513665    const char* in = (const char*)mmap(NULL, st.st_size, PROT_READ,
    514666        MAP_SHARED, fd, 0);
    515667
    516     // TODO: Fix stucking bug.
    517     // TODO: Parse data.
     668    // [Setup phase]
     669
     670    enum {
     671        T_STATE_NORMAL,
     672        T_STATE_COMMENT,
     673        T_STATE_MULTILINE_COMMENT,
     674        T_STATE_STRING,
     675    } t_state = T_STATE_NORMAL;
     676
     677    char quoteType = '\0';
     678
     679    char escChars[256];
     680
     681    for (int32 i = 0; i < 256; i++)
     682        escChars[i] = ~(char)0;
     683
     684    escChars['n'] = '\n';
     685    escChars['t'] = '\t';
     686    escChars['r'] = '\r';
     687    escChars['0'] = '\0';
     688    escChars['"'] = '\"';
     689    escChars['\'']= '\'';
     690
     691    // TODO: Add other escape sequences?
     692    // Multichar escape sequences cannot be resolved with this.
     693
     694    BString buffer = "";
     695    BList* tokens = new BList();
     696
     697    BList* errors = new BList();
     698        // Multiple errors are allowed, but currently unused.
     699
     700    BList* rows = new BList();
     701
     702    // [Tokenization phase]
    518703
    519704    for (int32 i = 0; i < st.st_size - 1; i++) {
    520         //...
    521     }*/
     705        if (t_state == T_STATE_NORMAL) {
     706            if (in[i] == ' ' || in[i] == '\t' || in[i] == '\n'
     707                 || in[i] == '\r') {
     708
     709                if (buffer != "") {
     710                    tokens->AddItem(new BString(buffer));
     711                    buffer = "";
     712                }
     713
     714                continue;
     715            }
     716
     717            if (in[i] == ',' || in[i] == ';' || in[i] == '{' || in[i] == '}'
     718                || in[i] == '(' || in[i] == ')') {
     719                if (buffer != "") {
     720                    tokens->AddItem(new BString(buffer));
     721                    buffer = in[i];
     722                    tokens->AddItem(new BString(buffer));
     723                    buffer = "";
     724                }
     725
     726                continue;
     727            }
     728
     729            if (in[i] == '"' || in[i] == '\'') {
     730                t_state = T_STATE_STRING;
     731                quoteType = in[i];
     732                buffer += in[i];
     733                continue;
     734            }
     735
     736            if (in[i] == '/') {
     737                if (in[i + 1] == '/') {
     738                    t_state = T_STATE_COMMENT;
     739                    continue;
     740                }
     741
     742                if (in[i + 1] == '*') {
     743                    t_state = T_STATE_MULTILINE_COMMENT;
     744                    continue;
     745                }
     746            }
     747
     748            buffer += in[i];
     749
     750        } else if (t_state == T_STATE_COMMENT) {
     751            if (in[i] == '\n') {
     752                t_state = T_STATE_NORMAL;
     753                continue;
     754            }
     755        } else if (t_state == T_STATE_MULTILINE_COMMENT) {
     756            if (in[i] == '*' && in[i + 1] == '/') {
     757                t_state = T_STATE_NORMAL;
     758                i++;
     759                continue;
     760            }
     761        } else if (t_state == T_STATE_STRING) {
     762            if (in[i] == '\\' && escChars[in[i]] != ~(char)0) {
     763                buffer += escChars[in[i]];
     764                i++;
     765                continue;
     766            }
     767
     768            if (in[i] == quoteType) {
     769                buffer += in[i];
     770                tokens->AddItem(new BString(buffer));
     771                buffer = "";
     772                t_state = T_STATE_NORMAL;
     773                continue;
     774            }
     775
     776            buffer += in[i];
     777        } else {
     778            // This can't even happen.
     779        }
     780    }
     781
     782    if (t_state == T_STATE_MULTILINE_COMMENT)
     783        errors->AddItem(new BString(
     784            "Multi-line comment not closed by end of file."));
     785    else if (t_state == T_STATE_STRING)
     786        errors->AddItem(new BString("String not closed by end of file."));
     787    else {
     788        // [Parsing phase]
     789
     790        for (int32 i = 0; i < tokens->CountItems(); i++) {
     791            BString& token = *(BString*)tokens->ItemAt(i);
     792
     793            if (token == "resource") {
     794                ResourceRow* row = new ResourceRow();
     795
     796                token = *(BString*)tokens->ItemAt(++i);
     797
     798                if (token[0] == '(') {
     799                    BList args;
     800                    bool wantComma = false;
     801
     802                    while (true) {
     803                        token = *(BString*)tokens->ItemAt(++i);
     804
     805                        if (token[0] == ')')
     806                            break;
     807
     808                        if (wantComma) {
     809                            if (token[0] != ',') {
     810                                errors->AddItem(new BString("Expected ','."));
     811                                break;
     812                            }
     813
     814                            wantComma = false;
     815                        } else {
     816                            args.AddItem(tokens->ItemAt(i));
     817                            wantComma = true;
     818                        }
     819                    }
     820
     821                    if (errors->CountItems() > 0)
     822                        break;
     823
     824                    token = *(BString*)tokens->ItemAt(++i);
     825
     826                    if (args.CountItems() > 2) {
     827                        errors->AddItem(new BString(
     828                            "Too many arguments for resource identifier."));
     829                        break;
     830                    }
     831
     832                    if (args.CountItems() >= 1) {
     833                        BString& arg = *(BString*)args.ItemAt(0);
     834
     835                        if (arg[0] == '"') {
     836                            errors->AddItem(new BString(
     837                                "Resource ID cannot be a string."));
     838                            break;
     839                        }
     840
     841                        row->SetResourceStringID(arg);
     842                    }
     843
     844                    if (args.CountItems() == 2) {
     845                        BString& arg = *(BString*)args.ItemAt(1);
     846
     847                        if (arg[0] != '"') {
     848                            errors->AddItem(new BString(
     849                                "Resource name must be a string."));
     850                            break;
     851                        }
     852
     853                        row->SetResourceName(arg);
     854                    }
     855                }
     856
     857                if (token[0] == '#') {
     858                    if (token.Length() != 7
     859                        || token[1] != '\'' || token[6] != '\'') {
     860                        errors->AddItem(new BString(
     861                            "Invalid syntax for resource type-code."));
     862                        break;
     863                    }
     864
     865                    BString code;
     866                    token.CopyInto(code, 2, 4);
     867                    row->SetResourceStringCode(code);
     868
     869                    token = *(BString*)tokens->ItemAt(++i);
     870                }
     871
     872                if (token[0] == '(') {
     873                    BString& type = *(BString*)tokens->ItemAt(++i);
     874                    token = *(BString*)tokens->ItemAt(++i);
     875
     876                    if (token[0] != ')') {
     877                        errors->AddItem(new BString(
     878                            "Expected ')'."));
     879                        break;
     880                    }
     881
     882                    row->SetResourceType(type);
     883                }
     884
     885            } else if (token == "type") {
     886                // TODO: Implement.
     887            } else if (token == "enum") {
     888                // TODO: Implement.
     889            }
     890        }
     891    }
     892
     893    // [Result phase]
     894
     895    if (errors->CountItems() > 0) {
     896        for (int32 i = 0; i < errors->CountItems(); i++) {
     897            BString& error = *(BString*)errors->ItemAt(i);
     898            PRINT(("ERROR: %s\n", error.String()));
     899            delete (BString*)tokens->ItemAt(i);
     900        }
     901
     902        delete errors;
     903    } else {
     904        for (int32 i = 0; i < rows->CountItems(); i++) {
     905            ResourceRow* row = (ResourceRow*)rows->ItemAt(i);
     906            PRINT(("[Resource]\n"));
     907            PRINT(("id   = %s\n", row->ResourceStringID()));
     908            PRINT(("name = %s\n", row->ResourceName()));
     909            // ...
     910            PRINT(("\n"));
     911        }
     912    }
    522913
    523     // Commented out input section. Same reason as above.
     914    // [Cleanup phase]
    524915
    525     // TODO: Implement importing from .rdef and/or other formats.
     916    for (int32 i = 0; i < tokens->CountItems(); i++)
     917        delete (BString*)tokens->ItemAt(i);
    526918
    527     BFile* file = new BFile(fAssocEntry, B_READ_ONLY);
     919    delete tokens;
     920
     921    munmap((void*)in, st.st_size);
     922
     923    // Killed code: Import from .rsrc
     924
     925    /*BFile* file = new BFile(fAssocEntry, B_READ_ONLY);
    528926    BResources input(file);
    529927    delete file;
    530928
    MainWindow::_Load()  
    538936        row->SetResourceID(id);
    539937        row->SetResourceName(name);
    540938        row->SetResourceSize(size);
    541         row->SetResourceTypeCode(code);
     939        row->SetResourceCode(code);
    542940        row->SetResourceRawData(input.LoadResource(code, id, &size));
    543941        fResourceList->AddRow(row);
    544     }
     942    }*/
    545943}
    546944
    547945
    MainWindow::_NextResourceID()  
    560958
    561959    return currentID;
    562960}
     961
     962
     963void
     964MainWindow::_RefreshStats()
     965{
     966    const size_t kB = 1024;
     967    const size_t MB = 1024 * 1024;
     968    const size_t GB = 1024 * 1024 * 1024;
     969
     970    size_t size = 0;
     971
     972    BString text = "";
     973
     974    text << fResourceList->CountRows();
     975    text << " resources, ";
     976
     977    for (int32 i = 0; i < fResourceList->CountRows(); i++) {
     978        ResourceRow* row = (ResourceRow*)fResourceList->RowAt(i);
     979        size += row->ResourceSize();
     980    }
     981
     982    if (size >= GB) {
     983        text << (double)size / GB;
     984        text << " GB";
     985    } else if (size >= MB) {
     986        text << (double)size / MB;
     987        text << " MB";
     988    } else if (size >= kB) {
     989        text << (double)size / kB;
     990        text << " kB";
     991    } else {
     992        text << size;
     993        text << " bytes";
     994    }
     995
     996    fStatsString->SetText(text);
     997}
     998
     999
     1000void
     1001MainWindow::_RefreshUndoRedo()
     1002{
     1003    if (fUndoContext->CanUndo()) {
     1004        fUndoItem->SetEnabled(true);
     1005        fUndoItem->SetLabel(fUndoContext->UndoLabel().Prepend("Undo "));
     1006    } else {
     1007        fUndoItem->SetEnabled(false);
     1008        fUndoItem->SetLabel("Undo");
     1009    }
     1010
     1011    if (fUndoContext->CanRedo()) {
     1012        fRedoItem->SetEnabled(true);
     1013        fRedoItem->SetLabel(fUndoContext->RedoLabel().Prepend("Redo "));
     1014    } else {
     1015        fRedoItem->SetEnabled(false);
     1016        fRedoItem->SetLabel("Redo");
     1017    }
     1018}
     1019
     1020
     1021void
     1022MainWindow::_Do(UndoContext::Action* action)
     1023{
     1024    fUnsavedChanges = true;
     1025    fUndoContext->Do(action);
     1026    _RefreshStats();
     1027    _RefreshUndoRedo();
     1028}
     1029
     1030
     1031MainWindow::AddAction::AddAction(const BString& label,
     1032    ResourceListView* list, BList* rows)
     1033    :
     1034    UndoContext::Action(label)
     1035{
     1036    fList = list;
     1037    fRows = rows;
     1038    fAdded = false;
     1039}
     1040
     1041
     1042MainWindow::AddAction::~AddAction()
     1043{
     1044    if (!fAdded)
     1045        for (int32 i = 0; i < fRows->CountItems(); i++)
     1046            delete (ResourceRow*)fRows->ItemAt(i);
     1047
     1048    delete fRows;
     1049}
     1050
     1051
     1052void
     1053MainWindow::AddAction::Do()
     1054{
     1055    for (int32 i = 0; i < fRows->CountItems(); i++) {
     1056        ResourceRow* row = (ResourceRow*)fRows->ItemAt(i);
     1057        fList->AddRow(row, row->ActionIndex, row->Parent);
     1058    }
     1059
     1060    fAdded = true;
     1061}
     1062
     1063
     1064void
     1065MainWindow::AddAction::Undo()
     1066{
     1067    for (int32 i = 0; i < fRows->CountItems(); i++)
     1068            fList->RemoveRow((ResourceRow*)fRows->ItemAt(i));
     1069
     1070    fAdded = false;
     1071}
     1072
     1073
     1074MainWindow::RemoveAction::RemoveAction(const BString& label,
     1075    ResourceListView* list, BList* rows)
     1076    :
     1077    UndoContext::Action(label)
     1078{
     1079    fList = list;
     1080    fRows = rows;
     1081    fRemoved = false;
     1082}
     1083
     1084
     1085MainWindow::RemoveAction::~RemoveAction()
     1086{
     1087    if (fRemoved)
     1088        for (int32 i = 0; i < fRows->CountItems(); i++)
     1089            delete (ResourceRow*)fRows->ItemAt(i);
     1090
     1091    delete fRows;
     1092}
     1093
     1094
     1095void
     1096MainWindow::RemoveAction::Do()
     1097{
     1098    for (int32 i = 0; i < fRows->CountItems(); i++)
     1099        fList->RemoveRow((ResourceRow*)fRows->ItemAt(i));
     1100
     1101    fRemoved = true;
     1102}
     1103
     1104
     1105void
     1106MainWindow::RemoveAction::Undo()
     1107{
     1108    for (int32 i = 0; i < fRows->CountItems(); i++) {
     1109        ResourceRow* row = (ResourceRow*)fRows->ItemAt(i);
     1110
     1111        fList->AddRow(row, row->ActionIndex, row->Parent);
     1112    }
     1113
     1114    fRemoved = false;
     1115}
     1116
     1117// TODO: Implement EditAction
     1118
     1119MainWindow::MoveUpAction::MoveUpAction(const BString& label,
     1120    ResourceListView* list, BList* rows)
     1121    :
     1122    UndoContext::Action(label)
     1123{
     1124    fList = list;
     1125    fRows = rows;
     1126}
     1127
     1128
     1129MainWindow::MoveUpAction::~MoveUpAction()
     1130{
     1131    delete fRows;
     1132}
     1133
     1134
     1135void
     1136MainWindow::MoveUpAction::Do()
     1137{
     1138    for (int32 i = 0; i < fRows->CountItems(); i++) {
     1139        ResourceRow* row = (ResourceRow*)fRows->ItemAt(i);
     1140
     1141        fList->SwapRows(row->ActionIndex, row->ActionIndex - 1,
     1142            row->Parent, row->Parent);
     1143
     1144        row->ActionIndex--;
     1145    }
     1146
     1147    fList->SelectionChanged();
     1148}
     1149
     1150
     1151void
     1152MainWindow::MoveUpAction::Undo()
     1153{
     1154    for (int32 i = fRows->CountItems() - 1; i >= 0; i--) {
     1155        ResourceRow* row = (ResourceRow*)fRows->ItemAt(i);
     1156
     1157        fList->SwapRows(row->ActionIndex, row->ActionIndex + 1,
     1158            row->Parent, row->Parent);
     1159
     1160        row->ActionIndex++;
     1161    }
     1162
     1163    fList->SelectionChanged();
     1164}
     1165
     1166MainWindow::MoveDownAction::MoveDownAction(const BString& label,
     1167    ResourceListView* list, BList* rows)
     1168    :
     1169    UndoContext::Action(label)
     1170{
     1171    fList = list;
     1172    fRows = rows;
     1173}
     1174
     1175
     1176MainWindow::MoveDownAction::~MoveDownAction()
     1177{
     1178    delete fRows;
     1179}
     1180
     1181
     1182void
     1183MainWindow::MoveDownAction::Do()
     1184{
     1185    for (int32 i = fRows->CountItems() - 1; i >= 0; i--) {
     1186        ResourceRow* row = (ResourceRow*)fRows->ItemAt(i);
     1187
     1188        fList->SwapRows(row->ActionIndex, row->ActionIndex + 1,
     1189            row->Parent, row->Parent);
     1190
     1191        row->ActionIndex++;
     1192    }
     1193
     1194    fList->SelectionChanged();
     1195}
     1196
     1197
     1198void
     1199MainWindow::MoveDownAction::Undo()
     1200{
     1201    for (int32 i = 0; i < fRows->CountItems(); i++) {
     1202        ResourceRow* row = (ResourceRow*)fRows->ItemAt(i);
     1203
     1204        fList->SwapRows(row->ActionIndex, row->ActionIndex - 1,
     1205            row->Parent, row->Parent);
     1206
     1207        row->ActionIndex--;
     1208    }
     1209
     1210    fList->SelectionChanged();
     1211}
     1212
  • src/apps/resourceedit/MainWindow.h

    diff --git a/src/apps/resourceedit/MainWindow.h b/src/apps/resourceedit/MainWindow.h
    index bc1523f..b903e1e 100644
    a b  
    66#define MAIN_WINDOW_H
    77
    88
     9#include "UndoContext.h"
     10
    911#include <Window.h>
    1012
    1113
    1214class ImageButton;
     15class ResourceListView;
     16class ResourceRow;
     17class SettingsFile;
    1318
    14 class BColumnListView;
     19class BBox;
    1520class BEntry;
    1621class BFilePanel;
    1722class BMenu;
    class BMenuField;  
    2025class BMenuItem;
    2126class BMessage;
    2227class BPopUpMenu;
     28class BStringView;
    2329class BTextControl;
    2430
    2531
    2632class MainWindow : public BWindow {
    2733public:
    28                         MainWindow(BRect frame, BEntry* entry);
     34                        MainWindow(BRect frame, BEntry* entry, SettingsFile* settings);
    2935                        ~MainWindow();
    3036
    3137    bool                QuitRequested();
     38    void                MouseDown(BPoint point);
    3239    void                MessageReceived(BMessage* msg);
    3340    void                SelectionChanged();
    3441
     42    void                AdaptSettings();
     43
    3544private:
    3645    BEntry*             fAssocEntry;
     46    SettingsFile*       fSettings;
     47
     48    BFilePanel*         fSavePanel;
     49    bool                fUnsavedChanges;
     50
     51    UndoContext*        fUndoContext;
    3752
    3853    BMenuBar*           fMenuBar;
    3954
    private:  
    5671    BMenuItem*          fClearItem;
    5772    BMenuItem*          fSelectAllItem;
    5873
     74    BMenu*              fToolsMenu;
     75    BMenuItem*          fAddAppResourcesItem;
     76    BMenuItem*          fSettingsItem;
     77
    5978    BMenu*              fHelpMenu;
    6079
    6180    BTextControl*       fResourceIDText;
    private:  
    6887    ImageButton*        fMoveUpButton;
    6988    ImageButton*        fMoveDownButton;
    7089
    71     BColumnListView*    fResourceList;
    72 
    73     BFilePanel*         fSavePanel;
     90    ResourceListView*   fResourceList;
     91    BBox*               fStatsBox;
     92    BStringView*        fStatsString;
    7493
    7594    void                _SetTitleFromEntry();
    7695    void                _SaveAs();
    private:  
    7998
    8099    int32               _NextResourceID();
    81100
     101    void                _RefreshStats();
     102    void                _RefreshUndoRedo();
     103    void                _Do(UndoContext::Action* action);
     104
     105    class AddAction : public UndoContext::Action {
     106    public:
     107                            AddAction(const BString& label,
     108                                ResourceListView* list, BList* rows);
     109                            ~AddAction();
     110
     111        void                Do();
     112        void                Undo();
     113
     114    private:
     115        ResourceListView*   fList;
     116        BList*              fRows;
     117        bool                fAdded;
     118
     119    };
     120
     121    class RemoveAction : public UndoContext::Action {
     122    public:
     123                            RemoveAction(const BString& label,
     124                                ResourceListView* list, BList* rows);
     125                            ~RemoveAction();
     126
     127        void                Do();
     128        void                Undo();
     129
     130    private:
     131        ResourceListView*   fList;
     132        BList*              fRows;
     133        bool                fRemoved;
     134
     135    };
     136
     137    class EditAction : public UndoContext::Action {
     138    public:
     139                            EditAction(const BString& label,
     140                                ResourceListView* list,
     141                                ResourceRow* rowold, ResourceRow* rownew);
     142                            ~EditAction();
     143
     144        void                Do();
     145        void                Undo();
     146
     147    private:
     148        ResourceListView*   fList;
     149        ResourceRow*        fRowOld;
     150        ResourceRow*        fRowNew;
     151
     152    };
     153
     154    class MoveUpAction : public UndoContext::Action {
     155    public:
     156                            MoveUpAction(const BString& label,
     157                                ResourceListView* list, BList* rows);
     158                            ~MoveUpAction();
     159
     160        void                Do();
     161        void                Undo();
     162
     163    private:
     164        ResourceListView*   fList;
     165        BList*              fRows;
     166
     167    };
     168
     169    class MoveDownAction : public UndoContext::Action {
     170    public:
     171                            MoveDownAction(const BString& label,
     172                                ResourceListView* list, BList* rows);
     173                            ~MoveDownAction();
     174
     175        void                Do();
     176        void                Undo();
     177
     178    private:
     179        ResourceListView*   fList;
     180        BList*              fRows;
     181
     182    };
    82183};
    83184
    84185
  • src/apps/resourceedit/ResourceEdit.cpp

    diff --git a/src/apps/resourceedit/ResourceEdit.cpp b/src/apps/resourceedit/ResourceEdit.cpp
    index 2ff1a57..977e463 100644
    a b  
    99#include "AboutWindow.h"
    1010#include "Constants.h"
    1111#include "MainWindow.h"
     12#include "SettingsFile.h"
     13#include "SettingsWindow.h"
    1214
    1315#include <Entry.h>
    1416#include <FilePanel.h>
    ResourceEdit::ResourceEdit()  
    2325
    2426    fOpenPanel = new BFilePanel(B_OPEN_PANEL, &be_app_messenger, NULL, 0, true,
    2527        new BMessage(MSG_OPEN_DONE));
     28
     29    fSettings = new SettingsFile("resourceedit_settings");
     30    fSettings->Load();
     31
     32    fSettingsWindow = NULL;
    2633}
    2734
    2835
    ResourceEdit::MessageReceived(BMessage* msg)  
    6875        }
    6976        case MSG_SAVEALL:
    7077        {
    71             for (int32 i = 0; i < fWindowList.CountItems(); i++)
    72                 ((MainWindow*)fWindowList.ItemAt(i))->PostMessage(MSG_SAVE);
     78            for (int32 i = 0; i < fWindowList.CountItems(); i++) {
     79                MainWindow* window = ((MainWindow*)fWindowList.ItemAt(i));
     80                window->PostMessage(MSG_SAVE);
     81            }
     82
     83            break;
     84        }
     85        case MSG_SETTINGS:
     86        {
     87            if (fSettingsWindow != NULL)
     88                fSettingsWindow->Activate();
     89            else
     90                fSettingsWindow = new SettingsWindow(fSettings);
    7391
    7492            break;
    7593        }
     94        case MSG_SETTINGS_APPLY:
     95        {
     96            for (int32 i = 0; i < fWindowList.CountItems(); i++) {
     97                MainWindow* window = ((MainWindow*)fWindowList.ItemAt(i));
     98                window->PostMessage(MSG_SETTINGS_APPLY);
     99            }
     100
     101            break;
     102        }
     103        case MSG_SETTINGS_CLOSED:
     104            fSettingsWindow = NULL;
     105            break;
     106
    76107        default:
    77108            BApplication::MessageReceived(msg);
    78109    }
    ResourceEdit::ReadyToRun()  
    98129void
    99130ResourceEdit::_CreateWindow(BEntry* assocEntry)
    100131{
    101     MainWindow* window = new MainWindow(_Cascade(), assocEntry);
     132    MainWindow* window = new MainWindow(_Cascade(), assocEntry, fSettings);
    102133
    103134    fWindowList.AddItem(window);
    104135
  • src/apps/resourceedit/ResourceEdit.h

    diff --git a/src/apps/resourceedit/ResourceEdit.h b/src/apps/resourceedit/ResourceEdit.h
    index dcdf976..6168fcf 100644
    a b  
    1010
    1111
    1212class MainWindow;
     13class SettingsFile;
     14class SettingsWindow;
    1315
    1416class BEntry;
    1517class BFilePanel;
    private:  
    3032
    3133    BFilePanel*     fOpenPanel;
    3234
     35    SettingsFile*   fSettings;
     36    SettingsWindow* fSettingsWindow;
     37
    3338    void            ArgvReceived(int32 argc, char* argv[]);
    3439    void            ReadyToRun();
    3540
  • src/apps/resourceedit/ResourceEdit.rdef

    diff --git a/src/apps/resourceedit/ResourceEdit.rdef b/src/apps/resourceedit/ResourceEdit.rdef
    index 58b821c..c225980 100644
    a b resource app_version {  
    1616
    1717resource app_flags B_SINGLE_LAUNCH;
    1818
    19 resource(1, "BEOS:FILE_TYPES") message {
     19resource file_types message {
    2020    "types" = "text/x-vnd.Be.ResourceDef"
    2121};
    2222
  • src/apps/resourceedit/ResourceListView.cpp

    diff --git a/src/apps/resourceedit/ResourceListView.cpp b/src/apps/resourceedit/ResourceListView.cpp
    index a329d77..654de44 100644
    a b ResourceListView::ResourceListView(BRect rect, const char* name,  
    1919    BColumnListView(rect, name, resizingMode, drawFlags, border,
    2020        showHorizontalScrollbar)
    2121{
    22 
     22    //SetMouseTrackingEnabled(true);
    2323}
    2424
    2525
    ResourceListView::~ResourceListView()  
    3030
    3131
    3232void
     33ResourceListView::MouseDown(BPoint point)
     34{
     35    PRINT(("MouseDown()"));
     36}
     37
     38
     39void
    3340ResourceListView::MessageReceived(BMessage* msg)
    3441{
    3542    switch (msg->what) {
    36         case B_SIMPLE_DATA: {
     43        case B_SIMPLE_DATA:
     44        {
    3745            entry_ref ref;
    3846            int32 n = 0;
    3947
  • src/apps/resourceedit/ResourceListView.h

    diff --git a/src/apps/resourceedit/ResourceListView.h b/src/apps/resourceedit/ResourceListView.h
    index 5551f82..88657f9 100644
    a b public:  
    1616                bool showHorizontalScrollbar = true);
    1717            ~ResourceListView();
    1818
     19    void    MouseDown(BPoint point);
    1920    void    MessageReceived(BMessage* msg);
    2021
    2122private:
  • src/apps/resourceedit/ResourceRow.cpp

    diff --git a/src/apps/resourceedit/ResourceRow.cpp b/src/apps/resourceedit/ResourceRow.cpp
    index ebe5dce..ecf94f7 100644
    a b  
    99#include <ColumnListView.h>
    1010#include <ColumnTypes.h>
    1111
     12#include <stdlib.h>
     13
    1214
    1315ResourceRow::ResourceRow()
    1416    :
    1517    BRow()
    1618{
    17     fRawData = NULL;
     19    Parent = NULL;
     20    ActionIndex = -1;
    1821
    19     SetField(new BIntegerField(0), 0);
     22    SetField(new BStringField(""), 0);
    2023    SetField(new BStringField(""), 1);
    2124    SetField(new BStringField(""), 2);
    2225    SetField(new BStringField(""), 3);
    ResourceRow::~ResourceRow()  
    3437void
    3538ResourceRow::SetResourceID(int32 id)
    3639{
    37     ((BIntegerField*)GetField(0))->SetValue(id);
     40    ((BStringField*)GetField(0))->SetString((BString() << id).String());
     41}
     42
     43
     44void
     45ResourceRow::SetResourceStringID(const char* id)
     46{
     47    ((BStringField*)GetField(0))->SetString(id);
    3848}
    3949
    4050
    ResourceRow::SetResourceType(const char* type)  
    5363
    5464
    5565void
    56 ResourceRow::SetResourceTypeCode(type_code code)
     66ResourceRow::SetResourceCode(type_code code)
    5767{
    58     fTypeCode = code;
    59     TypeCodeToString(code, fTypeString);
     68    fCode = code;
     69    ResourceType::CodeToString(code, fTypeString);
    6070    ((BStringField*)GetField(3))->SetString(fTypeString);
    6171}
    6272
    6373
    6474void
    65 ResourceRow::SetResourceData(const char* data)
     75ResourceRow::SetResourceStringCode(const char* code)
    6676{
    67     ((BStringField*)GetField(4))->SetString(data);
     77    fCode = ResourceType::StringToCode(code);
     78    ((BStringField*)GetField(3))->SetString(code);
    6879}
    6980
    7081
    7182void
    72 ResourceRow::SetResourceRawData(const void* data)
     83ResourceRow::SetResourceData(const char* data)
    7384{
    74     if (data == NULL)
    75         data = kDefaultData;
    76 
    77     fRawData = data;
    78 
    79     int32 ix = FindTypeCodeIndex(ResourceTypeCode());
    80 
    81     if (ix == -1)
    82         SetResourceData("[Unknown Data]");
    83     else
    84         SetResourceData(kDefaultTypes[ix].toString(fRawData));
     85    ((BStringField*)GetField(4))->SetString(data);
    8586}
    8687
    8788
    ResourceRow::SetResourceSize(off_t size)  
    9596int32
    9697ResourceRow::ResourceID()
    9798{
    98     return ((BIntegerField*)GetField(0))->Value();
     99    const char* strID = ResourceStringID();
     100
     101    // TODO: Check whether is numeric and resolve if not.
     102
     103    return atoi(strID);
     104}
     105
     106
     107const char*
     108ResourceRow::ResourceStringID()
     109{
     110    return ((BStringField*)GetField(0))->String();
    99111}
    100112
    101113
    ResourceRow::ResourceType()  
    114126
    115127
    116128type_code
    117 ResourceRow::ResourceTypeCode()
     129ResourceRow::ResourceCode()
    118130{
    119     return fTypeCode;
     131    return fCode;
    120132}
    121133
    122134
    123135const char*
    124 ResourceRow::ResourceData()
     136ResourceRow::ResourceStringCode()
    125137{
    126     return ((BStringField*)GetField(4))->String();
     138    return  ((BStringField*)GetField(3))->String();
    127139}
    128140
    129141
    130 const void*
    131 ResourceRow::ResourceRawData()
     142const char*
     143ResourceRow::ResourceData()
    132144{
    133     return fRawData;
     145    return ((BStringField*)GetField(4))->String();
    134146}
    135147
    136148
  • src/apps/resourceedit/ResourceRow.h

    diff --git a/src/apps/resourceedit/ResourceRow.h b/src/apps/resourceedit/ResourceRow.h
    index a9e65ca..26d3660 100644
    a b public:  
    1717                    ~ResourceRow();
    1818
    1919    void            SetResourceID(int32 id);
     20    void            SetResourceStringID(const char* id);
    2021    void            SetResourceName(const char* name);
    2122    void            SetResourceType(const char* type);
    22     void            SetResourceTypeCode(type_code code);
     23    void            SetResourceCode(type_code code);
     24    void            SetResourceStringCode(const char* code);
    2325    void            SetResourceData(const char* data);
    24     void            SetResourceRawData(const void*);
    2526    void            SetResourceSize(off_t size);
    2627
    2728    int32           ResourceID();
     29    const char*     ResourceStringID();
    2830    const char*     ResourceName();
    2931    const char*     ResourceType();
    30     type_code       ResourceTypeCode();
     32    type_code       ResourceCode();
     33    const char*     ResourceStringCode();
    3134    const char*     ResourceData();
    32     const void*     ResourceRawData();
    3335    off_t           ResourceSize();
    3436
     37    ResourceRow*    Parent;
     38    int32           ActionIndex;
    3539private:
    36     const void*     fRawData;
    37     type_code       fTypeCode;
     40    type_code       fCode;
    3841    char            fTypeString[8];
    3942
    4043};
  • new file src/apps/resourceedit/SettingsFile.cpp

    diff --git a/src/apps/resourceedit/SettingsFile.cpp b/src/apps/resourceedit/SettingsFile.cpp
    new file mode 100644
    index 0000000..63e84b5
    - +  
     1/*
     2 * Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
     3 * All rights reserved. Distributed under the terms of the MIT license.
     4 */
     5
     6
     7#include "SettingsFile.h"
     8
     9
     10SettingsFile::SettingsFile(const char* name)
     11{
     12    find_directory(B_USER_SETTINGS_DIRECTORY, &fPath);
     13    fPath.Append(name, true);
     14}
     15
     16
     17SettingsFile::~SettingsFile()
     18{
     19
     20}
     21
     22
     23void
     24SettingsFile::Defaults()
     25{
     26    UndoLimit = 100;
     27}
     28
     29
     30void
     31SettingsFile::Load()
     32{
     33    fFile = new BFile(fPath.Path(), B_READ_ONLY);
     34
     35    if (fFile->InitCheck() == B_OK) {
     36        fFile->Read(&UndoLimit, sizeof(UndoLimit));
     37        // TODO: Add more settings here (2/3).
     38    } else
     39        Defaults();
     40
     41    delete fFile;
     42}
     43
     44
     45void
     46SettingsFile::Save()
     47{
     48    fFile = new BFile(fPath.Path(), B_WRITE_ONLY | B_CREATE_FILE);
     49
     50    if (fFile->InitCheck() == B_OK) {
     51        fFile->Write(&UndoLimit, sizeof(UndoLimit));
     52        // TODO: Add more settings here (3/3).
     53    }
     54
     55    delete fFile;
     56}
  • new file src/apps/resourceedit/SettingsFile.h

    diff --git a/src/apps/resourceedit/SettingsFile.h b/src/apps/resourceedit/SettingsFile.h
    new file mode 100644
    index 0000000..2c52232
    - +  
     1/*
     2 * Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
     3 * All rights reserved. Distributed under the terms of the MIT license.
     4 */
     5#ifndef SETTINGS_FILE_H
     6#define SETTINGS_FILE_H
     7
     8
     9#include <File.h>
     10#include <FindDirectory.h>
     11#include <Path.h>
     12
     13
     14class SettingsFile
     15{
     16public:
     17    int32       UndoLimit;
     18    // TODO: Add more settings here (1/3).
     19
     20                SettingsFile(const char* name);
     21                ~SettingsFile();
     22
     23    void        Defaults();
     24    void        Load();
     25    void        Save();
     26
     27private:
     28    BPath       fPath;
     29    BFile*      fFile;
     30};
     31
     32
     33#endif
  • new file src/apps/resourceedit/SettingsWindow.cpp

    diff --git a/src/apps/resourceedit/SettingsWindow.cpp b/src/apps/resourceedit/SettingsWindow.cpp
    new file mode 100644
    index 0000000..9817659
    - +  
     1/*
     2 * Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
     3 * All rights reserved. Distributed under the terms of the MIT license.
     4 */
     5
     6
     7#include "SettingsWindow.h"
     8
     9#include "Constants.h"
     10#include "GenericSettingsView.h"
     11#include "SettingsFile.h"
     12
     13#include <Application.h>
     14#include <Button.h>
     15#include <GroupLayout.h>
     16#include <GroupLayoutBuilder.h>
     17#include <ListView.h>
     18#include <ScrollView.h>
     19#include <View.h>
     20
     21
     22SettingsWindow::SettingsWindow(SettingsFile* settings)
     23    :
     24    BWindow(BRect(200, 150, 600, 450), "Settings", B_TITLED_WINDOW, B_NOT_RESIZABLE)
     25{
     26    fSettings = settings;
     27
     28    BRect bounds = Bounds();
     29
     30    fBackView = new BView(bounds, "fBackView", B_FOLLOW_ALL, 0);
     31    fBackView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
     32
     33    fListView = new BListView(BRect(8, 8, 100 + 8, bounds.bottom - 8),
     34        "fListView", B_SINGLE_SELECTION_LIST, B_FOLLOW_ALL);
     35
     36    // TODO: Implement selecting different categories of settings.
     37    // fListView->SetSelectionMessage(new BMessage(...));
     38
     39    fListView->AddItem(new BStringItem("Generic"));
     40    fListView->Select(0);
     41
     42    fScrollView = new BScrollView("fScrollView", fListView, B_FOLLOW_TOP_BOTTOM,
     43        B_WILL_DRAW | B_FRAME_EVENTS, false, true);
     44
     45    fGenericSettingsView = new GenericSettingsView(
     46        BRect(132, 8, bounds.right - 8, bounds.bottom - 8 - 40),
     47        "fGenericSettingsView", fSettings);
     48    // TODO: Add more settings views (2/4).
     49
     50    fRevertButton = new BButton(BRect(bounds.right - 152, bounds.bottom - 32,
     51        bounds.right - 88, bounds.bottom - 8),
     52        "fRevertButton", "Revert",
     53        new BMessage(MSG_SETTINGS_REVERT));
     54
     55    fApplyButton = new BButton(BRect(bounds.right - 72, bounds.bottom - 32,
     56        bounds.right - 8, bounds.bottom - 8), "fApplyButton", "Apply",
     57        new BMessage(MSG_SETTINGS_APPLY));
     58
     59    AdaptSettings();
     60
     61    fBackView->AddChild(fScrollView);
     62    fBackView->AddChild(fGenericSettingsView);
     63    fBackView->AddChild(fRevertButton);
     64    fBackView->AddChild(fApplyButton);
     65    AddChild(fBackView);
     66
     67    Show();
     68}
     69
     70
     71SettingsWindow::~SettingsWindow()
     72{
     73
     74}
     75
     76
     77bool
     78SettingsWindow::QuitRequested()
     79{
     80    be_app->PostMessage(MSG_SETTINGS_CLOSED);
     81    return true;
     82}
     83
     84void
     85SettingsWindow::MessageReceived(BMessage* msg)
     86{
     87    switch (msg->what)
     88    {
     89        case MSG_SETTINGS_APPLY:
     90        {
     91            ApplySettings();
     92            fSettings->Save();
     93            be_app->PostMessage(MSG_SETTINGS_APPLY);
     94            break;
     95        }
     96        case MSG_SETTINGS_REVERT:
     97        {
     98            AdaptSettings();
     99            fSettings->Save();
     100            be_app->PostMessage(MSG_SETTINGS_APPLY);
     101            break;
     102        }
     103        default:
     104            BWindow::MessageReceived(msg);
     105    }
     106}
     107
     108void
     109SettingsWindow::ApplySettings()
     110{
     111    fGenericSettingsView->ApplySettings();
     112    // TODO: Add more settings views (3/4).
     113}
     114
     115void
     116SettingsWindow::AdaptSettings()
     117{
     118    fGenericSettingsView->AdaptSettings();
     119    // TODO: Add more settings views (4/4).
     120}
  • new file src/apps/resourceedit/SettingsWindow.h

    diff --git a/src/apps/resourceedit/SettingsWindow.h b/src/apps/resourceedit/SettingsWindow.h
    new file mode 100644
    index 0000000..da015de
    - +  
     1/*
     2 * Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
     3 * All rights reserved. Distributed under the terms of the MIT license.
     4 */
     5#ifndef SETTINGS_WINDOW_H
     6#define SETTINGS_WINDOW_H
     7
     8
     9#include <Window.h>
     10
     11
     12class GenericSettingsView;
     13class SettingsFile;
     14
     15class BButton;
     16class BListView;
     17class BScrollView;
     18class BView;
     19
     20
     21class SettingsWindow : public BWindow {
     22public:
     23                            SettingsWindow(SettingsFile* settings);
     24                            ~SettingsWindow();
     25
     26    bool                    QuitRequested();
     27    void                    MessageReceived(BMessage* msg);
     28
     29    void                    ApplySettings();
     30    void                    AdaptSettings();
     31
     32private:
     33    SettingsFile*           fSettings;
     34
     35    BView*                  fBackView;
     36    BListView*              fListView;
     37    BScrollView*            fScrollView;
     38
     39    GenericSettingsView*    fGenericSettingsView;
     40    // TODO: Add more settings (1/4).
     41
     42    BButton*                fRevertButton;
     43    BButton*                fApplyButton;
     44
     45};
     46
     47
     48#endif
  • new file src/apps/resourceedit/edits/AppFlagsEdit.cpp

    diff --git a/src/apps/resourceedit/edits/AppFlagsEdit.cpp b/src/apps/resourceedit/edits/AppFlagsEdit.cpp
    new file mode 100644
    index 0000000..5a14825
    - +  
     1/*
     2 * Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
     3 * All rights reserved. Distributed under the terms of the MIT license.
     4 */
  • new file src/apps/resourceedit/edits/AppFlagsEdit.h

    diff --git a/src/apps/resourceedit/edits/AppFlagsEdit.h b/src/apps/resourceedit/edits/AppFlagsEdit.h
    new file mode 100644
    index 0000000..5a14825
    - +  
     1/*
     2 * Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
     3 * All rights reserved. Distributed under the terms of the MIT license.
     4 */
  • new file src/apps/resourceedit/edits/BooleanEdit.cpp

    diff --git a/src/apps/resourceedit/edits/BooleanEdit.cpp b/src/apps/resourceedit/edits/BooleanEdit.cpp
    new file mode 100644
    index 0000000..bf65a93
    - +  
     1/*
     2 * Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
     3 * All rights reserved. Distributed under the terms of the MIT license.
     4 */
     5
     6
     7#include "NormalEdit.h"
     8#include "ResourceRow.h"
     9
     10#include <CheckBox.h>
     11#include <GroupLayout.h>
     12#include <GroupLayoutBuilder.h>
     13
     14
     15BooleanEdit::BooleanEdit()
     16    :
     17    EditView("BooleanEdit")
     18{
     19
     20}
     21
     22
     23BooleanEdit::~BooleanEdit()
     24{
     25
     26}
     27
     28
     29void
     30BooleanEdit::AttachTo(BView* view)
     31{
     32    EditView::AttachTo(view);
     33
     34    SetLayout(new BGroupLayout(B_VERTICAL));
     35
     36    fValueCheck = new BCheckBox(BRect(0, 0, 0, 0), "fValueText",
     37        "", NULL);
     38
     39    AddChild(BGroupLayoutBuilder(B_VERTICAL, 0)
     40        .Add(fValueCheck)
     41        .AddGlue()
     42    );
     43
     44    view->AddChild(this);
     45}
     46
     47
     48void
     49BooleanEdit::Edit(ResourceRow* row)
     50{
     51    EditView::Edit(row);
     52
     53    BString data = fRow->ResourceData();
     54
     55    if (data == "" || data == "0" || data == "false")
     56        fValueCheck->SetValue(B_CONTROL_OFF);
     57    else
     58        fValueCheck->SetValue(B_CONTROL_ON);
     59}
     60
     61
     62void
     63BooleanEdit::Commit()
     64{
     65    EditView::Commit();
     66
     67    if (fValueCheck->Value() == B_CONTROL_ON)
     68        fRow->SetResourceData("true");
     69    else
     70        fRow->SetResourceData("false");
     71}
  • new file src/apps/resourceedit/edits/BooleanEdit.h

    diff --git a/src/apps/resourceedit/edits/BooleanEdit.h b/src/apps/resourceedit/edits/BooleanEdit.h
    new file mode 100644
    index 0000000..5388999
    - +  
     1/*
     2 * Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
     3 * All rights reserved. Distributed under the terms of the MIT license.
     4 */
     5#ifndef BOOLEAN_EDIT_H
     6#define BOOLEAN_EDIT_H
     7
     8
     9#include "EditView.h"
     10
     11
     12class BCheckBox;
     13
     14
     15class BooleanEdit : public EditView {
     16public:
     17                    BooleanEdit();
     18                    ~BooleanEdit();
     19
     20    void            AttachTo(BView* view);
     21    void            Edit(ResourceRow* row);
     22    void            Commit();
     23
     24private:
     25    BCheckBox*      fValueCheck;
     26
     27};
     28
     29
     30#endif
  • new file src/apps/resourceedit/edits/EditView.cpp

    diff --git a/src/apps/resourceedit/edits/EditView.cpp b/src/apps/resourceedit/edits/EditView.cpp
    new file mode 100644
    index 0000000..dc9861a
    - +  
     1/*
     2 * Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
     3 * All rights reserved. Distributed under the terms of the MIT license.
     4 */
     5
     6
     7#include "EditView.h"
     8
     9
     10EditView::EditView(const char* name)
     11    :
     12    BView(BRect(0, 0, 0, 0), name, 0, 0)
     13{
     14    // Implemented by subclasses.
     15}
     16
     17
     18EditView::~EditView()
     19{
     20    // Implemented by subclasses.
     21}
     22
     23
     24void
     25EditView::AttachTo(BView* view)
     26{
     27    while (true) {
     28        BView* child = ChildAt(0);
     29
     30        if (child == NULL)
     31            break;
     32
     33        child->RemoveSelf();
     34    }
     35
     36    // Implemented by subclasses.
     37}
     38
     39
     40void
     41EditView::Edit(ResourceRow* row)
     42{
     43    fRow = row;
     44    // Implemented by subclasses.
     45}
     46
     47
     48void
     49EditView::Commit()
     50{
     51    // Implemented by subclasses.
     52}
  • new file src/apps/resourceedit/edits/EditView.h

    diff --git a/src/apps/resourceedit/edits/EditView.h b/src/apps/resourceedit/edits/EditView.h
    new file mode 100644
    index 0000000..23aca74
    - +  
     1/*
     2 * Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
     3 * All rights reserved. Distributed under the terms of the MIT license.
     4 */
     5#ifndef EDIT_VIEW_H
     6#define EDIT_VIEW_H
     7
     8
     9#include <View.h>
     10
     11
     12class ResourceRow;
     13
     14
     15class EditView : public BView {
     16public:
     17                            EditView(const char* name);
     18    virtual                 ~EditView();
     19
     20    virtual void            AttachTo(BView* view);
     21    virtual void            Edit(ResourceRow* row);
     22    virtual void            Commit();
     23
     24protected:
     25            ResourceRow*    fRow;
     26
     27};
     28
     29
     30#endif
     31
  • new file src/apps/resourceedit/edits/NormalEdit.cpp

    diff --git a/src/apps/resourceedit/edits/NormalEdit.cpp b/src/apps/resourceedit/edits/NormalEdit.cpp
    new file mode 100644
    index 0000000..fa82251
    - +  
     1/*
     2 * Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
     3 * All rights reserved. Distributed under the terms of the MIT license.
     4 */
     5
     6
     7#include "NormalEdit.h"
     8#include "ResourceRow.h"
     9
     10#include <GroupLayout.h>
     11#include <GroupLayoutBuilder.h>
     12#include <TextControl.h>
     13
     14
     15NormalEdit::NormalEdit()
     16    :
     17    EditView("NormalEdit")
     18{
     19
     20}
     21
     22
     23NormalEdit::~NormalEdit()
     24{
     25
     26}
     27
     28
     29void
     30NormalEdit::AttachTo(BView* view)
     31{
     32    EditView::AttachTo(view);
     33
     34    SetLayout(new BGroupLayout(B_VERTICAL));
     35
     36    fValueText = new BTextControl(BRect(0, 0, 0, 0), "fValueText",
     37        "Value:", "", NULL);
     38    fValueText->SetDivider(50);
     39
     40    AddChild(BGroupLayoutBuilder(B_VERTICAL, 0)
     41        .Add(fValueText)
     42        .AddGlue()
     43    );
     44
     45    view->AddChild(this);
     46}
     47
     48
     49void
     50NormalEdit::Edit(ResourceRow* row)
     51{
     52    EditView::Edit(row);
     53
     54    fValueText->SetText(fRow->ResourceData());
     55}
     56
     57
     58void
     59NormalEdit::Commit()
     60{
     61    EditView::Commit();
     62
     63    fRow->SetResourceData(fValueText->Text());
     64}
  • new file src/apps/resourceedit/edits/NormalEdit.h

    diff --git a/src/apps/resourceedit/edits/NormalEdit.h b/src/apps/resourceedit/edits/NormalEdit.h
    new file mode 100644
    index 0000000..ea5fe78
    - +  
     1/*
     2 * Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
     3 * All rights reserved. Distributed under the terms of the MIT license.
     4 */
     5#ifndef NORMAL_EDIT_H
     6#define NORMAL_EDIT_H
     7
     8
     9#include "EditView.h"
     10
     11
     12class BTextControl;
     13
     14// TODO: Templatize this class and rename to NumericEdit.
     15//template<typename $type>
     16class NormalEdit : public EditView {
     17public:
     18                    NormalEdit();
     19                    ~NormalEdit();
     20
     21    void            AttachTo(BView* view);
     22    void            Edit(ResourceRow* row);
     23    void            Commit();
     24
     25private:
     26    BTextControl*   fValueText;
     27
     28};
     29
     30
     31#endif
  • new file src/apps/resourceedit/interface/ImageButton.cpp

    diff --git a/src/apps/resourceedit/interface/ImageButton.cpp b/src/apps/resourceedit/interface/ImageButton.cpp
    new file mode 100644
    index 0000000..7b0b8dd
    - +  
     1/*
     2 * Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
     3 * All rights reserved. Distributed under the terms of the MIT license.
     4 */
     5
     6
     7#include "ImageButton.h"
     8
     9#include <Bitmap.h>
     10
     11
     12ImageButton::ImageButton(BRect frame, const char* name, BBitmap* image,
     13    BMessage* message, uint32 resizingMode = B_FOLLOW_NONE)
     14    :
     15    BButton(frame, name, "", message, resizingMode)
     16{
     17    fImage = image;
     18
     19    fDrawPoint.x = ((frame.RightTop().x - frame.LeftTop().x)
     20        - (image->Bounds().RightBottom().x + 1)) / 2;
     21
     22    fDrawPoint.y = ((frame.LeftBottom().y - frame.LeftTop().y)
     23        - (image->Bounds().RightBottom().y + 1)) / 2;
     24
     25    fInnerBounds = Bounds();
     26    fInnerBounds.InsetBy(3, 3);
     27
     28    SetDrawingMode(B_OP_ALPHA);
     29}
     30
     31
     32ImageButton::~ImageButton()
     33{
     34
     35}
     36
     37
     38void
     39ImageButton::Draw(BRect updateRect)
     40{
     41    BButton::Draw(updateRect);
     42    DrawBitmap(fImage, fDrawPoint);
     43
     44    if (!IsEnabled()) {
     45        rgb_color tempColor = HighColor();
     46        SetHighColor(255, 255, 255, 155);
     47        FillRect(fInnerBounds, B_SOLID_HIGH);
     48        SetHighColor(tempColor);
     49    }
     50}
     51
     52
     53void
     54ImageButton::ResizeTo(float width, float height)
     55{
     56    BButton::ResizeTo(width, height);
     57    fInnerBounds = Bounds();
     58    fInnerBounds.InsetBy(3, 3);
     59}
     60
     61
     62void
     63ImageButton::SetBitmap(BBitmap* image)
     64{
     65    fImage = image;
     66    Invalidate();
     67}
  • new file src/apps/resourceedit/interface/ImageButton.h

    diff --git a/src/apps/resourceedit/interface/ImageButton.h b/src/apps/resourceedit/interface/ImageButton.h
    new file mode 100644
    index 0000000..e0c3de8
    - +  
     1/*
     2 * Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
     3 * All rights reserved. Distributed under the terms of the MIT license.
     4 */
     5#ifndef IMAGE_BUTTON_H
     6#define IMAGE_BUTTON_H
     7
     8
     9#include <Button.h>
     10
     11
     12class ImageButton : public BButton
     13{
     14public:
     15                ImageButton(BRect frame, const char* name, BBitmap* image,
     16                    BMessage* message, uint32 resizingMode);
     17                ~ImageButton();
     18
     19    void        Draw(BRect updateRect);
     20    void        ResizeTo(float width, float height);
     21
     22    void        SetBitmap(BBitmap* image);
     23
     24private:
     25    BBitmap*    fImage;
     26    BPoint      fDrawPoint;
     27    BRect       fInnerBounds;
     28
     29};
     30
     31
     32#endif
  • new file src/apps/resourceedit/settings/GenericSettingsView.cpp

    diff --git a/src/apps/resourceedit/settings/GenericSettingsView.cpp b/src/apps/resourceedit/settings/GenericSettingsView.cpp
    new file mode 100644
    index 0000000..65d3377
    - +  
     1/*
     2 * Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
     3 * All rights reserved. Distributed under the terms of the MIT license.
     4 */
     5
     6
     7#include "GenericSettingsView.h"
     8
     9#include "SettingsFile.h"
     10
     11#include <GroupLayout.h>
     12#include <GroupLayoutBuilder.h>
     13#include <String.h>
     14#include <TextControl.h>
     15
     16#include <stdlib.h>
     17
     18
     19GenericSettingsView::GenericSettingsView(BRect frame, const char* name,
     20    SettingsFile* settings, uint32 resizingMode, uint32 flags)
     21    :
     22    BView(frame, name, resizingMode, flags)
     23{
     24    fSettings = settings;
     25
     26    SetLayout(new BGroupLayout(B_VERTICAL));
     27
     28    fUndoLimitText = new BTextControl(BRect(0, 0, 0, 0), "fUndoLimitText",
     29        "Undo Limit:", NULL, NULL);
     30    fUndoLimitText->SetDivider(100);
     31
     32    // TODO: Add more controls for generic settings (2/4).
     33
     34    AddChild(BGroupLayoutBuilder(B_VERTICAL, 8)
     35        .Add(fUndoLimitText)
     36        .AddGlue()
     37    );
     38}
     39
     40
     41GenericSettingsView::~GenericSettingsView()
     42{
     43
     44}
     45
     46
     47void
     48GenericSettingsView::ApplySettings()
     49{
     50    fSettings->UndoLimit = atoi(fUndoLimitText->Text());
     51    // TODO: Add more controls for generic settings (3/4).
     52}
     53
     54
     55void
     56GenericSettingsView::AdaptSettings()
     57{
     58    fUndoLimitText->SetText(BString() << fSettings->UndoLimit);
     59    // TODO: Add more controls for generic settings (4/4).
     60}
  • new file src/apps/resourceedit/settings/GenericSettingsView.h

    diff --git a/src/apps/resourceedit/settings/GenericSettingsView.h b/src/apps/resourceedit/settings/GenericSettingsView.h
    new file mode 100644
    index 0000000..47d1411
    - +  
     1/*
     2 * Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
     3 * All rights reserved. Distributed under the terms of the MIT license.
     4 */
     5#ifndef GENERIC_SETTINGS_VIEW_H
     6#define GENERIC_SETTINGS_VIEW_H
     7
     8
     9#include <View.h>
     10
     11
     12class SettingsFile;
     13
     14class BTextControl;
     15
     16
     17class GenericSettingsView : public BView {
     18public:
     19                        GenericSettingsView(BRect frame, const char* name,
     20                            SettingsFile* settings,
     21                            uint32 resizingMode = B_FOLLOW_ALL,
     22                            uint32 flags = 0);
     23                        ~GenericSettingsView();
     24
     25    void                ApplySettings();
     26    void                AdaptSettings();
     27
     28private:
     29    SettingsFile*       fSettings;
     30
     31    BTextControl*       fUndoLimitText;
     32    // TODO: Add more controls for generic settings (1/4).
     33
     34};
     35
     36
     37#endif
  • new file src/apps/resourceedit/support/UndoContext.cpp

    diff --git a/src/apps/resourceedit/support/UndoContext.cpp b/src/apps/resourceedit/support/UndoContext.cpp
    new file mode 100644
    index 0000000..c4f6775
    - +  
     1/*
     2 * Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
     3 * All rights reserved. Distributed under the terms of the MIT license.
     4 */
     5
     6
     7#include "UndoContext.h"
     8
     9#include "Constants.h"
     10
     11#include <List.h>
     12#include <String.h>
     13
     14
     15UndoContext::Action::Action(const BString& label)
     16{
     17    fLabel = label;
     18}
     19
     20
     21UndoContext::Action::~Action()
     22{
     23
     24}
     25
     26
     27void
     28UndoContext::Action::Do()
     29{
     30
     31}
     32
     33
     34void
     35UndoContext::Action::Undo()
     36{
     37
     38}
     39
     40
     41void
     42UndoContext::Action::SetLabel(const BString& label)
     43{
     44    fLabel = label;
     45}
     46
     47
     48BString
     49UndoContext::Action::Label() const
     50{
     51    return fLabel;
     52}
     53
     54
     55UndoContext::UndoContext()
     56{
     57    fAt = 0;
     58    fLimit = 3;
     59    fHistory = new BList();
     60}
     61
     62
     63UndoContext::~UndoContext()
     64{
     65    for (int32 i = 0; i < fHistory->CountItems(); i++)
     66        delete (Action*)fHistory->ItemAt(i);
     67
     68    delete fHistory;
     69}
     70
     71
     72void
     73UndoContext::SetLimit(int32 limit)
     74{
     75    int32 delta = fLimit - limit;
     76
     77    if (limit > 1)
     78        fLimit = limit;
     79    else
     80        limit = 1;
     81
     82    if (delta > 0) {
     83        for (int32 i = 0; i < delta; i++)
     84            delete (Action*)fHistory->ItemAt(i);
     85
     86        fHistory->RemoveItems(0, delta);
     87
     88        if (fAt > fLimit)
     89            fAt = fLimit;
     90    }
     91}
     92
     93
     94int32
     95UndoContext::Limit() const
     96{
     97    return fLimit;
     98}
     99
     100
     101void
     102UndoContext::Do(UndoContext::Action* action)
     103{
     104    int32 count = fHistory->CountItems();
     105
     106    if (fAt >= fLimit)
     107        delete (Action*)fHistory->RemoveItem((int32)0);
     108    else {
     109        for (int32 i = fAt; i < count; i++)
     110            delete (Action*)fHistory->ItemAt(i);
     111
     112        fHistory->RemoveItems(fAt, count - fAt);
     113
     114        fAt++;
     115    }
     116
     117    fHistory->AddItem(action);
     118
     119    action->Do();
     120}
     121
     122
     123void
     124UndoContext::Undo()
     125{
     126    if (!CanUndo())
     127        return;
     128
     129    fAt--;
     130    ((Action*)fHistory->ItemAt(fAt))->Undo();
     131}
     132
     133
     134void
     135UndoContext::Redo()
     136{
     137    if (!CanRedo())
     138        return;
     139
     140    ((Action*)fHistory->ItemAt(fAt))->Do();
     141    fAt++;
     142}
     143
     144
     145bool
     146UndoContext::CanUndo() const
     147{
     148    return fAt > 0;
     149}
     150
     151
     152bool
     153UndoContext::CanRedo() const
     154{
     155    return fAt < fHistory->CountItems();
     156}
     157
     158
     159BString
     160UndoContext::UndoLabel() const
     161{
     162    if (CanUndo())
     163        return ((Action*)fHistory->ItemAt(fAt - 1))->Label();
     164    else
     165        return "";
     166}
     167
     168BString
     169UndoContext::RedoLabel() const
     170{
     171    if (CanRedo())
     172        return ((Action*)fHistory->ItemAt(fAt))->Label();
     173    else
     174        return "";
     175}
  • new file src/apps/resourceedit/support/UndoContext.h

    diff --git a/src/apps/resourceedit/support/UndoContext.h b/src/apps/resourceedit/support/UndoContext.h
    new file mode 100644
    index 0000000..0146e1b
    - +  
     1/*
     2 * Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
     3 * All rights reserved. Distributed under the terms of the MIT license.
     4 */
     5#ifndef UNDO_CONTEXT_H
     6#define UNDO_CONTEXT_H
     7
     8
     9#include <List.h>
     10#include <String.h>
     11
     12
     13class UndoContext {
     14public:
     15    class Action {
     16    public:
     17                        Action(const BString& label);
     18        virtual         ~Action();
     19
     20        virtual void    Do();
     21        virtual void    Undo();
     22
     23        void            SetLabel(const BString& label);
     24        BString         Label() const;
     25
     26    private:
     27        BString         fLabel;
     28    };
     29
     30                UndoContext();
     31                ~UndoContext();
     32
     33    void        SetLimit(int32 limit);
     34    int32       Limit() const;
     35
     36    void        Do(Action* action);
     37
     38    void        Undo();
     39    void        Redo();
     40
     41    bool        CanUndo() const;
     42    bool        CanRedo() const;
     43
     44    BString     UndoLabel() const;
     45    BString     RedoLabel() const;
     46
     47private:
     48    int32       fAt;
     49    int32       fLimit;
     50    BList*      fHistory;
     51
     52};
     53
     54
     55#endif