diff --git a/internal/binding/parser/class.go b/internal/binding/parser/class.go index ee0d962f..7d3df730 100755 --- a/internal/binding/parser/class.go +++ b/internal/binding/parser/class.go @@ -20,6 +20,7 @@ type Class struct { Variables []*Variable `xml:"variable"` Properties []*Variable `xml:"property"` Classes []*Class `xml:"class"` + Since string `xml:"since,attr"` DocModule string Stub bool diff --git a/internal/binding/parser/function.go b/internal/binding/parser/function.go index 174b7fb1..7f82947f 100755 --- a/internal/binding/parser/function.go +++ b/internal/binding/parser/function.go @@ -23,6 +23,7 @@ type Function struct { Signature string `xml:"signature,attr"` Parameters []*Parameter `xml:"parameter"` Brief string `xml:"brief,attr"` + Since string `xml:"since,attr"` SignalMode string TemplateModeJNI string Default bool diff --git a/internal/cmd/minimal/minimal.go b/internal/cmd/minimal/minimal.go index 5413b8cc..21540222 100755 --- a/internal/cmd/minimal/minimal.go +++ b/internal/cmd/minimal/minimal.go @@ -152,12 +152,27 @@ func Minimal(appPath, buildTarget string) { } if buildTarget == "sailfish" || buildTarget == "sailfish-emulator" { - if _, ok := parser.State.ClassMap["QQuickWidget"]; ok { - parser.State.ClassMap["QQuickWidget"].Export = false - } if _, ok := parser.State.ClassMap["TestCase"]; ok { delete(parser.State.ClassMap, "TestCase") } + + for _, c := range parser.State.ClassMap { + switch c.Since { + case "5.3", "5.4", "5.5", "5.6", "5.7", "5.8": + delete(parser.State.ClassMap, c.Name) + } + + if !IsWhiteListedSailfishLib(c.Module) { + delete(parser.State.ClassMap, c.Name) + } + + for _, f := range c.Functions { + switch f.Since { + case "5.3", "5.4", "5.5", "5.6", "5.7", "5.8": + f.Export = false + } + } + } } if buildTarget == "ios" || buildTarget == "ios-simulator" { @@ -270,3 +285,17 @@ func isBlacklisted(appPath, currentPath string) bool { return false } + +func IsWhiteListedSailfishLib(name string) bool { + switch name { + case "Core", "Quick", "Qml", "Network", "Gui", "Concurrent", "Multimedia", "Sql", "Svg", "XmlPatterns", "Xml", "DBus", "WebKit", "Sensors", "Positioning": + { + return true + } + + default: + { + return false + } + } +} diff --git a/internal/cmd/setup/install.go b/internal/cmd/setup/install.go index c4f2bc3f..216a9869 100755 --- a/internal/cmd/setup/install.go +++ b/internal/cmd/setup/install.go @@ -25,22 +25,16 @@ func install(buildTarget string) { var env, tagFlags = getEnvAndTagflags(buildTarget) if buildTarget == "sailfish" { - env["GOARCH"] = "386" delete(env, "GOARM") var _, err = ioutil.ReadDir(filepath.Join(runtime.GOROOT(), "bin", "linux_386")) if err != nil { - var build = exec.Command(filepath.Join(runtime.GOROOT(), "src", func() string { - if runtime.GOOS == "windows" { - return "run.bat" - } - return "run.bash" - }())) + var build = exec.Command("go", "tool", "dist", "test", "-rebuild", "-run=no_tests") for key, value := range env { build.Env = append(build.Env, fmt.Sprintf("%v=%v", key, value)) } - build.Run() + utils.RunCmd(build, "failed to setup linux go tools for sailfish") } } diff --git a/internal/cmd/setup/test.go b/internal/cmd/setup/test.go index 40e3a492..d03de0c1 100755 --- a/internal/cmd/setup/test.go +++ b/internal/cmd/setup/test.go @@ -50,7 +50,7 @@ func test(buildTarget string) { //"grpc": []string{"hello_world","hello_world2"}, "qml": []string{"application", "drawer_nav_x", "gallery", "material", - "prop", "prop2"}, + "listview", "prop", "prop2"}, "quick": []string{"bridge", "bridge2", "calc", "dialog", "dynamic", "hotreload", "listview", "sailfish", "tableview", "translate", "view"}, @@ -64,14 +64,20 @@ func test(buildTarget string) { filepath.Join("treeview", "treeview_filelist"), "video_player"}, } } else { - examples = map[string][]string{ - "qml": []string{"application", "drawer_nav_x", "gallery"}, + if strings.HasPrefix(buildTarget, "sailfish") { + examples = map[string][]string{ + "quick": []string{"sailfish"}, + } + } else { + examples = map[string][]string{ + "qml": []string{"application", "drawer_nav_x", "gallery"}, - "quick": []string{"calc"}, + "quick": []string{"calc"}, - "sql": []string{"querymodel"}, + "sql": []string{"querymodel"}, - "widgets": []string{"line_edits", "pixel_editor", "textedit", "video_player"}, + "widgets": []string{"line_edits", "pixel_editor", "textedit", "video_player"}, + } } } @@ -80,10 +86,6 @@ func test(buildTarget string) { for _, example := range list { var example = filepath.Join(cat, example) - if strings.HasPrefix(buildTarget, "sailfish") && strings.HasPrefix(example, "widgets") { - utils.Log.Infoln("skipping example", example) - continue - } utils.Log.Infoln("testing", example) deploy.Deploy(&deploy.State{ diff --git a/internal/examples/qml/listview/main.go b/internal/examples/qml/listview/main.go new file mode 100755 index 00000000..2fc31c86 --- /dev/null +++ b/internal/examples/qml/listview/main.go @@ -0,0 +1,50 @@ +package main + +import ( + "os" + "time" + + "github.com/therecipe/qt/core" + "github.com/therecipe/qt/gui" + "github.com/therecipe/qt/qml" +) + +func main() { + gui.NewQGuiApplication(len(os.Args), os.Args) + + var view = qml.NewQQmlApplicationEngine(nil) + + var model = NewPersonModel(nil) + + var p = NewPerson(nil) + p.SetFirstName("john") + p.SetLastName("doe") + model.SetPeople([]*Person{p}) + + view.RootContext().SetContextProperty("PersonModel", model) + + view.Load(core.NewQUrl3("qrc:///qml/main.qml", 0)) + + go func() { + + time.Sleep(5 * time.Second) + + //add person + for i := 0; i < 3; i++ { + var p = NewPerson(nil) + p.SetFirstName("hello") + p.SetLastName("world") + model.AddPerson(p) + } + + //edit person + model.EditPerson(1, "bob", "") + model.EditPerson(3, "", "john") + + //remove person + model.RemovePerson(2) + + }() + + gui.QGuiApplication_Exec() +} diff --git a/internal/examples/qml/listview/personmodel.go b/internal/examples/qml/listview/personmodel.go new file mode 100755 index 00000000..0ef09ebc --- /dev/null +++ b/internal/examples/qml/listview/personmodel.go @@ -0,0 +1,116 @@ +package main + +import "github.com/therecipe/qt/core" + +const ( + FirstName = int(core.Qt__UserRole) + 1<= len(m.People()) { + return core.NewQVariant() + } + + var p = m.People()[index.Row()] + + switch role { + case FirstName: + { + return core.NewQVariant14(p.FirstName()) + } + + case LastName: + { + return core.NewQVariant14(p.LastName()) + } + + default: + { + return core.NewQVariant() + } + } +} + +func (m *PersonModel) rowCount(parent *core.QModelIndex) int { + return len(m.People()) +} + +func (m *PersonModel) columnCount(parent *core.QModelIndex) int { + return 1 +} + +func (m *PersonModel) roleNames() map[int]*core.QByteArray { + return m.Roles() +} + +func (m *PersonModel) addPerson(p *Person) { + m.BeginInsertRows(core.NewQModelIndex(), len(m.People()), len(m.People())) + m.SetPeople(append(m.People(), p)) + m.EndInsertRows() +} + +func (m *PersonModel) editPerson(row int, firstName string, lastName string) { + var p = m.People()[row] + + if firstName != "" { + p.SetFirstName(firstName) + } + + if lastName != "" { + p.SetLastName(lastName) + } + + var pIndex = m.Index(row, 0, core.NewQModelIndex()) + m.DataChanged(pIndex, pIndex, []int{FirstName, LastName}) +} + +func (m *PersonModel) removePerson(row int) { + m.BeginRemoveRows(core.NewQModelIndex(), row, row) + m.SetPeople(append(m.People()[:row], m.People()[row+1:]...)) + m.EndRemoveRows() +} diff --git a/internal/examples/qml/listview/qml/main.qml b/internal/examples/qml/listview/qml/main.qml new file mode 100755 index 00000000..14f39d70 --- /dev/null +++ b/internal/examples/qml/listview/qml/main.qml @@ -0,0 +1,15 @@ +import QtQuick 2.2 +import QtQuick.Controls 2.0 +import QtQuick.Layouts 1.3 + +ApplicationWindow { + visible: true + + ListView { + id: listView + model: PersonModel + delegate: Text { + text: firstName + " " + lastName + } + } +}