Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

a suggested fix for CPArrayController selection binding failure in retri... #1627

Merged
merged 1 commit into from

5 participants

Takenori Sato CappBot Aparajita Fishman Andrew Hankinson Alexander Ljungberg
Takenori Sato

...eving initial selection values

When CPArrayController is bound via selection key, initial selection values are not retrieved. Then it ends up with showing empty selection.

But after moving to another index, which calls setSelectionIndexes:(CPIndexSet)indexes, it becomes to work correctly.

setSelectionIndexes:(CPIndexSet)indexes calls _selectionDidChange(CPObjectController) that initiates selection proxy as follows:

- (void)_selectionDidChange
{
    if (_selection === undefined || _selection === nil)
        _selection = [[CPControllerSelectionProxy alloc] initWithController:self];

    [_selection controllerDidChange];
    [self didChangeValueForKey:@"selection"];
}

So I suspect the instantiation of the proxy is the key, and changed that the proxy is instantiated in the constructor.

But how does the instantiation is deferred at all?

CappBot
Collaborator

Milestone: Someday. Label: #new. What's next? A reviewer should examine this issue.

Alexander Ljungberg aljungberg was assigned
Aparajita Fishman
Owner

@aljungberg or cacaodev should look at this, they are the binding experts.

CappBot
Collaborator

Assignee: aljungberg. Milestone: Someday. Label: #new. What's next? A reviewer should examine this issue.

Andrew Hankinson

-#new
+bug
+AppKit
+#needs-info

CappBot
Collaborator

Assignee: aljungberg. Milestone: Someday. Labels: #needs-info, AppKit, bug. What's next? Additional information should be added as a comment to this isuse.

Aparajita Fishman aparajita merged commit 6a8cba5 into from
Aparajita Fishman
Owner

Merged, thank you!

CPObjectController was expecting its setContent to be called, which would eventually call _selectionDidChange, which would initialize _selection. However, CPArrayController overrides setContent and does not initialize _selection.

#fixed

CappBot
Collaborator

Assignee: aljungberg. Milestone: Someday. Labels: #fixed, AppKit, bug. What's next? This issue is considered successfully resolved.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jul 21, 2012
  1. Takenori Sato

    a suggested fix for CPArrayController selection binding failure in re…

    ggsato authored
    …trieving initial selection values
