I expanded the answer by @Leonid to restore the previous result if you cancel the evaluation and packaged the functionality into a cell style in my stylesheet for convenience. The cell expression for the stylesheet is pasted below.
This works in the cases I use often, but it has not been extensively tested. For example, it will not restore output in cases where multiple cells are generated during an evaluation of a single input cell. Also, only the last input of multiple input cells is displayed.
Cell[
StyleData["ExportCell", StyleDefinitions -> StyleData["Input"]],
CellEvaluationFunction->(
Module[{result = Null, thiscell, oldbackgr, tag, oldresult,evalq, nb},
(* find currently evaluating cell and change background *)
nb=EvaluationNotebook[];
SelectionMove[nb, All, EvaluationCell];
thiscell = NotebookSelection[];
oldbackgr = Replace[Background, Append[Options[thiscell], Background -> None]];
SetOptions[thiscell, {Background -> LightGreen, CellTags -> (tag = StringJoin["Export", ToString[Unique[]]])}];
NotebookLocate[tag];
(* ask user whether to evaluate cell *)
evalq = ChoiceDialog["Evaluate this cell?"];
SetOptions[thiscell, Background -> oldbackgr];
(* evaluate new result or reprint old result, as necessary *)
If[evalq,
result = ToExpression[#],
SelectionMove[nb,Next, Cell];
oldresult=NotebookRead[nb];
(* basic check for case when there is no existing output, will miss cases with other outputs, e.g., Print commands *)
If[oldresult[[2]]=="Output",
NotebookWrite[nb,oldresult];,
SelectionMove[nb,Previous,Cell];
];
];
SelectionMove[nb,After,Cell];
result
]& ),
CellFrameLabels->{{None, "Export"}, {None, None}},
MenuSortingValue->1500
]
EDIT:
Alternative check for output cell as suggested by @celtschk in comments is below. It's not an elegant implementation but it seems to work. However, this version may cause the input notebook to "blink" once as it autoscrolls rapidly back and forth in some cases where no output cell exists. Also, the input cursor location will not necessarily end up in the usual place since the front end normally moves it before evaluating any cells (actually, this is true of the previous version as well).
If[evalq,
result = ToExpression[#],
(* check if output cell exists *)
SelectionMove[nb,All,CellGroup, AutoScroll->False];
SelectionMove[nb,Before,CellGroup, AutoScroll->False];
SelectionMove[nb,Next,Cell, AutoScroll->False];
(* if input cell is first cell in a cell group *)
If[tag===(ReplaceAll[CellTags, Options[NotebookSelection[nb],CellTags]]),
SelectionMove[nb,All,CellGroup, AutoScroll->False];
SelectionMove[nb,After,CellGroup, AutoScroll->False];
SelectionMove[nb,Previous,Cell, AutoScroll->False];
oldresult = NotebookRead[nb];
(* if last cell in group is output cell *)
If[Part[oldresult, 2] == "Output",
NotebookWrite[nb, oldresult]
],
NotebookLocate[tag]
];
];
Exportare also the cells I would want that for. But I'd have no problems with a solution where I'd have to tag the cells accordingly. – celtschk Mar 07 '12 at 17:58