The name `find' does not exist in the context of `GLib.ListStore' - listbox

I'm totally clueless why this error is being thrown. The valadoc shows that this function exist. The append function also works. Here's the code to reproduce it:
class some_object : GLib.Object {
public int val {get; construct;}
public some_object (int val) {
Object (
val: val
);
}
}
class ExampleList : Gtk.ApplicationWindow {
construct {
var dummy = new some_object(0);
var model = new GLib.ListStore (GLib.Type.from_instance (dummy));
model.append (dummy);
uint position;
model.find (dummy, out position);
// ^^^^
}
}
class MyApplication : Gtk.Application {
public MyApplication () {
Object (
application_id: "com.example.listbox"
);
}
public override void activate () {
new ExampleList (). show_all ();
}
}
public static int main (string[] args) {
return new MyApplication (). run (args);
}
To compile I use:
valac --pkg=gtk+-3.0 so.vala
And the error I'm getting is:
so.vala:18.9-18.18: error: The name `find' does not exist in the context of `GLib.ListStore'
model.find (dummy, out position);
^^^^^^^^^^
Compilation failed: 1 error(s), 0 warning(s)

From the reference document you link to:
[ Version ( since = "2.64" ) ]
This GIO version was only released this year: it's likely that you are using an older version that does not include this function.

Related

How to convert a GLib.Value of type GStrv (string[]) to a GLib.Variant

In the following example one class property is of type Gstrv.
With ObjectClass.list_properties() one can query the Paramspec of all properties, and with get_property() all properties can be requested as GLib.Value. How would I access the Value of type GStrv and convert it to a GLib.Variant?
My GLib version is slightly outdated, so I do not have the GLib.Value.to_variant() function available yet :( .
public class Foo: GLib.Object {
public GLib.HashTable<string, int32> bar;
public Foo() {
bar = new GLib.HashTable<string, int32>(str_hash, str_equal);
}
public string[] bar_keys { owned get { return bar.get_keys_as_array(); } }
}
int main() {
var foo = new Foo();
Type type = foo.get_type();
ObjectClass ocl = (ObjectClass) type.class_ref ();
foreach (ParamSpec spec in ocl.list_properties ()) {
print ("%s\n", spec.get_name ());
Value property_value = Value(spec.value_type);
print ("%s\n", property_value.type_name ());
foo.get_property(spec.name, ref property_value);
// next: convert GLib.Value -> GLib.Variant :(
}
foo.bar.set("baz", 42);
return 0;
}
Output:
bar-keys
GStrv
Using GLib.Value.get_boxed() seems to be working.
Example:
// compile simply with: valac valacode.vala
public class Foo: GLib.Object {
public GLib.HashTable<string, int32> bar;
public Foo() {
bar = new GLib.HashTable<string, int32>(str_hash, str_equal);
}
public string[] bar_keys { owned get { return bar.get_keys_as_array(); } }
}
public Variant first_gstrv_property_as_variant(Object obj)
{
Type class_type = obj.get_type();
ObjectClass ocl = (ObjectClass) class_type.class_ref ();
foreach (ParamSpec spec in ocl.list_properties ()) {
print ("%s\n", spec.get_name ());
Value property_value = Value(spec.value_type);
print ("%s\n", property_value.type_name ());
obj.get_property(spec.name, ref property_value);
// next: convert GLib.Value -> GLib.Variant
if(property_value.type_name () == "GStrv") {
return new GLib.Variant.strv((string[])property_value.get_boxed());
}
}
return new GLib.Variant("s", "No property of type GStrv found");
}
int main() {
var foo = new Foo();
print("%s\n", first_gstrv_property_as_variant(foo).print(true));
foo.bar.set("baz", 42);
print("%s\n", first_gstrv_property_as_variant(foo).print(true));
foo.bar.set("zot", 3);
print("%s\n", first_gstrv_property_as_variant(foo).print(true));
return 0;
}
Output:
bar-keys
GStrv
#as []
bar-keys
GStrv
['baz']
bar-keys
GStrv
['baz', 'zot']
In the generated c-code this looks as follows:
_tmp18_ = g_value_get_boxed (&property_value);
_tmp19_ = g_variant_new_strv ((gchar**) _tmp18_, -1);
Passing -1 as length to g_variant_new_strv() means the string array is considered as null terminated. Inside g_variant_new_strv() the g_strv_length() function is used to determine the length.
Hopefully it will be useful to someone else someday. :-)

Instantiation of object in Vala generic

