Wednesday, December 30, 2009

Delete is broken in Hierarchical Data

I have a AdvancedDataGrid where I am deleting the children. When all the children are gone the folder icon does not change. If I walk the collection and then force the children = null, then the folder changes to a sheet (leaf) icon, as you would expect by looking at the HierachicalCollection class. However when I go to add a new leaf to the summary folder the folder reappears and the down arrow opens indicating that it's got a child, but the child does not render.

Repro using this is swf.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application layout="horizontal"
viewSourceURL="srcview/index.html"
xmlns:mx="http://www.adobe.com/2006/mxml%22>
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.collections.IHierarchicalCollectionView;
import mx.collections.ICollectionView;
import mx.collections.HierarchicalData;
[Bindable] public var tasks:HierarchicalData = new HierarchicalData([{id: "T1", name: "Task #1", startTime: "1/14/2008 8:0:0", endTime: "1/28/2008 17:0:0"}, {id: "T2", name: "Task #2", startTime: "1/29/2008 8:0:0", endTime: "2/5/2008 17:0:0"},
{id: "T3", name: "Summary Task #1", startTime: "2/5/2008 8:0:0", endTime: "2/17/2008 17:0:0", children: [{id: "T4", name: "Task #3", startTime: "2/5/2008 8:0:0", endTime: "2/12/2008 17:0:0"},
{id: "T5", name: "Task #4", startTime: "2/13/2008 8:0:0", endTime: "2/17/2008 17:0:0"}]},
{id: "T6", name: "Milestone #1", milestone: "true", startTime: "2/17/2008 17:0:0", endTime: "2/17/2008 17:0:0"}]);

private function onDelete():void {
var task:Object = adGrid.selectedItem;
if(task != null) {
var _taskCollection:IHierarchicalCollectionView = IHierarchicalCollectionView(adGrid.dataProvider);
var parentTask:Object = _taskCollection.getParentItem(task);
_taskCollection.removeChild(parentTask, task);
//trace(parentTask.id + " has children = " + tasks.hasChildren(parentTask));
//this.cleanTaskCollection(tasks.source as Array);
_taskCollection.itemUpdated(parentTask);
//_taskCollection.refresh();
} else {
mx.controls.Alert.show("Please select a node");
}
}

private function cleanTaskCollection(collection:Array):void {
for each(var task:Object in collection) {
if(task.children && task.children.length == 0) {
// attempt to force item render to not show folders
task.children = null;
} else {
// recurse
cleanTaskCollection(task.children);
}
}
}
private var count:int = 0;

private function onAdd():void {
var task:Object = adGrid.selectedItem;
if(task != null) {
var child:Object = new Object;
child.id = count++;
child.name = "new node " + count;
if(task.children == null) {
task.children = new Array();
}
var _taskCollection:IHierarchicalCollectionView = IHierarchicalCollectionView(adGrid.dataProvider);
_taskCollection.addChild(task, child);
} else {
mx.controls.Alert.show("Please select a node");
}
}
]]>
</mx:Script>
<mx:AdvancedDataGrid dataProvider="{tasks}"
designViewDataType="tree"
id="adGrid">
</mx:AdvancedDataGrid>
<mx:Button click="onDelete()"
label="delete">
</mx:Button>
<mx:Button click="onAdd()"
label="add">
</mx:Button>
</mx:Application>

Monday, December 28, 2009

Finding circular dependencies in Flex/AS3

I was looking for cycles in a directed graph in a task chart implementation I was doing for a client. My implementation of the Tarjan algorithm is hard coded for a linkage of task objects linked by constraints. I’d be interested to find out if anyone else has dug into this algorithm and gotten it to work.

