Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions gui-js/apps/minsky-electron/src/app/events/electron.events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,15 @@ ipcMain.handle(
}
);

ipcMain.handle(
events.GODLEY_POPUP_UNDO,
async (event, payload: { itemId: string; changes: number }) => {
const godley = new GodleyIcon(minsky.namedItems.elem(payload.itemId));
await godley.popup.undo(payload.changes);
event.sender.send(events.GODLEY_POPUP_REFRESH);
}
);

ipcMain.on(
events.REFRESH_ALL_GODLEY_POPUPS, async () => {
WindowManager.refreshAllGodleyPopups();
Expand Down
17 changes: 12 additions & 5 deletions gui-js/apps/minsky-electron/src/app/managers/GodleyMenuManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export class GodleyMenuManager {
const godley = new GodleyIcon(minsky.namedItems.elem(itemInfo.id));
const menu = Menu.buildFromTemplate([
scope.getGodleyFileMenuItem(window, godley),
scope.getGodleyEditMenuItem(godley),
scope.getGodleyEditMenuItem(window, godley, itemInfo.id),
scope.getGodleyViewMenuItem(window),
scope.getGodleyOptionsMenuItem(window),
new MenuItem({
Expand Down Expand Up @@ -188,20 +188,28 @@ export class GodleyMenuManager {
}

private static getGodleyEditMenuItem(
godley: GodleyIcon
window: Electron.BrowserWindow,
godley: GodleyIcon,
itemId: string
) {
return new MenuItem({
label: 'Edit',
submenu: [
{
label: 'Undo',
accelerator: 'CmdOrCtrl + z',
click: () => {godley.popup.undo(1);},
click: () => window.webContents?.send(events.GODLEY_POPUP_UNDO_REQUEST, {
itemId,
changes: 1,
}),
},
{
label: 'Redo',
accelerator: 'CmdOrCtrl + y',
click: () => {godley.popup.undo(-1);},
click: () => window.webContents?.send(events.GODLEY_POPUP_UNDO_REQUEST, {
itemId,
changes: -1,
}),
},
{
label: 'Title',
Expand Down Expand Up @@ -281,4 +289,3 @@ export class GodleyMenuManager {
menu.popup();
}
}

2 changes: 2 additions & 0 deletions gui-js/libs/shared/src/lib/constants/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ export const events = {
GET_CURRENT_WINDOW: 'get-current-window',
GET_PREFERENCES: 'get-preferences',
GODLEY_POPUP_REFRESH: 'godley-popup-refresh',
GODLEY_POPUP_UNDO: 'godley-popup-undo',
GODLEY_POPUP_UNDO_REQUEST: 'godley-popup-undo-request',
GODLEY_VIEW_MOUSEDOWN: 'godley-view-mousedown',
GODLEY_VIEW_IMPORT_STOCK: 'godley-view-import-stock',
HELP_FOR: 'help-for',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,10 @@ export class GodleyWidgetViewComponent implements OnDestroy, OnInit, AfterViewIn
this.windowId = (await this.electronService.getCurrentWindow()).id;

if(!this.canvasMode) {
this.electronService.on(events.GODLEY_POPUP_UNDO_REQUEST, async (e, payload) => {
await this.finishEditing();
await this.electronService.invoke(events.GODLEY_POPUP_UNDO, payload);
});
this.electronService.on(events.GODLEY_POPUP_REFRESH, async e => {
await this.hardRefresh();
});
Expand Down Expand Up @@ -256,6 +260,7 @@ export class GodleyWidgetViewComponent implements OnDestroy, OnInit, AfterViewIn

async onRowAdd(i) {
await this.finishEditing();
await this.namedItemSubCommand.pushHistory();
this.godleyIcon.table.insertRow(i+3);
await this.hardRefresh();
}
Expand All @@ -268,24 +273,28 @@ export class GodleyWidgetViewComponent implements OnDestroy, OnInit, AfterViewIn

async onRowMove(i, n) {
await this.finishEditing();
await this.namedItemSubCommand.pushHistory();
this.godleyIcon.table.moveRow(i+2,n);
await this.hardRefresh();
}

async onColumnAdd(i) {
await this.finishEditing();
await this.namedItemSubCommand.pushHistory();
this.godleyIcon.table.insertCol(i+2);
await this.hardRefresh();
}

async onColumnDelete(i) {
await this.finishEditing();
await this.namedItemSubCommand.pushHistory();
this.godleyIcon.table.deleteCol(i+2);
await this.hardRefresh();
}

async onColumnMove(i, n) {
await this.finishEditing();
await this.namedItemSubCommand.pushHistory();
this.godleyIcon.table.moveCol(i+1,n);
await this.hardRefresh();
}
Expand Down
63 changes: 0 additions & 63 deletions gui-js/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 15 additions & 6 deletions model/godleyIcon.cc
Original file line number Diff line number Diff line change
Expand Up @@ -222,8 +222,15 @@ namespace minsky
}

void GodleyIcon::setCell(int row, int col, const string& newVal)
{
setCellImpl(row, col, newVal, true);
}

void GodleyIcon::setCellImpl(int row, int col, const string& newVal,
bool recordHistory)
{
if (!table.cellInTable(row,col)) return;
if (recordHistory) popup.pushHistory();
// if this operation is clearing an initial condition cell, set it to 0
string& c=table.cell(row,col);
if (newVal.empty() && !c.empty() && table.initialConditionRow(row))
Expand All @@ -241,6 +248,7 @@ namespace minsky
{
if (row>0 && row<=table.rows())
{
popup.pushHistory();
table.deleteRow(row-1);
// if shared column data is deleted, remove it from the other tables too
for (size_t col=1; col<table.cols(); ++col)
Expand All @@ -253,15 +261,16 @@ namespace minsky
void GodleyIcon::moveCell(const MoveCellArgs& args)
{
if (!table.cellInTable(args.srcRow, args.srcCol) || !table.cellInTable(args.destRow, args.destCol)) return;
popup.pushHistory();

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implemented in 486227f: cross-column moves now record one history transaction while both cell updates still perform linked-column balancing. Added an Undo regression test.

if (args.srcCol!=args.destCol) // if moving between columns, we can delete and
// add, which ensures any linked columns are
// correctly updated
{
// create a copy here, as setCell may resize the array, changing
// what the reference referred to.
const string oldVal=table.cell(args.srcRow, args.srcCol);
setCell(args.destRow, args.destCol, oldVal);
setCell(args.srcRow, args.srcCol, "");
setCellImpl(args.destRow, args.destCol, oldVal, false);
setCellImpl(args.srcRow, args.srcCol, "", false);
}
else // within a column, just move the data without affecting any linked column
{
Expand Down Expand Up @@ -301,7 +310,7 @@ namespace minsky
return r;
}

void GodleyIcon::update()
void GodleyIcon::update(bool preserveTable)
{
updateVars(m_stockVars, table.getColumnVariables(), VariableType::stock);
updateVars(m_flowVars, table.getVariables(), VariableType::flow);
Expand Down Expand Up @@ -329,16 +338,16 @@ namespace minsky
fc1.coef*=fc.coef;
v.init(fc1.str());
}
v.godleyOverridden=true;
}
else if (preserveTable)
v.init("");
else
{
// populate cell with current variable's initial value
const FlowCoef fc(v.init());
table.cell(r,c)=fc.str();
v.godleyOverridden=true;
}

v.godleyOverridden=true;
}

if (m_variableDisplay)
Expand Down
4 changes: 3 additions & 1 deletion model/godleyIcon.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ namespace minsky
}

double titleOffs() const {return !table.title.empty()? 15*zoomFactor(): 0;}
void setCellImpl(int row, int col, const string& val, bool recordHistory);

public:
static SVGRenderer svgRenderer; ///< SVG icon to display when not in editor mode
Expand Down Expand Up @@ -121,7 +122,8 @@ namespace minsky
std::vector<Summary> summarise() const;

/// updates the variable lists with the Godley table
void update();
/// @param preserveTable - do no populate table's initial conditions from variable init conditions
void update(bool preserveTable=false);

GodleyIcon* clone() const override {
auto r=new GodleyIcon(*this);
Expand Down
Loading
Loading