I want to create a new object of given type inside of generic in Vala language.
class MyClass <T> : GLib.Object
{
protected T data;
public MyClass ()
{
data = new T ();
}
}
I understand that this can't work, but what is the way to do something like that?
You are probably best instantiating it when calling the constructor for MyClass:
void main () {
new MyClass<Test> (new Test ());
new MyClass<Example> (new Example ());
}
class MyClass <T>
{
protected T data;
public MyClass (T data)
{
this.data = data;
}
}
class Test {}
class Example {}
Vala generics do not currently provide constraints. If you are going to pass in a dependency in this way you may want to consider using an interface type instead of a generic type.
Update
If you are wanting to implement a factory then an interface with a static method or function is probably best:
void main () {
var a = CommandFactory.get_command ("A");
var b = CommandFactory.get_command ("B");
a.run ();
b.run ();
}
namespace CommandFactory {
Command get_command (string criteria) {
Command result = null;
switch (criteria) {
case "A":
result = new CommandA ();
break;
case "B":
result = new CommandB ();
break;
default:
assert_not_reached ();
}
return result;
}
}
interface Command:Object {
public abstract void run ();
}
class CommandA:Object, Command {
void run () { print ("A\n"); }
}
class CommandB:Object, Command {
void run () { print ("B\n"); }
}
I assume by 'abstract fabric pattern' you mean 'abstract factory pattern'? You could try using GType introspection to then instantiate the Object, but it must be a GObject and you by pass Vala's static analysis checks:
void main () {
new MyClass<Example> (new Example ());
/* These will fail at runtime
new MyClass<string> ("this will fail at runtime");
new MyClass<ThisWillFailAtRuntime> (new ThisWillFailAtRuntime ());
*/
}
class MyClass <T>
{
protected T data;
public MyClass (T data)
{
assert (typeof(T).is_object());
this.data = Object.new (typeof(T));
}
}
class Example:Object {}
class ThisWillFailAtRuntime {}
Note that Object.new() is also a static method.
I'm not sure what you are trying to achieve, but you are probably better looking more closely at interfaces and favouring composition over inheritance in your object data model.

Reusing signal handlers?

Is there a way in Vala to have multiple signal handlers perform the same code, while they have access to the local scope?
Defining a lambda using a delegate works, but requires a delegate definition and gives the warning "copying delegates is not supported":
delegate void ChangeHandler ();
void test () {
var answer = 42;
ChangeHandler handler = () => {
debug("size or position changed. answer: %i", answer);
};
size_changed.connect (handler);
position_changed.connect (handler);
}
As far as I know there is also no way to pass information to handlers? something like:
void test () {
var answer = 42;
size_changed.connect (handler, answer);
position_changed.connect (handler, answer);
}
void handler (answer) {
debug("size or position changed. answer: %i", answer);
}
I could do this, but this requires a lot of extra code, especially when there are many arguments.
void test () {
var answer = 42;
size_changed.connect (handler, answer);
position_changed.connect (() => handler(answer));
}
void handler (answer) {
debug("size or position changed. answer: %i", answer);
}
Is there a way to connect multiple signals to one anonymous function? Something like:
void test () {
var answer = 42;
multi_connect(size_changed, position_changed, () => {
debug("size or position changed. answer: %i", answer);
});
}
How about using this to pass data:
public class Test : GLib.Object {
public signal void sig_1 ();
public signal void sig_2 ();
private int answer = 42;
private void sig_handler (Test t) {
stdout.printf("sig_1 or sig_2 triggered. answer: %d\n", answer);
}
public static int main(string[] args) {
Test t1 = new Test();
t1.sig_1.connect(t1.sig_handler);
t1.sig_2.connect(t1.sig_handler);
t1.sig_1();
t1.sig_2();
return 0;
}
}
Maybe it is more readable with two classes:
public class SignalRaiser : GLib.Object {
public signal void sig_1 ();
public signal void sig_2 ();
}
public class SignalReceiver : GLib.Object {
private int answer = 42;
public void sig_handler (SignalRaiser sender) {
stdout.printf("sig_1 or sig_2 triggered. answer: %d\n", answer);
}
}
int main(string[] args) {
var raiser = new SignalRaiser();
var receiver = new SignalReceiver();
raiser.sig_1.connect(receiver.sig_handler);
raiser.sig_2.connect(receiver.sig_handler);
raiser.sig_1();
raiser.sig_2();
return 0;
}

handleURI for http://AAA.BBB.CCC.DDD:8080/myapp/ uri: '' returns ambigious result (Vaadin 6)

