diff --git a/app.go b/gxui/app.go similarity index 100% rename from app.go rename to gxui/app.go diff --git a/gxui/main.go b/gxui/main.go new file mode 100644 index 0000000..14cdb34 --- /dev/null +++ b/gxui/main.go @@ -0,0 +1,82 @@ +package main + +import ( + "fmt" + "os" + "os/exec" + + "github.com/nelsam/gxui" + "github.com/nelsam/gxui/drivers/gl" + "github.com/nelsam/gxui/themes/dark" + "github.com/nelsam/gxui/themes/light" +) + +const ( + version = "1.1.0.0" + defIni = "[basic]\ntheme=dk" +) + +var ( + dr gxui.Driver + th gxui.Theme + master map[string][]app + linmaster map[string][]app + cats []string + lin []string + wine bool + comEnbld bool + darkTheme = true +) + +func main() { + updated := false + os.MkdirAll("PortableApps/LinuxPACom", 0777) + stat, err := versionDL() + if stat { + res := getVersionFileInfo() + if res != "Error!" { + stat, err = checkForUpdate(res) + if stat { + downloadUpdate(res) + updated = true + } else { + fmt.Println(err) + } + } else { + fmt.Println("Failed Version File Info") + } + } else { + fmt.Println(err) + } + if updated { + cmd := exec.Command("./LinuxPA") + cmd.Stdin = os.Stdin + cmd.Stdout = os.Stdout + cmd.Start() + } else { + master = make(map[string][]app) + linmaster = make(map[string][]app) + gl.StartDriver(appMain) + } +} + +func appMain(dri gxui.Driver) { + dr = dri + setup() + if darkTheme { + th = dark.CreateTheme(dr) + } else { + th = light.CreateTheme(dr) + } + th = dark.CreateTheme(dr) + ui() +} + +func contains(arr []string, str string) bool { + for _, v := range arr { + if v == str { + return true + } + } + return false +} diff --git a/gxui/setup.go b/gxui/setup.go new file mode 100644 index 0000000..0874dd2 --- /dev/null +++ b/gxui/setup.go @@ -0,0 +1,208 @@ +package main + +import ( + "bufio" + "fmt" + "image" + "image/draw" + _ "image/png" + "os" + "reflect" + "sort" + "strings" + + "github.com/nelsam/gxui" +) + +func setup() { + PortableAppsFold, err := os.Open("PortableApps") + if PAStat, _ := PortableAppsFold.Stat(); err != nil || !PAStat.IsDir() { + os.Mkdir("PortableApps", 0777) + PortableAppsFold, err = os.Open("PortableApps") + if err != nil { + panic("Can't find PortableApps folder and can't create one!") + } + } + if _, err = os.Open("PortableApps/LinuxPACom"); err != nil { + os.Mkdir("PortableApps/LinuxPACom", 0777) + } + fmt.Println(err) + _, err = os.Open("PortableApps/LinuxPACom/common.sh") + if err == nil { + comEnbld = true + } + fi, err := os.Open("PortableApps/LinuxPACom/Info.ini") + if err != nil { + fi, err = os.Create("PortableApps/LinuxPACom/Info.ini") + if err == nil { + wrt := bufio.NewWriter(fi) + wrt.WriteString(defIni) + wrt.Flush() + } + } + if err == nil { + rdr := bufio.NewReader(fi) + for err != nil { + ln, _, error := rdr.ReadLine() + err = error + str := string(ln) + if strings.HasPrefix(str, "theme=") { + str = strings.TrimPrefix(str, "theme=") + if str == "lt" { + darkTheme = false + } + } + } + } + PAFolds, _ := PortableAppsFold.Readdirnames(-1) + sort.Strings(PAFolds) + for _, v := range PAFolds { + fold, _ := os.Open("PortableApps/" + v) + if stat, _ := fold.Stat(); stat.IsDir() && stat.Name() != "PortableApps.com" && stat.Name() != "LinuxPACom" { + ap := processApp("PortableApps/" + v) + if !reflect.DeepEqual(ap, app{}) { + if _, ok := master[ap.cat]; !ok { + cats = append(cats, ap.cat) + sort.Strings(cats) + } + if len(ap.lin) != 0 { + if _, ok := linmaster[ap.cat]; !ok { + lin = append(lin, ap.cat) + sort.Strings(lin) + } + } + master[ap.cat] = append(master[ap.cat], ap) + if len(ap.lin) != 0 { + linmaster[ap.cat] = append(linmaster[ap.cat], ap) + } + } + } + } +} + +func processApp(fold string) (out app) { + wd, _ := os.Getwd() + out.dir = wd + "/" + fold + out.ini = findInfo(fold) + if out.ini != nil { + out.name = getName(out.ini) + out.ini = findInfo(fold) + out.cat = getCat(out.ini) + out.ini = findInfo(fold) + } + if out.name == "" { + out.name = strings.TrimPrefix(fold, "PortableApps/") + } + if out.cat == "" { + out.cat = "Other" + } + out.icon = getIcon(fold) + folder, _ := os.Open(fold) + fis, _ := folder.Readdirnames(-1) + for _, v := range fis { + tmp, _ := os.Open(fold + "/" + v) + if stat, _ := tmp.Stat(); stat.IsDir() { + continue + } + if strings.HasSuffix(strings.ToLower(v), ".appimage") { + out.appimg = append(out.appimg, v) + out.ex = append(out.ex, v) + out.lin = append(out.lin, v) + } else if strings.HasSuffix(strings.ToLower(v), ".exe") { + out.ex = append(out.ex, v) + } else { + btys := make([]byte, 4) + rdr := bufio.NewReader(tmp) + rdr.Read(btys) + if (strings.Contains(strings.ToLower(string(btys)), "elf") && !strings.HasSuffix(strings.ToLower(v), ".so") && !strings.Contains(v, ".so.")) || strings.HasPrefix(strings.ToLower(string(btys)), "#!") { + out.ex = append(out.ex, v) + out.lin = append(out.lin, v) + } + } + } + if len(out.ex) == 0 { + return app{} + } + if len(out.lin) == 0 { + out.name += " (Wine)" + } + return +} + +func getCat(ini *os.File) string { + rdr := bufio.NewReader(ini) + var ret string + for line, _, err := rdr.ReadLine(); err == nil; line, _, err = rdr.ReadLine() { + if strings.HasPrefix(string(line), "Category=") { + ret = strings.TrimPrefix(string(line), "Category=") + break + } + } + rdr.Reset(ini) + return ret +} + +func getName(ini *os.File) string { + rdr := bufio.NewReader(ini) + var ret string + for line, _, err := rdr.ReadLine(); err == nil; line, _, err = rdr.ReadLine() { + if strings.HasPrefix(string(line), "Name=") { + ret = strings.TrimPrefix(string(line), "Name=") + break + } + } + rdr.Reset(ini) + return ret +} + +func getIcon(fold string) gxui.Texture { + var pic *os.File + if folder, err := os.Open(fold + "/App/AppInfo"); err == nil { + fis, _ := folder.Readdir(-1) + var pics []string + for _, v := range fis { + if !v.IsDir() && strings.HasSuffix(strings.ToLower(v.Name()), ".png") && strings.HasPrefix(strings.ToLower(v.Name()), "appicon_") { + pics = append(pics, v.Name()) + } + } + sort.Strings(pics) + if len(pics) > 1 { + var ind int + if !contains(pics, "appicon_32.png") { + ind = len(pics) - 1 + } else { + ind = sort.SearchStrings(pics, "appicon_32.png") + } + pic, _ = os.Open(fold + "/App/AppInfo/" + pics[ind]) + } + } else if fi, err := os.Open(fold + "/appicon.png"); err == nil { + pic = fi + } else { + return nil + } + img, _, err := image.Decode(pic) + if err != nil { + return nil + } + rgba := image.NewRGBA(img.Bounds()) + draw.Draw(rgba, img.Bounds(), img, image.ZP, draw.Src) + ret := dr.CreateTexture(rgba, 1) + return ret +} + +func findInfo(fold string) *os.File { + tmp, err := os.Open(fold + "/App/AppInfo") + if err == nil { + fis, _ := tmp.Readdirnames(-1) + for _, v := range fis { + if strings.ToLower(v) == "appinfo.ini" { + tmp, _ := os.Open(fold + "/App/AppInfo/" + v) + return tmp + } + } + } + if fi, err := os.Open(fold + "/appinfo.ini"); err == nil { + return fi + } + return nil +} diff --git a/strList.go b/gxui/strList.go similarity index 100% rename from strList.go rename to gxui/strList.go diff --git a/gxui/ui.go b/gxui/ui.go new file mode 100644 index 0000000..8c83a87 --- /dev/null +++ b/gxui/ui.go @@ -0,0 +1,66 @@ +package main + +import ( + "os" + "os/exec" + + "github.com/nelsam/gxui" +) + +func ui() { + catListAdap := &StrList{} + appListAdap := &catAdap{} + catListAdap.SetStrings(lin) + win := th.CreateWindow(500, 500, "LinuxPA") + top := th.CreateLinearLayout() + top.SetDirection(gxui.BottomToTop) + splBox := th.CreateLinearLayout() + spl := th.CreateSplitterLayout() + spl.SetOrientation(gxui.Horizontal) + catList := th.CreateList() + catList.SetAdapter(catListAdap) + catList.OnSelectionChanged(func(it gxui.AdapterItem) { + appListAdap.setCat(it.(string)) + }) + appList := th.CreateTree() + appList.SetAdapter(appListAdap) + spl.AddChild(catList) + spl.AddChild(appList) + splBox.AddChild(spl) + butBox := th.CreateLinearLayout() + butBox.SetDirection(gxui.LeftToRight) + if _, err := exec.LookPath("wine"); err == nil { + wineBut := th.CreateButton() + wineBut.SetType(gxui.ToggleButton) + wineBut.SetChecked(wine) + wineBut.SetText("Show Windows Apps") + wineBut.OnClick(func(gxui.MouseEvent) { + wine = wineBut.IsChecked() + appListAdap.refresh() + if wineBut.IsChecked() { + catListAdap.SetStrings(cats) + wineBut.SetText("Hide Windows Apps") + } else { + catListAdap.SetStrings(lin) + wineBut.SetText("Show Windows Apps") + } + }) + _, err := os.Open("Start.exe") + if err == nil { + pa := th.CreateButton() + pa.SetText("Open PortableApps Launcher") + pa.OnClick(func(gxui.MouseEvent) { + cmd := exec.Command("wine", "Start.exe") + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + cmd.Start() + }) + butBox.AddChild(pa) + } + butBox.AddChild(wineBut) + } + top.AddChild(butBox) + top.AddChild(splBox) + win.AddChild(top) + win.OnClose(dr.Terminate) +} diff --git a/main.go b/main.go index 14cdb34..68aed07 100644 --- a/main.go +++ b/main.go @@ -5,15 +5,12 @@ import ( "os" "os/exec" + "github.com/gotk3/gotk3/gtk" "github.com/nelsam/gxui" - "github.com/nelsam/gxui/drivers/gl" - "github.com/nelsam/gxui/themes/dark" - "github.com/nelsam/gxui/themes/light" ) const ( - version = "1.1.0.0" - defIni = "[basic]\ntheme=dk" + version = "2.0.0.0" ) var ( @@ -54,24 +51,39 @@ func main() { cmd.Stdout = os.Stdout cmd.Start() } else { - master = make(map[string][]app) - linmaster = make(map[string][]app) - gl.StartDriver(appMain) + // master = make(map[string][]app) + // linmaster = make(map[string][]app) + uiStart() } } -func appMain(dri gxui.Driver) { - dr = dri - setup() - if darkTheme { - th = dark.CreateTheme(dr) - } else { - th = light.CreateTheme(dr) +func uiStart() { + gtk.Init(nil) + win, err := gtk.WindowNew(gtk.WINDOW_TOPLEVEL) + if err != nil { + fmt.Println("Window not created", err) } - th = dark.CreateTheme(dr) - ui() + win.SetTitle("LinuxPA") + win.Connect("destroy", func() { + gtk.MainQuit() + }) + win.SetDefaultSize(500, 500) + ui(win) + gtk.Main() } +// func appMain(dri gxui.Driver) { +// dr = dri +// setup() +// if darkTheme { +// th = dark.CreateTheme(dr) +// } else { +// th = light.CreateTheme(dr) +// } +// th = dark.CreateTheme(dr) +// ui() +// } + func contains(arr []string, str string) bool { for _, v := range arr { if v == str { diff --git a/setup.go b/setup.go index 8290ad2..0874dd2 100644 --- a/setup.go +++ b/setup.go @@ -14,8 +14,6 @@ import ( "github.com/nelsam/gxui" ) -const () - func setup() { PortableAppsFold, err := os.Open("PortableApps") if PAStat, _ := PortableAppsFold.Stat(); err != nil || !PAStat.IsDir() { diff --git a/ui.go b/ui.go index 8c83a87..cfb33db 100644 --- a/ui.go +++ b/ui.go @@ -1,66 +1,7 @@ -package main +package ui -import ( - "os" - "os/exec" +import "github.com/gotk3/gotk3/gtk" - "github.com/nelsam/gxui" -) +func ui(win *gtk.Window) { -func ui() { - catListAdap := &StrList{} - appListAdap := &catAdap{} - catListAdap.SetStrings(lin) - win := th.CreateWindow(500, 500, "LinuxPA") - top := th.CreateLinearLayout() - top.SetDirection(gxui.BottomToTop) - splBox := th.CreateLinearLayout() - spl := th.CreateSplitterLayout() - spl.SetOrientation(gxui.Horizontal) - catList := th.CreateList() - catList.SetAdapter(catListAdap) - catList.OnSelectionChanged(func(it gxui.AdapterItem) { - appListAdap.setCat(it.(string)) - }) - appList := th.CreateTree() - appList.SetAdapter(appListAdap) - spl.AddChild(catList) - spl.AddChild(appList) - splBox.AddChild(spl) - butBox := th.CreateLinearLayout() - butBox.SetDirection(gxui.LeftToRight) - if _, err := exec.LookPath("wine"); err == nil { - wineBut := th.CreateButton() - wineBut.SetType(gxui.ToggleButton) - wineBut.SetChecked(wine) - wineBut.SetText("Show Windows Apps") - wineBut.OnClick(func(gxui.MouseEvent) { - wine = wineBut.IsChecked() - appListAdap.refresh() - if wineBut.IsChecked() { - catListAdap.SetStrings(cats) - wineBut.SetText("Hide Windows Apps") - } else { - catListAdap.SetStrings(lin) - wineBut.SetText("Show Windows Apps") - } - }) - _, err := os.Open("Start.exe") - if err == nil { - pa := th.CreateButton() - pa.SetText("Open PortableApps Launcher") - pa.OnClick(func(gxui.MouseEvent) { - cmd := exec.Command("wine", "Start.exe") - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - cmd.Start() - }) - butBox.AddChild(pa) - } - butBox.AddChild(wineBut) - } - top.AddChild(butBox) - top.AddChild(splBox) - win.AddChild(top) - win.OnClose(dr.Terminate) } diff --git a/update.go b/update.go index ed57ce4..f1c5d60 100644 --- a/update.go +++ b/update.go @@ -69,6 +69,8 @@ func checkForUpdate(new string) (bool, error) { } if newNums[i] > curNums[i] { return true, nil + } else if curNums[i] > newNums[i] { + return false, nil } } return false, nil