package model.task {
import ilog.gantt.TaskChart;


public class Tarjan {
private var index:int = 0;
private var stack:Array = new Array();
private var SCC:Array = new Array();
public var taskChart:ilog.gantt.TaskChart;

/**
* N.B. Don't forget to reset the *.index = -1 after checking
*
* DJH 12/24/2009 This will only work for task nodes connected by constraints. It does not traverse
* the entire task hierachical data
*
* I don't fully understand but all nodes are treated as loops. Look through the SCC
* array for child arrays which with more than 1 node and those the the cycles.
*
*/
public function tarjan(task:Object /* node */ /*, adjacencyList:Array*/ ):Array {
trace("tarjan():: push task " + task.id);
task.index = index;
task.lowLink = index;
index++;
stack.push(task);
var constraints:Array = taskChart.getFromConstraints(task);
// Collect the successors
if(constraints) {
for each(var c:Object in constraints) {
var toTask:Object = taskChart.getToTask(c);
if(toTask == null) {
// DJH 12/9/2009, fix the constraint does not chain to a successor, so ignore
continue;
}
if(toTask.index == -1) {
tarjan(toTask /*, adjacencyList*/ );
task.lowLink = Math.min(task.lowLink, toTask.lowLink);
} else if(stack.indexOf(toTask) >= 0) {
task.lowLink = Math.min(task.lowLink, toTask.index);
}
}
}
if(task.lowLink == task.index) {
var arr:Array = new Array();
do {
toTask = stack.pop();
arr.push(toTask);
} while(toTask != task)
SCC.push(arr);
}
return SCC;
}
}
}

Tuesday, June 23, 2009

Desktopless, headless, AIR on Linux Redhat

AIR installed fine on my RedHat RHEL 5.3 box, with the added bonus of it being a AMD-64 sytem, so a few moments of panic, but I was able to yum in the Gtk *.so. In the Gnome it’s easy enough from the desktop AdobeAIRInstaller.bin, which installs
Binaries to /opt/Adobe AIR/

This is where a little fun began, it turns out that you the application will not run and I get the following error: (./YourAIRApplication:14779): Gtk-WARNING **: cannot open display:

One way around this is to us Xvfb, a virtual frame buffer. For RedHat I was able to download the rpm and install. The bonus here is that xvfb-run is actually a script. Running the final command below works.

rpm -Uvh XFree86-Xvfb-3.3.2.3-25.i386.rpm
xvfb-run.sh
cd /opt/YourAIRApplication/bin
xvfb-run.sh ./YourAIRApplication

Attempting to run on a copied Adobe Air install: I couldn’t get Adobe Air to run from just the binaries, so I copied
/opt/Adobe\ Air to a clean box

I attempted to run ./opt/YourAIRApplication/bin/YourAIRApplication

And I get:
Error loading the runtime (libadobecertstore.so: cannot open shared object file: No such file or

Time to stop and go write some Flex code!

Friday, June 12, 2009


width="100%" height="100%">

/**
* bubbles the rollout event up to the lauching button
*/
private function onRollOut(event : MouseEvent) : void
{
this.dispatchEvent(event);
}
]]>

width="30" height="110"
horizontalScrollPolicy="off" verticalScrollPolicy="off"
backgroundColor="#626262"
rollOut="onRollOut(event)"
>
styleName="progressBar"
borderColor="#BDBDBD"
showTrackHighlight="true"
themeColor="#AEDF4F"
y="5"
/>



Saturday, June 6, 2009

Flex RSS/Atom Reader with thumbnails

I didn't see any samples of RSS readers with thumbnails, so I wrote a quick Atom reader. Ping me if you'd like the source. Future project for me is to bypass the proxy.php by making a javascript call and avoid the cross domain.

Thursday, June 4, 2009

AT&T Blue SIM Card - unlocking a nokia phone

Folks, I found out today that go forward, AT&T's plan to support hardware for the blue sim card phones is to unlock goPhones. All you need to do is to call the legacy blue plan customer service. No need to lie, no need to look for unlock codes on the web.

Wednesday, April 29, 2009

AFCSDevConsole is pegging my CPU

I'm on Cocomo 092 version, and I left the AFCSDevConsole lying around on my desktop for about 8 hours and it's pegged my CPU. Has anyone else seen this?

SoundEffect.play() doesn't play

Incredibly frustrating hour when I couldn't get SoundEffect play() to run, stepped through it in the debugger, but I didn't come to any conclusions.

Anyway, the way to get 'er done is posted on flexexamples.com

See SoundAsset


// ding support
[Embed('../assets/ding.mp3')]
private var ding_mp3:Class;
private var ding:SoundAsset = new ding_mp3() as SoundAsset;