This page is out of date. Refresh to see the latest.
1  AppKit/CPObjectController.j
View
@@ -109,6 +109,7 @@
[self setObjectClass:[CPMutableDictionary class]];
_observedKeys = [[CPCountedSet alloc] init];
+ _selection = [[CPControllerSelectionProxy alloc] initWithController:self];
}
return self;
130 Tests/Manual/ArrayControllerInitialSelectionTest/AppController.j
View
@@ -0,0 +1,130 @@
+/*
+ * AppController.j
+ * ArrayControllerSetContentTest
+ *
+ * Created by You on July 17, 2012.
+ * Copyright 2012, Your Company All rights reserved.
+ */
+
+@import <Foundation/CPObject.j>
+@import <AppKit/CPArrayController.j>
+@import <AppKit/CPTextField.j>
+
+@implementation AppController : CPObject
+{
+ CPString log;
+ CPString selectedValue;
+}
+
+- (void)applicationDidFinishLaunching:(CPNotification)aNotification
+{
+ var theWindow = [[CPWindow alloc] initWithContentRect:CGRectMakeZero() styleMask:CPBorderlessBridgeWindowMask],
+ contentView = [theWindow contentView],
+ contentWidth = [contentView frame].size.width;
+
+ // instantiate a controller
+ var controller = [[CPArrayController alloc] init];
+ var content = [CPMutableArray array],
+ message = [[Message alloc] initWithMessage:@"This is an initial content" withAppController:self];
+ [content addObject:message];
+ [controller setContent:content];
+
+ // listen to selectedIndex change
+ [controller addObserver:self forKeyPath:@"selectionIndex" options: nil context: nil];
+
+ // create a field, and establish a binding
+ var field = [CPTextField textFieldWithStringValue:@"" placeholder:@"bound value appears here..." width:contentWidth/2];
+ [field setFrameOrigin:CGPointMake(20, 20)];
+ [field bind:@"value" toObject:controller withKeyPath:@"selection.message" options:nil];
+ [field setEditable:NO];
+ [contentView addSubview:field];
+
+ var logField = [CPTextField textFieldWithStringValue:@"" placeholder:@"access to bound field is logged here..." width:contentWidth/2];
+ [logField setFrameOrigin:CGPointMake(20, 50)];
+ [logField bind:@"value" toObject:self withKeyPath:@"log" options:nil];
+ [logField setEditable:NO];
+ [contentView addSubview:logField];
+
+ var selectedField = [CPTextField textFieldWithStringValue:@"" placeholder:@"waiting for a selection" width:contentWidth/2];
+ [selectedField setFrameOrigin:CGPointMake(20, 80)];
+ [selectedField bind:@"value" toObject:self withKeyPath:@"selectedValue" options:nil];
+ [selectedField setEditable:NO];
+ [contentView addSubview:selectedField];
+
+ [theWindow orderFront:self];
+
+ // later, a content is retrieved from a server, and updated by setContent or contetnArray binding.
+ // Here, uses setContent
+ var newContent = [CPMutableArray array],
+ newMessage = [[Message alloc] initWithMessage:@"Successfully you see a new content" withAppController:self];
+ [newContent addObject:newMessage];
+ [controller setContent:newContent];
+
+ // Uncomment the following line to turn on the standard menu bar.
+ //[CPMenu setMenuBarVisible:YES];
+}
+
+- (CPArrayController)controller
+{
+ return controller;
+}
+
+- (CPString)log
+{
+ return log;
+}
+
+- (void)setLog:(CPString)aLog
+{
+ log = aLog;
+}
+
+- (CPString)selectedValue
+{
+ return selectedValue;
+}
+
+- (void)setSelectedValue:(CPString)aSelectedValue
+{
+ selectedValue = aSelectedValue;
+}
+
+- (void)observeValueForKeyPath:(CPString)keyPath ofObject:(id)object change:(CPDictionary)change context:(id)context
+{
+ var newIndex = [change valueForKey:CPKeyValueChangeNewKey],
+ selectedObject = [[object content] objectAtIndex:newIndex];
+
+ return [self setSelectedValue:@"Current Value via selectionIndex: " + [selectedObject messageWithoutCheck]];
+}
+
+@end
+
+@implementation Message : CPObject
+{
+ CPString message;
+ AppController app;
+}
+
+- (id)initWithMessage:(CPString)aMessage withAppController:(AppController)anApp
+{
+ self = [super init];
+ if (self)
+ {
+ message = aMessage;
+ app = anApp;
+ }
+ return self;
+}
+
+- (CPString)message
+{
+ [app setLog:@"the following message is about to be read: " + message];
+ return message;
+}
+
+- (CPString)messageWithoutCheck
+{
+ return message;
+}
+
+@end
12 Tests/Manual/ArrayControllerInitialSelectionTest/Info.plist
View
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CPApplicationDelegateClass</key>
+ <string>AppController</string>
+ <key>CPBundleName</key>
+ <string>ArrayControllerInitialSelectionTest</string>
+ <key>CPPrincipalClass</key>
+ <string>CPApplication</string>
+</dict>
+</plist>
93 Tests/Manual/ArrayControllerInitialSelectionTest/Jakefile
View
@@ -0,0 +1,93 @@
+/*
+ * Jakefile
+ * ArrayControllerInitialSelectionTest
+ *
+ * Created by You on July 21, 2012.
+ * Copyright 2012, Your Company All rights reserved.
+ */
+
+var ENV = require("system").env,
+ FILE = require("file"),
+ JAKE = require("jake"),
+ task = JAKE.task,
+ FileList = JAKE.FileList,
+ app = require("cappuccino/jake").app,
+ configuration = ENV["CONFIG"] || ENV["CONFIGURATION"] || ENV["c"] || "Debug",
+ OS = require("os");
+
+app ("ArrayControllerInitialSelectionTest", function(task)
+{
+ task.setBuildIntermediatesPath(FILE.join("Build", "ArrayControllerInitialSelectionTest.build", configuration));
+ task.setBuildPath(FILE.join("Build", configuration));
+
+ task.setProductName("ArrayControllerInitialSelectionTest");
+ task.setIdentifier("com.yourcompany.ArrayControllerInitialSelectionTest");
+ task.setVersion("1.0");
+ task.setAuthor("Your Company");
+ task.setEmail("feedback @nospam@ yourcompany.com");
+ task.setSummary("ArrayControllerInitialSelectionTest");
+ task.setSources((new FileList("**/*.j")).exclude(FILE.join("Build", "**")));
+ task.setResources(new FileList("Resources/**"));
+ task.setIndexFilePath("index.html");
+ task.setInfoPlistPath("Info.plist");
+
+ if (configuration === "Debug")
+ task.setCompilerFlags("-DDEBUG -g");
+ else
+ task.setCompilerFlags("-O");
+});
+
+task ("default", ["ArrayControllerInitialSelectionTest"], function()
+{
+ printResults(configuration);
+});
+
+task ("build", ["default"]);
+
+task ("debug", function()
+{
+ ENV["CONFIGURATION"] = "Debug";
+ JAKE.subjake(["."], "build", ENV);
+});
+
+task ("release", function()
+{
+ ENV["CONFIGURATION"] = "Release";
+ JAKE.subjake(["."], "build", ENV);
+});
+
+task ("run", ["debug"], function()
+{
+ OS.system(["open", FILE.join("Build", "Debug", "ArrayControllerInitialSelectionTest", "index.html")]);
+});
+
+task ("run-release", ["release"], function()
+{
+ OS.system(["open", FILE.join("Build", "Release", "ArrayControllerInitialSelectionTest", "index.html")]);
+});
+
+task ("deploy", ["release"], function()
+{
+ FILE.mkdirs(FILE.join("Build", "Deployment", "ArrayControllerInitialSelectionTest"));
+ OS.system(["press", "-f", FILE.join("Build", "Release", "ArrayControllerInitialSelectionTest"), FILE.join("Build", "Deployment", "ArrayControllerInitialSelectionTest")]);
+ printResults("Deployment")
+});
+
+task ("desktop", ["release"], function()
+{
+ FILE.mkdirs(FILE.join("Build", "Desktop", "ArrayControllerInitialSelectionTest"));
+ require("cappuccino/nativehost").buildNativeHost(FILE.join("Build", "Release", "ArrayControllerInitialSelectionTest"), FILE.join("Build", "Desktop", "ArrayControllerInitialSelectionTest", "ArrayControllerInitialSelectionTest.app"));
+ printResults("Desktop")
+});
+
+task ("run-desktop", ["desktop"], function()
+{
+ OS.system([FILE.join("Build", "Desktop", "ArrayControllerInitialSelectionTest", "ArrayControllerInitialSelectionTest.app", "Contents", "MacOS", "NativeHost"), "-i"]);
+});
+
+function printResults(configuration)
+{
+ print("----------------------------");
+ print(configuration+" app built at path: "+FILE.join("Build", configuration, "ArrayControllerInitialSelectionTest"));
+ print("----------------------------");
+}
BIN  Tests/Manual/ArrayControllerInitialSelectionTest/Resources/spinner.gif
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
107 Tests/Manual/ArrayControllerInitialSelectionTest/index-debug.html
View
@@ -0,0 +1,107 @@
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<!--
+ index-debug.html
+ ArrayControllerInitialSelectionTest
+
+ Created by You on July 21, 2012.
+ Copyright 2012, Your Company All rights reserved.
+-->
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7, chrome=1" />
+
+ <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
+
+ <meta name="apple-mobile-web-app-capable" content="yes" />
+ <meta name="apple-mobile-web-app-status-bar-style" content="black" />
+
+ <link rel="apple-touch-icon" href="Resources/icon.png" />
+ <link rel="apple-touch-startup-image" href="Resources/default.png" />
+
+ <title>ArrayControllerInitialSelectionTest</title>
+
+ <script type="text/javascript">
+ OBJJ_MAIN_FILE = "main.j";
+ OBJJ_INCLUDE_PATHS = ["Frameworks/Debug", "Frameworks", "SomethingElse"];
+ </script>
+
+ <script src="Frameworks/Debug/Objective-J/Objective-J.js" type="text/javascript" charset="UTF-8"></script>
+
+ <script type="text/javascript">
+ objj_msgSend_reset();
+
+ // DEBUG OPTIONS:
+
+ // Uncomment to enable printing of backtraces on exceptions:
+ //objj_msgSend_decorate(objj_backtrace_decorator);
+
+ // Uncomment to supress exceptions that take place inside a message
+ //objj_msgSend_decorate(objj_supress_exceptions_decorator)
+
+ // Uncomment to enable runtime type checking:
+ //objj_msgSend_decorate(objj_typecheck_decorator);
+
+ // Uncomment (along with both above) to print backtraces on type check errors:
+ //objj_typecheck_prints_backtrace = true;
+
+ // Uncomment to disable the default logger (CPLogConsole if window.console exists, CPLogPopup otherwise):
+ //CPLogUnregister(CPLogDefault);
+
+ // Uncomment to enable a specific logger:
+ //CPLogRegister(CPLogConsole);
+ //CPLogRegister(CPLogPopup);
+
+ // Tag view DOM elements with a "data-cappuccino-view" attribute that contains
+ // the class name of the view that created them. Comment this or set to false to disable.
+ appkit_tag_dom_elements = true;
+ </script>
+
+ <style type="text/css">
+ body{margin:0; padding:0;}
+ #container {position: absolute; top:50%; left:50%;}
+ #content {width:800px; text-align:center; margin-left: -400px; height:50px; margin-top:-25px; line-height: 50px;}
+ #content {font-family: "Helvetica", "Arial", sans-serif; font-size: 18px; color: black; text-shadow: 0px 1px 0px white; }
+ #loadgraphic {margin-right: 0.2em; margin-bottom:-2px;}
+ </style>
+
+ <!--[if lt IE 7]>
+ <STYLE type="text/css">
+ #container { position: relative; top: 50%; }
+ #content { position: relative;}
+ </STYLE>
+ <![endif]-->
+
+ </head>
+
+ <body style="">
+ <div id="cappuccino-body">
+ <div id="loadingcontainer" style="background-color: #eeeeee; overflow:hidden; width:100%; height:100%; position: absolute; top: 0; left: 0;">
+ <script type="text/javascript">
+ document.write("<div id='container'><p id='content'>" +
+ "<img id='loadgraphic' width='16' height='16' src='Resources/spinner.gif' /> " +
+ "Loading ArrayControllerInitialSelectionTest...</p></div>");
+ </script>
+
+ <noscript>
+ <div id="container">
+ <div style="width: 440px; padding: 10px 25px 20px 25px; font-family: sans-serif; background-color: #ffffff; position: relative; left: -245px; top: -120px; text-align: center; -moz-border-radius: 20px; -webkit-border-radius: 20px; color: #555555">
+ <p style="line-height: 1.4em;">JavaScript is required for this site to work correctly but is either disabled or not supported by your browser.</p>
+ <p style="font-size:120%; padding:10px;"><a href="http://cappuccino.org/noscript">Show me how to enable JavaScript</a></p>
+ <p style="font-size:80%;">You may want to upgrade to a newer browser while you're at it:</p>
+ <ul style="margin:0;padding:0; text-align: center; font-size:80%;" >
+ <li style="display: inline;"><a href="http://www.apple.com/safari/download/">Safari</a></li>
+ <li style="display: inline;"><a href="http://www.mozilla.com/en-US/firefox/">Firefox</a></li>
+ <li style="display: inline;"><a href="http://www.google.com/chrome/">Chrome</a></li>
+ <li style="display: inline;"><a href="http://www.opera.com/download/">Opera</a></li>
+ <li style="display: inline;"><a href="http://www.microsoft.com/windows/downloads/ie/getitnow.mspx">Internet Explorer</a></li>
+ </ul>
+ </div>
+ </div>
+ </noscript>
+ </div>
+ </div>
+ </body>
+
+</html>
78 Tests/Manual/ArrayControllerInitialSelectionTest/index.html
View
@@ -0,0 +1,78 @@
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<!--
+ index.html
+ ArrayControllerInitialSelectionTest
+
+ Created by You on July 21, 2012.
+ Copyright 2012, Your Company All rights reserved.
+-->
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7, chrome=1" />
+
+ <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
+
+ <meta name="apple-mobile-web-app-capable" content="yes" />
+ <meta name="apple-mobile-web-app-status-bar-style" content="black" />
+
+ <link rel="apple-touch-icon" href="Resources/icon.png" />
+ <link rel="apple-touch-startup-image" href="Resources/default.png" />
+
+ <title>ArrayControllerInitialSelectionTest</title>
+
+ <script type="text/javascript">
+ OBJJ_MAIN_FILE = "main.j";
+ </script>
+
+ <script type="text/javascript" src="Frameworks/Objective-J/Objective-J.js" charset="UTF-8"></script>
+
+ <style type="text/css">
+ body{margin:0; padding:0;}
+ #container {position: absolute; top:50%; left:50%;}
+ #content {width:800px; text-align:center; margin-left: -400px; height:50px; margin-top:-25px; line-height: 50px;}
+ #content {font-family: "Helvetica", "Arial", sans-serif; font-size: 18px; color: black; text-shadow: 0px 1px 0px white; }
+ #loadgraphic {margin-right: 0.2em; margin-bottom:-2px;}
+ </style>
+
+ <!--[if lt IE 7]>
+ <STYLE type="text/css">
+ #container { position: relative; top: 50%; }
+ #content { position: relative;}
+ </STYLE>
+ <![endif]-->
+
+ </head>
+
+ <body style="">
+ <div id="cappuccino-body">
+ <div id="loadingcontainer" style="background-color: #eeeeee; overflow:hidden; width:100%; height:100%; position: absolute; top: 0; left: 0;">
+ <script type="text/javascript">
+ document.write("<div id='container'><p id='content'>" +
+ "<img id='loadgraphic' width='16' height='16' src='Resources/spinner.gif' /> " +
+ "Loading ArrayControllerInitialSelectionTest...</p></div>");
+ </script>
+
+ <noscript>
+ <div id="container">
+ <div style="width: 440px; padding: 10px 25px 20px 25px; font-family: sans-serif; background-color: #ffffff; position: relative; left: -245px; top: -120px; text-align: center; -moz-border-radius: 20px; -webkit-border-radius: 20px; color: #555555">
+ <p style="line-height: 1.4em;">JavaScript is required for this site to work correctly but is either disabled or not supported by your browser.</p>
+ <p style="font-size:120%; padding:10px;"><a href="http://cappuccino.org/noscript">Show me how to enable JavaScript</a></p>
+ <p style="font-size:80%;">You may want to upgrade to a newer browser while you're at it:</p>
+ <ul style="margin:0;padding:0; text-align: center; font-size:80%;" >
+ <li style="display: inline;"><a href="http://www.apple.com/safari/download/">Safari</a></li>
+ <li style="display: inline;"><a href="http://www.mozilla.com/en-US/firefox/">Firefox</a></li>
+ <li style="display: inline;"><a href="http://www.google.com/chrome/">Chrome</a></li>
+ <li style="display: inline;"><a href="http://www.opera.com/download/">Opera</a></li>
+ <li style="display: inline;"><a href="http://www.microsoft.com/windows/downloads/ie/getitnow.mspx">Internet Explorer</a></li>
+ </ul>
+ </div>
+ </div>
+ </noscript>
+ </div>
+ </div>
+ </body>
+
+</html>
+
18 Tests/Manual/ArrayControllerInitialSelectionTest/main.j
View
@@ -0,0 +1,18 @@
+/*
+ * AppController.j
+ * ArrayControllerInitialSelectionTest
+ *
+ * Created by You on July 21, 2012.
+ * Copyright 2012, Your Company All rights reserved.
+ */
+
+@import <Foundation/Foundation.j>
+@import <AppKit/AppKit.j>
+
+@import "AppController.j"
+
+
+function main(args, namedArgs)
+{
+ CPApplicationMain(args, namedArgs);
+}
Something went wrong with that request. Please try again.