Example #1
0
// Load loads a new component with the provided location and with the
// content read from r. The location informs the resource name for
// logged messages, and its path is used to locate any other resources
// referenced by the QML content.
//
// Once a component is loaded, component instances may be created from
// the resulting object via its Create and CreateWindow methods.
func (e *Engine) Load(location string, r io.Reader) (Object, error) {
	var cdata *C.char
	var cdatalen C.int

	qrc := strings.HasPrefix(location, "qrc:")
	if qrc {
		if r != nil {
			return nil, fmt.Errorf("cannot load qrc resource while providing data: %s", location)
		}
	} else {
		data, err := ioutil.ReadAll(r)
		if err != nil {
			return nil, err
		}
		if colon, slash := strings.Index(location, ":"), strings.Index(location, "/"); colon == -1 || slash <= colon {
			if filepath.IsAbs(location) {
				location = "file:///" + filepath.ToSlash(location)
			} else {
				dir, err := os.Getwd()
				if err != nil {
					return nil, fmt.Errorf("cannot obtain absolute path: %v", err)
				}
				location = "file:///" + filepath.ToSlash(filepath.Join(dir, location))
			}
		}

		// Workaround issue #84 (QTBUG-41193) by not refering to an existent file.
		if s := strings.TrimPrefix(location, "file:///"); s != location {
			if _, err := os.Stat(filepath.FromSlash(s)); err == nil {
				location = location + "."
			}
		}

		cdata, cdatalen = unsafeBytesData(data)
	}

	var err error
	cloc, cloclen := unsafeStringData(location)
	comp := &Common{engine: e}
	RunMain(func() {
		// TODO The component's parent should probably be the engine.
		comp.addr = C.newComponent(e.addr, nilPtr)
		if qrc {
			C.componentLoadURL(comp.addr, cloc, cloclen)
		} else {
			C.componentSetData(comp.addr, cdata, cdatalen, cloc, cloclen)
		}
		message := C.componentErrorString(comp.addr)
		if message != nilCharPtr {
			err = errors.New(strings.TrimRight(C.GoString(message), "\n"))
			C.free(unsafe.Pointer(message))
		}
	})
	if err != nil {
		return nil, err
	}
	return comp, nil
}
Example #2
0
// Load loads a new component with the provided location and with the
// content read from r. The location informs the resource name for
// logged messages, and its path is used to locate any other resources
// referenced by the QML content.
//
// Once a component is loaded, component instances may be created from
// the resulting object via its Create and CreateWindow methods.
func (e *Engine) Load(location string, r io.Reader) (Object, error) {
	data, err := ioutil.ReadAll(r)
	if err != nil {
		return nil, err
	}
	if colon, slash := strings.Index(location, ":"), strings.Index(location, "/"); colon == -1 || slash <= colon {
		//println("location:", location)
		//if !filepath.IsAbs(location) {
		//	dir, err := os.Getwd()
		//	if err != nil {
		//		return nil, fmt.Errorf("cannot obtain absolute path: %v", err)
		//	}
		//	location = filepath.Join(dir, location)
		//}
		//cpath, cpathLen := unsafeStringData(location)
		//curl := C.urlFromLocalFile(cpath, cpathLen)
		//if curl == nilCharPtr {
		//	return nil, fmt.Errorf("cannot parse local path: %q", location)
		//}
		//url := C.GoString(curl)
		//C.free(unsafe.Pointer(curl))
		//println("location:", url)

		if filepath.IsAbs(location) {
			location = "file://" + filepath.ToSlash(location)
		} else {
			dir, err := os.Getwd()
			if err != nil {
				return nil, fmt.Errorf("cannot obtain absolute path: %v", err)
			}
			location = "file://" + filepath.ToSlash(filepath.Join(dir, location))
		}

	}

	cdata, cdatalen := unsafeBytesData(data)
	cloc, cloclen := unsafeStringData(location)
	comp := &Common{engine: e}
	gui(func() {
		// TODO The component's parent should probably be the engine.
		comp.addr = C.newComponent(e.addr, nilPtr)
		C.componentSetData(comp.addr, cdata, cdatalen, cloc, cloclen)
		message := C.componentErrorString(comp.addr)
		if message != nilCharPtr {
			err = errors.New(strings.TrimRight(C.GoString(message), "\n"))
			C.free(unsafe.Pointer(message))
		}
	})
	if err != nil {
		return nil, err
	}
	return comp, nil
}
Example #3
0
File: qml.go Project: hahaya/qml
// Load loads a new component with the provided location and with the
// content read from r. The location informs the resource name for
// logged messages, and its path is used to locate any other resources
// referenced by the QML content.
//
// Once a component is loaded, component instances may be created from
// the resulting object via its Create and CreateWindow methods.
func (e *Engine) Load(location string, r io.Reader) (*Object, error) {
	data, err := ioutil.ReadAll(r)
	if err != nil {
		return nil, err
	}
	if colon, slash := strings.Index(location, ":"), strings.Index(location, "/"); colon == -1 || slash <= colon {
		// TODO Better testing for this.
		if filepath.IsAbs(location) {
			location = "file:" + filepath.ToSlash(location)
		} else {
			dir, err := os.Getwd()
			if err != nil {
				return nil, fmt.Errorf("cannot obtain absolute path: %v", err)
			}
			location = "file:" + filepath.ToSlash(filepath.Join(dir, location))
		}
	}

	cdata, cdatalen := unsafeBytesData(data)
	cloc, cloclen := unsafeStringData(location)
	comp := &Object{engine: e}
	gui(func() {
		// TODO The component's parent should probably be the engine.
		comp.addr = C.newComponent(e.addr, nilPtr)
		C.componentSetData(comp.addr, cdata, cdatalen, cloc, cloclen)
		message := C.componentErrorString(comp.addr)
		if message != nilCharPtr {
			err = errors.New(strings.TrimRight(C.GoString(message), "\n"))
			C.free(unsafe.Pointer(message))
		}
	})
	if err != nil {
		return nil, err
	}
	return comp, nil
}