In my Vaadin 6 application I sometimes get the following error:
SEVERE: Terminal error:
java.lang.RuntimeException: handleURI for http://AAA.BBB.CCC.DDD:8080/myapp/ uri: '' returns ambigious result.
at com.vaadin.ui.Window.handleURI(Window.java:432)
at com.vaadin.terminal.gwt.server.AbstractCommunicationManager.handleURI(AbstractCommunicationManager.java:2291)
at com.vaadin.terminal.gwt.server.CommunicationManager.handleURI(CommunicationManager.java:370)
at com.vaadin.terminal.gwt.server.AbstractApplicationServlet.handleURI(AbstractApplicationServlet.java:1099)
at com.vaadin.terminal.gwt.server.AbstractApplicationServlet.service(AbstractApplicationServlet.java:535)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
Accrording to Vaadin source it occurs in the following method:
public DownloadStream handleURI(URL context, String relativeUri) {
DownloadStream result = null;
if (uriHandlerList != null) {
Object[] handlers;
synchronized (uriHandlerList) {
handlers = uriHandlerList.toArray();
}
for (int i = 0; i < handlers.length; i++) {
final DownloadStream ds = ((URIHandler) handlers[i]).handleURI(
context, relativeUri);
if (ds != null) {
if (result != null) {
throw new RuntimeException("handleURI for " + context
+ " uri: '" + relativeUri
+ "' returns ambigious result.");
}
result = ds;
}
}
}
return result;
}
I actually create a DownloadStream in a column generator (in order to display images in a table):
public class ImageColumnGenerator implements Table.ColumnGenerator {
private static final Logger LOGGER = LoggerFactory.getLogger(ImageColumnGenerator.class);
public final static String IMAGE_FIELD = "image";
public Object generateCell(final Table aTable, final Object aItemId, final Object aColumnId) {
if (!IMAGE_FIELD.equals(aColumnId)) {
return null;
}
final BeanItem<UserProductImageBean> beanItem = (BeanItem<UserProductImageBean>)
aTable.getItem(aItemId);
final StreamResource streamResource = new StreamResource(new StreamResource.StreamSource() {
public InputStream getStream() {
return new ByteArrayInputStream(beanItem.getBean().getImageData());
}
},
beanItem.getBean().getFileName(),
MyApplication.getInstance());
LOGGER.debug("imageResource: " + streamResource);
final Embedded embedded = new Embedded("", streamResource);
return embedded;
}
}
beanItem.getBean().getImageData() is a byte array (byte[]) with image data, which I get from a web service.
MyApplication.getInstance() is defined as follows:
public class MyApplication extends Application implements ApplicationContext.TransactionListener
{
private static ThreadLocal<MyApplication> currentApplication =
new ThreadLocal<MyApplication> ();
public static MyApplication getInstance()
{
return currentApplication.get ();
}
}
What can I do in order to fix the aforementioned (severe) error?
As soon as nobody answer. I'm not at all expert in what hell it is above, but - try to find out on what kind of urls this error arise on, and do with them something before feed them to DownloadStream

a last in, first out (LIFO) abstract data type and data structure. Perhaps the most common use of stacks is to store

MyStack()
{
Vector<Integer> v=new Vector<Integer>(10,2);
}
void push(int n)
{
v.addElement(n);
}
void pop()
{
if(v.isEmpty())
System.out.println("Stack underflow!");
else
System.out.println(v.elementAt(0));
}
void display()
{
for(int i=0;i<v.size();i++)
System.out.print(v.elementAt(i) +" ");
}
}
class StackDemo
{
public static void main(String args[])
{
Scanner in=new Scanner(System.in);
MyStack s=new MyStack();
int option=0;
do
{
System.out.println("1: Push\n2:Pop\n3:Display\n4:Quit");
System.out.println("Enter your option: ");
option=in.nextInt();
switch(option)
{
case 1:
{
System.out.println("Enter an integer:");
int n=in.nextInt();
s.push(n);break;
}
case 2:s.pop();break;
case 3:s.display();break;
}
}
while(option!=4);
}
}
// throws an error: variable v not found. Any help would be much appreciated.Thanks.
It looks like v is being created locally in your constructor instead of as a member of your class.
Try defining v as a class member and then simply assign it in your constructor.
class MyStack {
Vector<Integer> v;
public MyStack() {
v = new Vector<Integer>(10,2);
}
}
Or just assign it when you define it:
class MyStack {
Vector<Integer> v = new Vector<Integer>(10,2);
}
Check out the Java tutorial on class members.

Resources