view release on metacpan or search on metacpan
socialcalc/Changes.txt view on Meta::CPAN
2008-09-19:
ScheduleSheetCommands now starts a time-sliced loop to execute commands
2008-09-20:
2008-09-21:
2008-09-22:
2008-09-23:
Made commands, recalc, and display all be timer driven
Added deferred command execution
Added edit.busy
Made most of UI observe the busy flag, including Button and Drag additions
2008-11-06:
Added calcorder as a timesliced part of recalc.
2008-11-07:
Added recalc to coded and decoded sheet attributes.
Sheet recalc attribute is now followed, as well as new sheet.recalconce.
2008-11-10:
SpreadsheetControl now has a default status line.
Added recalc button to toolbar.
2008-11-11:
Recalc is now followed in mult-sheet recalc.
2008-11-14:
Tab switching is ignored away from sheet when editor.busy.
Initial spreadsheet.currentTab is now 0 after initialization.
Recalc button in toolbar is only displayed if recalc needed
2008-11-15:
Made spreadsheet.DoOnResize.
Fixed bug with ResizeTableEditor changing griddiv but not toplevel.
2008-11-16:
Made SocialCalc.ResetSheet only reset data stuff so Reload works in new event-driven world.
2008-11-19:
Sort range is now saved and loaded.
2008-11-24:
Added sheet.changedrendervalues to fix bugs with changed fonts, etc.
Added color chooser to settings tab
Made scroll wheel follow editor.busy
2008-11-26:
Updated simpleedit14.pl
Fixed some IE bugs with SocialCalc.SpreadsheetControlDecodeSpreadsheetSave with ^$
2008-11-29:
Fixed row hide setting load bug (typo).
2008-12-01:
Made simpleedit14.pl do server-side wikitext expansion differently than client-side.
socialcalc/socialcalc-3.js view on Meta::CPAN
sheetobj: null, // sheet being operated on
parseobj: null, // SocialCalc.Parse object with the command string, etc.
timerobj: null, // used for timeslicing
firsttimerdelay: 50, // wait before starting cmds (for Chrome - to give time to update)
timerdelay: 1, // wait between slices
maxtimeslice: 100, // do another slice after this many milliseconds
saveundo: false, // arg for ExecuteSheetCommand
CmdExtensionCallbacks: {}, // for startcmdextension, in form: cmdname, {func:function(cmdname, data, sheet, SocialCalc.Parse object, saveundo), data:whatever}
cmdextensionbusy: "" // if length>0, command loop waits for SocialCalc.ResumeFromCmdExtension()
// statuscallback: null, // called during execution - obsolete: use sheet obj's
// statuscallbackparams: null
};
//
// SocialCalc.ScheduleSheetCommands
//
// statuscallback is called at the beginning (cmdstart) and end (cmdend).
socialcalc/socialcalc-3.js view on Meta::CPAN
sci.timerobj = null;
while (!sci.parseobj.EOF()) { // go through all commands (separated by newlines)
errortext = SocialCalc.ExecuteSheetCommand(sci.sheetobj, sci.parseobj, sci.saveundo);
if (errortext) alert(errortext);
sci.parseobj.NextLine();
if (sci.cmdextensionbusy.length > 0) { // forced wait
if (sci.sheetobj.statuscallback) { // notify others if requested
sci.sheetobj.statuscallback(sci, "cmdextension", sci.cmdextensionbusy, sci.sheetobj.statuscallbackparams);
}
return;
}
if (((new Date()) - starttime) >= sci.maxtimeslice) { // if taking too long, give up CPU for a while
sci.timerobj = window.setTimeout(SocialCalc.SheetCommandsTimerRoutine, sci.timerdelay);
return;
}
}
if (sci.sheetobj.statuscallback) { // notify others if requested
sci.sheetobj.statuscallback(sci, "cmdend", "", sci.sheetobj.statuscallbackparams);
}
}
SocialCalc.ResumeFromCmdExtension = function() {
var sci = SocialCalc.SheetCommandInfo;
sci.cmdextensionbusy = "";
SocialCalc.SheetCommandsTimerRoutine();
}
//
// errortext = SocialCalc.ExecuteSheetCommand(sheet, cmd, saveundo)
//
// cmd is a SocialCalc.Parse object.
//
socialcalc/socialcalcserver.pl view on Meta::CPAN
spreadsheet.ExecuteCommand('redisplay', '');
}
else {
spreadsheet.ExecuteCommand('recalc', '');
}
function docmdext (name, data, sheet, cmd, saveundo) {
var cmdstr = cmd.RestOfString();
data.editor.EditorScheduleSheetCommands(cmdstr, false, false);
SocialCalc.SheetCommandInfo.cmdextensionbusy = "Do Cmd Ext "+cmdstr;
window.setTimeout(function(){SocialCalc.ResumeFromCmdExtension();}, 100);
}
function doloadclipboardext (name, data, sheet, cmd, saveundo) {
var cmdstr = cmd.RestOfString();
SocialCalc.SheetCommandInfo.cmdextensionbusy = "Load Clipboard Ext "+cmdstr;
loaddata(cmdstr);
// window.setTimeout(function(){SocialCalc.ResumeFromCmdExtension();}, 100);
// SocialCalc.ResumeFromCmdExtension();
}
var loaddatatimerobj;
function loaddata(url) {
socialcalc/socialcalcspreadsheetcontrol.js view on Meta::CPAN
var tabs = spreadsheet.tabs;
var views = spreadsheet.views;
if (typeof obj == "string") {
newtab = obj;
}
else {
newtab = obj.id.slice(spreadsheet.idPrefix.length,-3);
}
if (spreadsheet.editor.busy && // if busy and switching from "sheet", ignore
(!tabs[spreadsheet.currentTab].view || tabs[spreadsheet.currentTab].view=="sheet")) {
for (i=0; i<tabs.length; i++) {
if(tabs[i].name==newtab && (tabs[i].view && tabs[i].view!="sheet")) {
return;
}
}
}
if (spreadsheet.tabs[spreadsheet.currentTab].onunclick) {
spreadsheet.tabs[spreadsheet.currentTab].onunclick(spreadsheet, spreadsheet.tabs[spreadsheet.currentTab].name);
socialcalc/socialcalctableeditor.js view on Meta::CPAN
this.verticaltablecontrol = null;
this.horizontaltablecontrol = null;
this.logo = null;
this.cellhandles = null;
// Dynamic properties:
this.timeout = null; // if non-null, timer id for position calculations
this.busy = false; // true when executing command, calculating, etc.
this.ensureecell = false; // if true, ensure ecell is visible after timeout
this.deferredCommands = []; // commands to execute after busy, in form: {cmdstr: "cmds", saveundo: t/f}
this.gridposition = null; // screen coords of full grid
this.headposition = null; // screen coords of upper left of grid within header rows
this.firstscrollingrow = null; // row number of top row in last (the scrolling) pane
this.firstscrollingrowtop = null; // position of top row in last (the scrolling) pane
this.lastnonscrollingrow = null; // row number of last displayed row in last non-scrolling
// pane, or zero (for thumb position calculations)
this.lastvisiblerow = null; // used for paging down
this.firstscrollingcol = null; // column number of top col in last (the scrolling) pane
this.firstscrollingcolleft = null; // position of top col in last (the scrolling) pane
socialcalc/socialcalctableeditor.js view on Meta::CPAN
// Methods:
SocialCalc.TableEditor.prototype.CreateTableEditor = function(width, height) {return SocialCalc.CreateTableEditor(this, width, height);};
SocialCalc.TableEditor.prototype.ResizeTableEditor = function(width, height) {return SocialCalc.ResizeTableEditor(this, width, height);};
SocialCalc.TableEditor.prototype.SaveEditorSettings = function() {return SocialCalc.SaveEditorSettings(this);};
SocialCalc.TableEditor.prototype.LoadEditorSettings = function(str, flags) {return SocialCalc.LoadEditorSettings(this, str, flags);};
SocialCalc.TableEditor.prototype.EditorRenderSheet = function() {SocialCalc.EditorRenderSheet(this);};
SocialCalc.TableEditor.prototype.EditorScheduleSheetCommands = function(cmdstr, saveundo, ignorebusy) {SocialCalc.EditorScheduleSheetCommands(this, cmdstr, saveundo, ignorebusy);};
SocialCalc.TableEditor.prototype.ScheduleSheetCommands = function(cmdstr, saveundo) {
this.context.sheetobj.ScheduleSheetCommands(cmdstr, saveundo);
};
SocialCalc.TableEditor.prototype.SheetUndo = function() {
this.context.sheetobj.SheetUndo();
};
SocialCalc.TableEditor.prototype.SheetRedo = function() {
this.context.sheetobj.SheetRedo();
};
SocialCalc.TableEditor.prototype.EditorStepSet = function(status, arg) {SocialCalc.EditorStepSet(this, status, arg);};
socialcalc/socialcalctableeditor.js view on Meta::CPAN
if (editor.ecell) editor.SetECellHeaders("selected");
SocialCalc.AssignID(editor, editor.fullgrid, "fullgrid"); // give it an id
editor.EditorMouseRegister();
}
//
// EditorScheduleSheetCommands(editor, cmdstr, saveundo, ignorebusy)
//
SocialCalc.EditorScheduleSheetCommands = function(editor, cmdstr, saveundo, ignorebusy) {
if (editor.state!="start" && !ignorebusy) { // ignore commands if editing a cell
return;
}
if (editor.busy && !ignorebusy) { // hold off on commands if doing one
editor.deferredCommands.push({cmdstr: cmdstr, saveundo: saveundo});
return;
}
switch (cmdstr) {
case "recalc":
case "redisplay":
editor.context.sheetobj.ScheduleSheetCommands(cmdstr, false);
break;
socialcalc/socialcalctableeditor.js view on Meta::CPAN
}
}
}
switch (status) {
case "startup":
break;
case "cmdstart":
editor.busy = true;
sheetobj.celldisplayneeded = "";
break;
case "cmdextension":
break;
case "cmdend":
signalstatus(status);
if (sheetobj.changedrendervalues) {
socialcalc/socialcalctableeditor.js view on Meta::CPAN
editor.recalcFunction(editor);
}
else {
if (sheetobj.renderneeded) {
editor.FitToEditTable();
sheetobj.renderneeded = false;
editor.ScheduleRender();
}
else {
editor.SchedulePositionCalculations(); // just in case command changed positions
// editor.busy = false;
// signalstatus("cmdendnorender");
}
}
return;
case "calcstart":
editor.busy = true;
break;
case "calccheckdone":
case "calcorder":
case "calcstep":
case "calcloading":
case "calcserverfunc":
break;
case "calcfinished":
signalstatus(status);
editor.ScheduleRender();
return;
case "schedrender":
editor.busy = true; // in case got here without cmd or recalc
break;
case "renderdone":
break;
case "schedposcalc":
editor.busy = true; // in case got here without cmd or recalc
break;
case "doneposcalc":
if (editor.deferredCommands.length) {
signalstatus(status);
dcmd = editor.deferredCommands.shift();
editor.EditorScheduleSheetCommands(dcmd.cmdstr, dcmd.saveundo, true);
}
else {
editor.busy = false;
signalstatus(status);
if (editor.state=="start") editor.DisplayCellContents(); // make sure up to date
}
return;
default:
addmsg("Unknown status: "+status);
break;
}
socialcalc/socialcalctableeditor.js view on Meta::CPAN
break;
default:
progress = status;
break;
}
if (!progress && params.calculating) {
progress = scc.s_statusline_calculating;
}
// if there is a range, calculate sum (not during busy times)
if (!params.calculating && !params.command && !progress && editor.range.hasrange
&& (editor.range.left!=editor.range.right || editor.range.top!=editor.range.bottom)) {
sum = 0;
for (r=editor.range.top; r <= editor.range.bottom; r++) {
for (c=editor.range.left; c <= editor.range.right; c++) {
cell = editor.context.sheetobj.cells[SocialCalc.crToCoord(c, r)];
if (!cell) continue;
if (cell.valuetype && cell.valuetype.charAt(0)=="n") {
sum += cell.datavalue-0;
}
socialcalc/socialcalctableeditor.js view on Meta::CPAN
line = "set "+ecell.coord+" "+cmd;
errortext = editor.EditorScheduleSheetCommands(line, true, false);
}
editor.DisplayCellContents();
}
SocialCalc.EditorProcessMouseWheel = function(event, delta, mousewheelinfo, wobj) {
if (wobj.functionobj.editor.busy) return; // ignore if busy
if (delta > 0) {
wobj.functionobj.editor.ScrollRelative(true, -1);
}
if (delta < 0) {
wobj.functionobj.editor.ScrollRelative(true, +1);
}
}
socialcalc/socialcalctableeditor.js view on Meta::CPAN
editor.MoveECellCallback[f](editor);
}
editor.UpdateCellCSS(cell, editor.ecell.row, editor.ecell.col);
editor.SetECellHeaders("selected");
for (f in editor.StatusCallback) { // let status line, etc., know
editor.StatusCallback[f].func(editor, "moveecell", newcell, editor.StatusCallback[f].params);
}
if (editor.busy) {
editor.ensureecell = true; // wait for when not busy
}
else {
editor.ensureecell = false;
editor.EnsureECellVisible();
}
return newcell;
}
socialcalc/socialcalctableeditor.js view on Meta::CPAN
var viewport = SocialCalc.GetViewportInfo();
var clientX = event.clientX + viewport.horizontalScroll;
var clientY = event.clientY + viewport.verticalScroll;
var mouseinfo = SocialCalc.EditorMouseInfo;
editor = SocialCalc.Keyboard.focusTable; // get TableEditor doing keyboard stuff
if (!editor) return true; // we're not handling it -- let browser do default
if (editor.busy) return; // don't do anything when busy (is this correct?)
var cellhandles = editor.cellhandles;
cellhandles.movedmouse = false; // detect no-op
if (cellhandles.timer) { // cancel timer
window.clearTimeout(cellhandles.timer);
cellhandles.timer = null;
}
if (cellhandles.tooltipstimer) {
socialcalc/socialcalctableeditor.js view on Meta::CPAN
s.zIndex = 3;
setStyles(control.paneslider, scc.TCpanesliderStyle);
s.backgroundImage="url("+imageprefix+"paneslider-"+vh+".gif)";
if (scc.TCpanesliderClass) control.paneslider.className = scc.TCpanesliderClass;
AssignID(control.editor, control.paneslider, "paneslider"+vh);
TooltipRegister(control.paneslider, "paneslider", vh);
functions = {MouseDown:SocialCalc.TCPSDragFunctionStart,
MouseMove: SocialCalc.TCPSDragFunctionMove,
MouseUp: SocialCalc.TCPSDragFunctionStop,
Disabled: function() {return control.editor.busy;}};
functions.control = control; // make sure this is there
SocialCalc.DragRegister(control.paneslider, control.vertical, !control.vertical, functions);
control.main.appendChild(control.paneslider);
control.lessbutton = document.createElement("div");
s = control.lessbutton.style;
s.height = (control.vertical ? control.buttonthickness : control.controlthickness)+"px";
socialcalc/socialcalctableeditor.js view on Meta::CPAN
s.position = "absolute";
setStyles(control.lessbutton, scc.TClessbuttonStyle);
s.backgroundImage="url("+imageprefix+"less-"+vh+"n.gif)"
if (scc.TClessbuttonClass) control.lessbutton.className = scc.TClessbuttonClass;
AssignID(control.editor, control.lessbutton, "lessbutton"+vh);
params = {repeatwait:scc.TClessbuttonRepeatWait, repeatinterval:scc.TClessbuttonRepeatInterval,
normalstyle: "backgroundImage:url("+imageprefix+"less-"+vh+"n.gif);",
downstyle: "backgroundImage:url("+imageprefix+"less-"+vh+"d.gif);",
hoverstyle: "backgroundImage:url("+imageprefix+"less-"+vh+"h.gif);"};
functions = {MouseDown:function(){if(!control.editor.busy) control.editor.ScrollRelative(control.vertical, -1);},
Repeat:function(){if(!control.editor.busy) control.editor.ScrollRelative(control.vertical, -1);},
Disabled: function() {return control.editor.busy;}};
SocialCalc.ButtonRegister(control.lessbutton, params, functions);
control.main.appendChild(control.lessbutton);
control.morebutton = document.createElement("div");
s = control.morebutton.style;
s.height = (control.vertical ? control.buttonthickness : control.controlthickness)+"px";
s.width = (control.vertical ? control.controlthickness : control.buttonthickness)+"px";
s.zIndex = 2;
socialcalc/socialcalctableeditor.js view on Meta::CPAN
s.position = "absolute";
setStyles(control.morebutton, scc.TCmorebuttonStyle);
s.backgroundImage="url("+imageprefix+"more-"+vh+"n.gif)"
if (scc.TCmorebuttonClass) control.morebutton.className = scc.TCmorebuttonClass;
AssignID(control.editor, control.morebutton, "morebutton"+vh);
params = {repeatwait:scc.TCmorebuttonRepeatWait, repeatinterval:scc.TCmorebuttonRepeatInterval,
normalstyle: "backgroundImage:url("+imageprefix+"more-"+vh+"n.gif);",
downstyle: "backgroundImage:url("+imageprefix+"more-"+vh+"d.gif);",
hoverstyle: "backgroundImage:url("+imageprefix+"more-"+vh+"h.gif);"};
functions = {MouseDown:function(){if(!control.editor.busy) control.editor.ScrollRelative(control.vertical, +1);},
Repeat:function(){if(!control.editor.busy) control.editor.ScrollRelative(control.vertical, +1);},
Disabled: function() {return control.editor.busy;}};
SocialCalc.ButtonRegister(control.morebutton, params, functions);
control.main.appendChild(control.morebutton);
control.scrollarea = document.createElement("div");
s = control.scrollarea.style;
s.height = control.controlthickness+"px";
s.width = control.controlthickness+"px";
s.zIndex = 1;
s.overflow = "hidden"; // IE will make the DIV at least font-size height...so use this
s.position = "absolute";
setStyles(control.scrollarea, scc.TCscrollareaStyle);
s.backgroundImage="url("+imageprefix+"scrollarea-"+vh+".gif)";
if (scc.TCscrollareaClass) control.scrollarea.className = scc.TCscrollareaClass;
AssignID(control.editor, control.scrollarea, "scrollarea"+vh);
params = {repeatwait:scc.TCscrollareaRepeatWait, repeatinterval:scc.TCscrollareaRepeatWait};
functions = {MouseDown:SocialCalc.ScrollAreaClick, Repeat:SocialCalc.ScrollAreaClick,
Disabled: function() {return control.editor.busy;}};
functions.control = control;
SocialCalc.ButtonRegister(control.scrollarea, params, functions);
control.main.appendChild(control.scrollarea);
control.thumb = document.createElement("div");
s = control.thumb.style;
s.height = (control.vertical ? control.thumbthickness : control.controlthickness)+"px";
s.width = (control.vertical ? control.controlthickness : control.thumbthickness)+"px";
socialcalc/socialcalctableeditor.js view on Meta::CPAN
s.overflow = "hidden"; // IE will make the DIV at least font-size height...so use this
s.position = "absolute";
setStyles(control.thumb, scc.TCthumbStyle);
control.thumb.style.backgroundImage="url("+imageprefix+"thumb-"+vh+"n.gif)";
if (scc.TCthumbClass) control.thumb.className = scc.TCthumbClass;
AssignID(control.editor, control.thumb, "thumb"+vh);
functions = {MouseDown:SocialCalc.TCTDragFunctionStart,
MouseMove: SocialCalc.TCTDragFunctionMove,
MouseUp: SocialCalc.TCTDragFunctionStop,
Disabled: function() {return control.editor.busy;}};
functions.control = control; // make sure this is there
SocialCalc.DragRegister(control.thumb, control.vertical, !control.vertical, functions);
params = {normalstyle: "backgroundImage:url("+imageprefix+"thumb-"+vh+"n.gif)", name:"Thumb",
downstyle: "backgroundImage:url("+imageprefix+"thumb-"+vh+"d.gif)",
hoverstyle: "backgroundImage:url("+imageprefix+"thumb-"+vh+"h.gif)"};
SocialCalc.ButtonRegister(control.thumb, params, null); // give it button-like visual behavior
control.main.appendChild(control.thumb);
socialcalc/socialcalctableeditor.js view on Meta::CPAN
//
// ScrollAreaClick - Button function to process pageup/down clicks
//
SocialCalc.ScrollAreaClick = function(e, buttoninfo, bobj) {
var control = bobj.functionobj.control;
var bposition = SocialCalc.GetElementPosition(bobj.element);
var clickpos = control.vertical ? buttoninfo.clientY : buttoninfo.clientX;
if (control.editor.busy) { // ignore if busy - wait for next repeat
return;
}
control.editor.PageRelative(control.vertical, clickpos > control.thumbpos ? 1 : -1);
return;
}
//
// PositionTableControlElements