' Gambas class file
PUBLIC sBaseDir AS String = "/usr/share/vine-app-install-data/"
PUBLIC sPathLua AS String = "/usr/share/vine-app-install/list-package-info.lua"
PUBLIC sPathTmp AS String = "/tmp/v-a-i." & CStr(Int(Rnd(10000, 99999)))
PUBLIC sIconDir AS String = "/usr/share/icons/gnome/24x24/categories/"
PUBLIC iHeightHBox AS Integer = Desktop.Scale * 5 ' default row height of gridview
PUBLIC cApplications AS NEW Collection ' store application information (multi dimension), = Name
PUBLIC sAppName AS String ' store app name globaly (used for reading apt-cache's output)
PUBLIC idSumm AS Integer = 0 ' : Summary
PUBLIC idDesc AS Integer = 1 ' : Description
PUBLIC idCat AS Integer = 2 ' : Category
PUBLIC idStat AS Integer = 3 ' : State (Installed/NotInstalled)
PUBLIC idCkBox AS Integer = 4 ' : Checkbox State (On / Off)
PUBLIC SUB Form_Open()
'setup left(category) panel
hspMain.Layout = "180," & CStr(hspMain.Width - 180)
AddCategories("All", ("All"), Stock["24/package"])
AddCategories("Accessories", ("Accessories"), Picture[sIconDir & "applications-accessories.png"])
AddCategories("Internet", ("Internet"), Picture[sIconDir & "applications-internet.png"])
AddCategories("Office", ("Office"), Picture[sIconDir & "applications-office.png"])
AddCategories("Graphics", ("Graphics"), Picture[sIconDir & "applications-graphics.png"])
AddCategories("Multimedia", ("Multimedia"), Picture[sIconDir & "applications-multimedia.png"])
AddCategories("Games", ("Games"), Picture[sIconDir & "applications-games.png"])
AddCategories("System", ("System"), Picture[sIconDir & "applications-system.png"])
AddCategories("Development", ("Development"), Picture[sIconDir & "applications-development.png"])
AddCategories("Other", ("Other"), Picture[sIconDir & "applications-other.png"])
AddCategories("Tasks", ("Tasks"), Stock["24/component"])
AddCategories("Restricted", ("Restricted"), Stock["24/lock"])
' start with "All" is selected
lctCategory.Select(lctCategory.Children[0])
FMain.Enabled = FALSE
LoadAppData()
END
PUBLIC SUB Form_Close()
IF Exist(sPathTmp) THEN KILL sPathTmp
END
PUBLIC SUB btnClose_Click()
ME.Close
END
PUBLIC SUB lctApps_MouseDown()
DIM sApp AS String
DIM iSsHeight AS Integer
DIM hPict AS Picture
' return immediately while loading the app list
IF lctApps.Current = NULL THEN RETURN
'make visible and expand the detail pane
IF svwDetail.Visible = FALSE THEN
svwDetail.Visible = TRUE
vspRight.Layout = CStr(vspRight.Height / 2) & "," & CStr(vspRight.Height / 2)
ENDIF
' set icon(large) and description of selected package
sApp = lctApps.Current.Name
tlbAppDesc.Text = "" & sApp & "
"
tlbAppDesc.Text &= cApplications[sApp][idDesc]
IF Exist(sBaseDir &/ cApplications[sApp][idCat] &/ "icons" &/ sApp & ".png") = TRUE THEN
pbxDetail.Picture = Image.Load(sBaseDir &/ cApplications[sApp][idCat] &/ "icons" &/ sApp & ".png").stretch(48, 48).Picture
ELSE
pbxDetail.Picture = Picture["noicon.png"]
ENDIF
' set screenshot if available
IF Exist(sBaseDir &/ cApplications[sApp][idCat] &/ "screenshots" &/ sApp & ".png") = TRUE THEN
hPict = Picture[sBaseDir &/ cApplications[sApp][idCat] &/ "screenshots" &/ sApp & ".png"]
iSsHeight = hPict.Height / hPict.Width * pbxThumb.Width
pbxThumb.Picture = hPict.Image.Stretch(pbxThumb.Width, iSsHeight).Picture
pbxThumb.Mouse = Mouse.Pointing
pbxThumb.Visible = TRUE
ELSE
pbxThumb.Mouse = Mouse.Default
pbxThumb.Visible = FALSE
ENDIF
END
PUBLIC SUB pbxThumb_MouseUp()
DIM sName AS String
sName = lctApps.Current.Name
EXEC ["xdg-open", sBaseDir &/ cApplications[sName][idCat] &/ "screenshots" &/ sName & ".png"]
END
PUBLIC SUB CheckBoxes_Click()
DIM sApp AS String
' ignore useless event call while loading the application data
IF FMain.Enabled = FALSE THEN RETURN
sApp = LAST.Parent.Name
' synchronize checkbox valu and idCkBox value
IF LAST.Value = CheckBox.True THEN
cApplications[sApp][idCkBox] = "On"
ELSE
cApplications[sApp][idCkBox] = "Off"
ENDIF
' change color of selected application
IF LAST.Value = CheckBox.TRUE AND cApplications[sApp][idStat] = "NotInstalled" THEN
LAST.Parent.Children[1].Background = Color.DarkGreen
LAST.Parent.Children[2].Background = Color.DarkGreen
LAST.Parent.Children[3].Background = Color.DarkGreen
LAST.Parent.Children[3].Foreground = Color.White
ELSE IF LAST.Value = CheckBox.False AND cApplications[sApp][idStat] = "Installed" THEN
LAST.Parent.Children[1].Background = Color.Darkred
LAST.Parent.Children[2].Background = Color.Darkred
LAST.Parent.Children[3].Background = Color.Darkred
LAST.Parent.Children[3].Foreground = Color.White
ELSE
LAST.Parent.Children[1].Background = Color.Default
LAST.Parent.Children[2].Background = Color.Default
LAST.Parent.Children[3].Background = Color.Default
LAST.Parent.Children[3].Foreground = Color.Default
ENDIF
END
PUBLIC SUB lctCategory_Click()
FilterLctApps()
END
PUBLIC SUB cbxState_Click()
FilterLctApps()
END
PUBLIC SUB btnSearch_Click()
btnSearch.SetFocus
FilterLctApps()
END
PUBLIC SUB btnApply_Click()
DIM sSelection AS String
DIM hProcess AS Stream
DIM element AS String[]
FOR EACH element IN cApplications
IF element[idCkBox] = "On" AND element[idStat] = "NotInstalled" THEN
sSelection &= cApplications.Key & " " & "install" & "\n"
ELSE IF element[idCkBox] = "Off" AND element[idStat] = "Installed" THEN
sSelection &= cApplications.Key & " " & "delete" & "\n"
ENDIF
NEXT
IF Len(sSelection) > 0 THEN
FMain.Enabled = FALSE
FMain.Mouse = Mouse.Wait
hProcess = EXEC ["synaptic", "--non-interactive", "--hide-main-window", "--set-selections", "<"] FOR WRITE AS "ShellSynaptic"
PRINT #hProcess, sSelection;
CLOSE #hProcess
ELSE
Message.Error(("Nothing marked as install and/or remove"))
ENDIF
END
PUBLIC SUB ShellSynaptic_kill()
LoadAppData()
END
PUBLIC SUB tbxSearch_GotFocus()
IF tbxSearch.Text = ("Enter search term") THEN
tbxSearch.Clear
tbxSearch.Foreground = Color.TextForeground
ELSE
tbxSearch.SelectAll
ENDIF
END
PUBLIC SUB tbxSearch_LostFocus()
IF tbxSearch.Text = "" THEN
tbxSearch.Foreground = Val("&HA0A0A0&")
tbxSearch.Text = ("Enter search term")
ENDIF
END
PUBLIC SUB Form_KeyPress()
' set focus on search field when Ctrl + K pressed
IF Key.Control = TRUE AND Key.Code = Key["K"] THEN tbxSearch.SetFocus
END
PUBLIC SUB tbxSearch_KeyPress()
' press enter key then start serch
IF Key.Code = Key.Return THEN FilterLctApps()
END
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'' procedures and functions (including process event)
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
PUBLIC SUB AddCategories(sName AS String, sText AS String, pIcon AS Picture)
' add set of HBox, PictureBox and TextLabel in list container
DIM hBox AS HBox
DIM hLabel AS Label
DIM hPict AS PictureBox
' create HBox
hBox = NEW HBox(lctCategory)
hBox.Padding = 4
hBox.Spacing = 8
hBox.Height = 32
hBox.Name = sName
' create PictureBox for icon
hPict = NEW PictureBox(hBox)
hPict.Picture = pIcon
hPict.Resize(24, 24)
' create TextLaber for group name
hLabel = NEW Label(hBox)
hLabel.Expand = TRUE
hLabel.Text = sText
END
PUBLIC SUB LoadAppData()
DIM hProcess AS Stream
DIM hFile AS File
DIM sDir AS String
DIM sFile AS String
DIM aFileAndDir AS NEW String[] ' used for sorting
DIM sAppList AS String
DIM i AS Integer
DIM sTmp AS String
' get file name & dirctory and sort them by file name (*not directory name)
FOR EACH sDir IN Dir(sBaseDir, "*", gb.Directory)
FOR EACH sFile IN Dir(sBaseDir &/ sDir, "*", gb.File)
aFileAndDir.Add(sFile & ":" & sDir)
sAppList &= sFile & " "
NEXT
NEXT
aFileAndDir.Sort
' store name & category into collection (also reload it)
IF cApplications.Count > 0 THEN cApplications.Clear
FOR i = 0 TO aFileAndDir.Max
cApplications.Add(["", "", Split(aFileAndDir[i], ":")[1], "", ""], Split(aFileAndDir[i], ":")[0])
NEXT
' extract package info from apt cache and store it to gridview
hFile = OPEN sPathTmp FOR CREATE
PRINT #hFile, sAppList
CLOSE #hFile
' should use file to pass large number of application names (possibly a bug or not?)
hProcess = SHELL "apt-get script " & sPathLua & " < " & sPathTmp FOR INPUT AS "ShellAptScript"
END
PUBLIC SUB ShellAptScript_Read()
DIM sLine AS String
DIM sRpmq AS String
DIM hPict AS Picture
LINE INPUT #LAST, sLine
IF InStr(sLine, ": ") THEN
SELECT CASE Split(sLine, ":")[0]
CASE "Package" ' Name
sLine = Right(sLine, Len(sLine) - 9) ' pacakge name
sAppName = sLine ' hold current app name
CASE "State"
IF Right(sLine, Len(Sline) - 7) = "Installed" THEN
cApplications[sAppName][idCkBox] = "On"
cApplications[sAppName][idStat] = "Installed"
ELSE
cApplications[sAppName][idCkBox] = "Off"
cApplications[sAppName][idStat] = "NotInstalled"
END IF
CASE "Summary"
cApplications[sAppName][idSumm] = Right(sLine, Len(sLine) - 9)
CASE "Description"
END SELECT
ELSE
' assume only description has multi line text
IF sAppName <> "" THEN
cApplications[sAppName][idDesc] &= sLine & "
"
ENDIF
ENDIF
END
PUBLIC SUB ShellAptScript_Kill()
CreateAppList()
FilterLctApps()
FMain.Mouse = Mouse.Default
FMain.Enabled = TRUE
' should set forcus on something to catch key event (as workaround?)
btnClose.SetFocus
END
PUBLIC SUB CreateAppList()
DIM hBox AS HBox
DIM hCheckbox AS CheckBox
DIM hTextLabel AS TextLabel
DIM hPict AS PictureBox
DIM hPanel AS Panel
DIM element AS String[]
DIM i AS Integer
IF lctApps.Count > 0 THEN lctApps.Clear
FOR EACH element IN cApplications
' create HBox
hBox = NEW HBox(lctApps)
hBox.Padding = 1
hBox.Spacing = 0
hBox.Height = iHeightHBox
hBox.Name = cApplications.Key
'create panel (for space adjustment)
hPanel = NEW Panel(hBox)
HPanel.Width = 4
HPanel.Height = iHeightHBox
' create checkbox
hCheckbox = NEW CheckBox(hBox) AS "CheckBoxes"
hCheckbox.Width = 20
hCheckbox.Height = 24
IF element[idStat] = "Installed" THEN
hCheckbox.Value = TRUE
ELSE
hCheckbox.Value = FALSE
ENDIF
' create PictureBox for icon
hPict = NEW PictureBox(hBox)
hPict.Alignment = Align.Center
hPict.Width = 32
hPict.Height = 24
IF Exist(sBaseDir &/ element[idCat] &/ "icons" &/ cApplications.Key & ".png") = TRUE THEN
hPict.Picture = Image.Load(sBaseDir &/ element[idCat] &/ "icons" &/ cApplications.Key & ".png").stretch(24, 24).Picture
ELSE
hPict.Picture = Picture["noicon24.png"]
ENDIF
' create TextLabel for application name
hTextLabel = NEW TextLabel(hBox)
hTextLabel.Expand = TRUE
hTextLabel.Alignment = Align.Normal
hTextLabel.Text = " " & cApplications.Key & "
"
hTextLabel.Text &= " " & element[idSumm]
NEXT
END
PUBLIC SUB FilterLctApps()
DIM i AS Integer
DIM sName AS String
' hide unmatch application with specified category and state
FOR i = 0 TO lctApps.Children.Count - 1
sName = lctApps.Children[i].Name
IF CkCategory(sName) = TRUE AND CkState(sName) = TRUE AND CkSearch(sName) = TRUE THEN
lctApps.Children[i].Height = iHeightHBox
lctApps.Children[i].Visible = TRUE
ELSE
lctApps.Children[i].Height = 0
lctApps.Children[i].Visible = FALSE
ENDIF
NEXT
lctApps.Refresh()
END
FUNCTION CkCategory(sApp AS String) AS Boolean
' return TRUE if an application shold be shown
IF cApplications[sApp][idCat] = lctCategory.Current.Name OR lctCategory.Current.Name = "All" THEN ' show all rows if "All" is selected
RETURN TRUE
ELSE
RETURN FALSE
ENDIF
END
FUNCTION CkState(sApp AS String) AS Boolean
' return TRUE if an application shold be shown
SELECT CASE cbxState.Text
CASE ("Installed")
IF cApplications[sApp][idStat] = "Installed" THEN
RETURN TRUE
ELSE
RETURN FALSE
ENDIF
CASE ("Not installed")
IF cApplications[sApp][idStat] = "NotInstalled" THEN
RETURN TRUE
ELSE
RETURN FALSE
ENDIF
CASE ("Marked changes")
IF cApplications[sApp][idStat] = "Installed" AND cApplications[sApp][idCkBox] = "Off" THEN
RETURN TRUE
ELSE IF cApplications[sApp][idStat] = "NotInstalled" AND cApplications[sApp][idCkBox] = "On" THEN
RETURN TRUE
ELSE
RETURN FALSE
ENDIF
DEFAULT
RETURN TRUE
END SELECT
END
PUBLIC SUB CkSearch(sApp AS String) AS Boolean
' return TRUE if serch term is not specified
IF tbxSearch.Text = "" OR tbxSearch.Text = ("Enter search term") THEN RETURN TRUE
' return TRUE if name , summary or description contains serch term
IF InStr(sApp, tbxSearch.Text, 0, gb.Text) > 0 OR InStr(cApplications[sApp][idSumm], tbxSearch.Text, 0, gb.Text) > 0 OR InStr(cApplications[sApp][idDesc], tbxSearch.Text, 0, gb.Text) > 0 THEN
RETURN TRUE
ELSE
RETURN FALSE
ENDIF
END