Reload
This commit is contained in:
commit
3bde7c3d5f
22
.gitattributes
vendored
Normal file
22
.gitattributes
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
# Auto detect text files and perform LF normalization
|
||||
* text=auto
|
||||
|
||||
# Custom for Visual Studio
|
||||
*.cs diff=csharp
|
||||
*.sln merge=union
|
||||
*.csproj merge=union
|
||||
*.vbproj merge=union
|
||||
*.fsproj merge=union
|
||||
*.dbproj merge=union
|
||||
|
||||
# Standard to msysgit
|
||||
*.doc diff=astextplain
|
||||
*.DOC diff=astextplain
|
||||
*.docx diff=astextplain
|
||||
*.DOCX diff=astextplain
|
||||
*.dot diff=astextplain
|
||||
*.DOT diff=astextplain
|
||||
*.pdf diff=astextplain
|
||||
*.PDF diff=astextplain
|
||||
*.rtf diff=astextplain
|
||||
*.RTF diff=astextplain
|
||||
166
.gitignore
vendored
Normal file
166
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,166 @@
|
|||
*.exe
|
||||
*.org
|
||||
|
||||
#################
|
||||
## Eclipse
|
||||
#################
|
||||
|
||||
*.pydevproject
|
||||
.project
|
||||
.metadata
|
||||
bin/
|
||||
tmp/
|
||||
*.tmp
|
||||
*.bak
|
||||
*.swp
|
||||
*~.nib
|
||||
local.properties
|
||||
.classpath
|
||||
.settings/
|
||||
.loadpath
|
||||
|
||||
# External tool builders
|
||||
.externalToolBuilders/
|
||||
|
||||
# Locally stored "Eclipse launch configurations"
|
||||
*.launch
|
||||
|
||||
# CDT-specific
|
||||
.cproject
|
||||
|
||||
# PDT-specific
|
||||
.buildpath
|
||||
|
||||
|
||||
#################
|
||||
## Visual Studio
|
||||
#################
|
||||
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
*.sln.docstates
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Rr]elease/
|
||||
*_i.c
|
||||
*_p.c
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.vspscc
|
||||
.builds
|
||||
*.dotCover
|
||||
|
||||
## TODO: If you have NuGet Package Restore enabled, uncomment this
|
||||
#packages/
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish
|
||||
|
||||
# Others
|
||||
[Bb]in
|
||||
[Oo]bj
|
||||
sql
|
||||
TestResults
|
||||
*.Cache
|
||||
ClientBin
|
||||
stylecop.*
|
||||
~$*
|
||||
*.dbmdl
|
||||
Generated_Code #added for RIA/Silverlight projects
|
||||
|
||||
# Backup & report files from converting an old project file to a newer
|
||||
# Visual Studio version. Backup files are not needed, because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
|
||||
|
||||
|
||||
############
|
||||
## Windows
|
||||
############
|
||||
|
||||
# Windows image file caches
|
||||
Thumbs.db
|
||||
|
||||
# Folder config file
|
||||
Desktop.ini
|
||||
|
||||
|
||||
#############
|
||||
## Python
|
||||
#############
|
||||
|
||||
*.py[co]
|
||||
|
||||
# Packages
|
||||
*.egg
|
||||
*.egg-info
|
||||
dist
|
||||
build
|
||||
eggs
|
||||
parts
|
||||
bin
|
||||
var
|
||||
sdist
|
||||
develop-eggs
|
||||
.installed.cfg
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
.coverage
|
||||
.tox
|
||||
|
||||
#Translations
|
||||
*.mo
|
||||
|
||||
#Mr Developer
|
||||
.mr.developer.cfg
|
||||
|
||||
# Mac crap
|
||||
.DS_Store
|
||||
61
About.ahk
Normal file
61
About.ahk
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
About:
|
||||
; Cursor change for about box links:
|
||||
; Load the cursor and start the hook:
|
||||
hCurs:=DllCall("LoadCursor","UInt",NULL,"Int",32649,"UInt") ;IDC_HAND
|
||||
OnMessage(0x200,"WM_MOUSEMOVE")
|
||||
|
||||
GuiChildInit("AboutBox")
|
||||
ABw = 250
|
||||
ABh = 150
|
||||
ABx := CenterX(ABw)
|
||||
ABy := CenterY(ABh)
|
||||
|
||||
DevEmail := "JJPujara@gmail.com"
|
||||
SiteUrl := "http://www.reddit.com/r/LifeRPG/"
|
||||
|
||||
Gui, AboutBox:Add, Picture, w32 h-1, res/WP_RPG_VG.ico
|
||||
|
||||
Gui, AboutBox:Font, bold
|
||||
Gui, AboutBox:Add, Text, x+10, LifeRPG r2
|
||||
Gui, AboutBox:Font
|
||||
|
||||
Gui, AboutBox:Add, Text, y+1, by Jayvant Javier Pujara
|
||||
Gui, AboutBox:Font, cBlue
|
||||
Gui, AboutBox:Add, Text, y+1 gAboutLinkEmail vAboutLinkEmail, %DevEmail%
|
||||
Gui, AboutBox:Font
|
||||
|
||||
Gui, AboutBox:Add, Text, xm y+10, For help and discussion,`nvisit the LifeRPG community on reddit:
|
||||
Gui, AboutBox:Font, cBlue
|
||||
Gui, AboutBox:Add, Text, y+1 gAboutLinkSite, %SiteUrl%
|
||||
Gui, AboutBox:Font,
|
||||
|
||||
Gui, AboutBox:Add, Button, y+15 w80 Default gAboutBoxGuiClose, OK
|
||||
Gui, AboutBox:Show, w%ABw% h%ABh% x%ABx% y%ABy%, About
|
||||
return
|
||||
|
||||
AboutLinkEmail:
|
||||
Run, mailto:%DevEmail%
|
||||
return
|
||||
|
||||
AboutLinkSite:
|
||||
Run, %SiteUrl%
|
||||
return
|
||||
|
||||
AboutBoxGuiClose:
|
||||
AboutBoxGuiEscape:
|
||||
; Disable the hook and destroy the cursor:
|
||||
OnMessage(0x200,"")
|
||||
DllCall("DestroyCursor","Uint",hCurs)
|
||||
GuiChildClose("AboutBox")
|
||||
return
|
||||
|
||||
; Cursor hook:
|
||||
WM_MOUSEMOVE(wParam,lParam)
|
||||
{
|
||||
Global hCurs, AboutLinkEmail
|
||||
MouseGetPos,,,,ctrl
|
||||
; Only change over certain controls, use Windows Spy to find them.
|
||||
If ctrl in Static4,Static6
|
||||
DllCall("SetCursor","UInt",hCurs)
|
||||
Return
|
||||
}
|
||||
166
Data/.gitignore
vendored
Normal file
166
Data/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,166 @@
|
|||
*.db
|
||||
*.ini
|
||||
|
||||
#################
|
||||
## Eclipse
|
||||
#################
|
||||
|
||||
*.pydevproject
|
||||
.project
|
||||
.metadata
|
||||
bin/
|
||||
tmp/
|
||||
*.tmp
|
||||
*.bak
|
||||
*.swp
|
||||
*~.nib
|
||||
local.properties
|
||||
.classpath
|
||||
.settings/
|
||||
.loadpath
|
||||
|
||||
# External tool builders
|
||||
.externalToolBuilders/
|
||||
|
||||
# Locally stored "Eclipse launch configurations"
|
||||
*.launch
|
||||
|
||||
# CDT-specific
|
||||
.cproject
|
||||
|
||||
# PDT-specific
|
||||
.buildpath
|
||||
|
||||
|
||||
#################
|
||||
## Visual Studio
|
||||
#################
|
||||
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
*.sln.docstates
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Rr]elease/
|
||||
*_i.c
|
||||
*_p.c
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.vspscc
|
||||
.builds
|
||||
*.dotCover
|
||||
|
||||
## TODO: If you have NuGet Package Restore enabled, uncomment this
|
||||
#packages/
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish
|
||||
|
||||
# Others
|
||||
[Bb]in
|
||||
[Oo]bj
|
||||
sql
|
||||
TestResults
|
||||
*.Cache
|
||||
ClientBin
|
||||
stylecop.*
|
||||
~$*
|
||||
*.dbmdl
|
||||
Generated_Code #added for RIA/Silverlight projects
|
||||
|
||||
# Backup & report files from converting an old project file to a newer
|
||||
# Visual Studio version. Backup files are not needed, because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
|
||||
|
||||
|
||||
############
|
||||
## Windows
|
||||
############
|
||||
|
||||
# Windows image file caches
|
||||
Thumbs.db
|
||||
|
||||
# Folder config file
|
||||
Desktop.ini
|
||||
|
||||
|
||||
#############
|
||||
## Python
|
||||
#############
|
||||
|
||||
*.py[co]
|
||||
|
||||
# Packages
|
||||
*.egg
|
||||
*.egg-info
|
||||
dist
|
||||
build
|
||||
eggs
|
||||
parts
|
||||
bin
|
||||
var
|
||||
sdist
|
||||
develop-eggs
|
||||
.installed.cfg
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
.coverage
|
||||
.tox
|
||||
|
||||
#Translations
|
||||
*.mo
|
||||
|
||||
#Mr Developer
|
||||
.mr.developer.cfg
|
||||
|
||||
# Mac crap
|
||||
.DS_Store
|
||||
BIN
Electrolize-Regular.ttf
Normal file
BIN
Electrolize-Regular.ttf
Normal file
Binary file not shown.
117
FileManage.ahk
Normal file
117
FileManage.ahk
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
; Database Open/Select: =====================================================
|
||||
FileOpen:
|
||||
Gui, +OwnDialogs
|
||||
FileSelectFile, NewDB, , data, Open a projects database, LifeRPG Database (*.db)
|
||||
if (NewDB <> "")
|
||||
{
|
||||
if (IsObject(db))
|
||||
{
|
||||
OldDB := db
|
||||
OldDB.Close()
|
||||
}
|
||||
; Set the db var to the new database:
|
||||
db := DBA.DataBaseFactory.OpenDataBase("SQLite", NewDB)
|
||||
|
||||
; Check to see if database is old and needs to be updated:
|
||||
if (ProfileGet("release") = "")
|
||||
{
|
||||
MsgBox Updating Database
|
||||
; Add columns to projects table:
|
||||
ProjectsNewCols := {"dateDone":"NUMERIC", "dateEntered":"NUMERIC", "skill":"TEXT", "levelDone":"NUMERIC"}
|
||||
for col, type in ProjectsNewCols
|
||||
{
|
||||
db.Query("ALTER TABLE projects ADD " . col . " " . type)
|
||||
}
|
||||
|
||||
; Create inventory table:
|
||||
CreateInventory := "CREATE TABLE inventory ( id INTEGER PRIMARY KEY, item TEXT, description TEXT, value NUMERIC, date NUMERIC, category TEXT )"
|
||||
db.Query(CreateInventory)
|
||||
|
||||
; Create finances table:
|
||||
CreateFinances := "CREATE TABLE finances ( date NUMERIC, id INTEGER PRIMARY KEY, description TEXT, amount NUMERIC, category TEXT )"
|
||||
db.Query(CreateFinances)
|
||||
|
||||
; Create profile table and fill in settings:
|
||||
; points: 0
|
||||
; threshold: 100
|
||||
; name:
|
||||
; momentum: 100
|
||||
; MMTLastUpdate: Right now
|
||||
; title:
|
||||
; release: 2
|
||||
CreateProfile := "CREATE TABLE profile ( setting TEXT, value TEXT )"
|
||||
db.Query(CreateProfile)
|
||||
ProfileSettings := {"points": 0, "threshold": 100, "name":"Edit Profile", "momentum": 100, "MMTLastUpdate": FormatTime(,"yyyyMMdd"), "title":"", "release":2}
|
||||
for setting, value in ProfileSettings
|
||||
{
|
||||
ProfileRecord := {}
|
||||
ProfileRecord.Setting := setting
|
||||
ProfileRecord.value := value
|
||||
db.Insert(ProfileRecord, "profile")
|
||||
}
|
||||
}
|
||||
|
||||
; Update GUI controls to display new database data (HUD and main projects ListView)
|
||||
FileOpenGUI_Refresh()
|
||||
}
|
||||
return
|
||||
|
||||
FileNew:
|
||||
Gui, +OwnDialogs
|
||||
; Present dialog to set database file name
|
||||
FileSelectFile, NewDB_Path, S24, New LifeRPG.db, New projects database, LifeRPG Database (*.db)
|
||||
if (NewDB_Path <> "")
|
||||
{
|
||||
; Get the desired filename:
|
||||
SplitPath, NewDB_Path, NewDB_Name, NewDB_Dir, NewDB_Ext
|
||||
|
||||
; Refresh everything needed to "load" database, set as default, add to recents menu
|
||||
if (NewDB_Ext = "")
|
||||
{
|
||||
NewDB_Name .= ".db"
|
||||
NewDB_Path .= ".db"
|
||||
}
|
||||
|
||||
NewDB := NewDB_Path
|
||||
|
||||
if (IsObject(db))
|
||||
{
|
||||
OldDB := db
|
||||
OldDB.Close()
|
||||
}
|
||||
|
||||
if (FileExist(NewDB_Path))
|
||||
FileDelete, %NewDB_Path%
|
||||
; Copy blank database to selected location and rename to desired name:
|
||||
FileCopy, Res\Blank.db, %NewDB_Path%
|
||||
|
||||
; Point the db var to the new database:
|
||||
db := DBA.DataBaseFactory.OpenDataBase("SQLite", NewDB)
|
||||
|
||||
; Update GUI controls to display new database data (HUD and main projects ListView)
|
||||
FileOpenGUI_Refresh()
|
||||
}
|
||||
return
|
||||
|
||||
FileOpenGUI_Refresh()
|
||||
{
|
||||
global
|
||||
if (OldDB)
|
||||
{
|
||||
gosub ClearSearch
|
||||
MomentumLastUpdate := ProfileGet("MMTLastUpdate")
|
||||
HUD_Refresh()
|
||||
}
|
||||
SettingSet("File", "LastOpened", NewDB) ; Update settings file to point to new "current" database:
|
||||
}
|
||||
|
||||
SettingSet(Section, Key, Value)
|
||||
{
|
||||
IniWrite, %Value%, data/Settings.ini, %Section%, %Key%
|
||||
}
|
||||
|
||||
SettingGet(Section, Key)
|
||||
{
|
||||
IniRead, Setting, data/Settings.ini, %Section%, %Key%
|
||||
return Setting
|
||||
}
|
||||
382
Functions.ahk
Normal file
382
Functions.ahk
Normal file
|
|
@ -0,0 +1,382 @@
|
|||
;~ ===============================================================================
|
||||
;~ Useful Functions:
|
||||
|
||||
; Stops user from being able to resize the listView columns on the main window:
|
||||
;~ OnMessage(0x4E,"WM_NOTIFY")
|
||||
;~ WM_NOTIFY(wParam, lParam, msg, hwnd)
|
||||
;~ { Critical
|
||||
;~ Static HDN_BEGINTRACKA = -306, HDN_BEGINTRACKW = -326
|
||||
;~ Code := -(~NumGet(lParam+0, 8))-1
|
||||
;~ Return, Code = HDN_BEGINTRACKA || Code = HDN_BEGINTRACKW ? True : ""
|
||||
;~ }
|
||||
|
||||
|
||||
|
||||
; Colored Listview rows and text
|
||||
|
||||
; OnMessage( WM_NOTIFY := 0x4E, "WM_NOTIFY" ) ; this line must be executed for the function to work
|
||||
|
||||
WM_NOTIFY( wparam, lparam, msg, hwnd ) {
|
||||
Static psz, pty, lvitem, itext, offset_code, offset_row, offset_color, LVM_GETITEMTEXT
|
||||
|
||||
; Up to 4 istviews can be colored at a time. Remeber to forcibly redraw them if more than one is
|
||||
; fully drawn at once.
|
||||
Global Colored_LV_1, Colored_LV_2, Colored_LV_3, Colored_LV_4
|
||||
, Colored_LV_1_BG, Colored_LV_2_BG, Colored_LV_3_BG, Colored_LV_4_BG
|
||||
, Colored_LV_1_TX, Colored_LV_2_TX, Colored_LV_3_TX, Colored_LV_4_TX
|
||||
|
||||
Critical
|
||||
|
||||
If !( psz )
|
||||
{
|
||||
; Prep the static vars on first run, including LVITEM for getting the color values from the listview.
|
||||
LVM_GETITEMTEXT := 0x1000 + ( A_IsUnicode ? 115 : 45 )
|
||||
psz := A_PtrSize ? A_PtrSize : 4
|
||||
pty := A_PtrSize = 8 ? "UPtr" : "UInt"
|
||||
offset_code := 2 * psz
|
||||
offset_row := 3 * psz + 24
|
||||
offset_color := 5 * psz + 28
|
||||
VarSetCapacity( lvitem, 52 + 2 * psz, 0 )
|
||||
VarSetCapacity( itext, 250 << !! A_IsUnicode, 0 )
|
||||
NumPut( 1, lvitem, 0, "UInt" )
|
||||
NumPut( &itext, lvitem, 20, pty )
|
||||
NumPut( 250, lvitem, 20 + psz, "UInt" )
|
||||
}
|
||||
|
||||
; Get the HWND of the controls sending this notification and see if it's one of our listviews
|
||||
ct_hwnd := NumGet( lparam + 0, 0, pty )
|
||||
If ( ( ct_hwnd = Colored_LV_1 && which_lv := "1" ) || ( ct_hwnd = Colored_LV_2 && which_lv := "2" )
|
||||
|| ( ct_hwnd = Colored_LV_3 && which_lv := "3" ) || ( ct_hwnd = Colored_LV_4 && which_lv := "4" ) )
|
||||
&& ( -12 = NumGet( lparam + 0, offset_code, "Int" ) ) ; NM_CUSTOMDRAW = -12
|
||||
If ( 1 = draw_stage := NumGet( lparam + 0, offset_code + 4, "Int" ) ) ; CDDS_PREPAINT = 1
|
||||
Return 0x20 ; CDRF_NOTIFYITEMDRAW = 0x20
|
||||
Else If ( draw_stage = 0x10001 ) ; CDDS_PREPAINT = 0x1, CDDS_ITEM = 0x10001
|
||||
{
|
||||
; Now we know the notification is for an item prepaint, so we can adjust the text and bg colors.
|
||||
; The colors are kept in the listview itself
|
||||
item := NumGet( lparam + 0, offset_row, "UInt" )
|
||||
If ( 0 < 0 | Colored_LV_%which_lv%_TX )
|
||||
{
|
||||
NumPut( Colored_LV_%which_lv%_TX - 1, lvitem, 8, "UInt" )
|
||||
SendMessage, LVM_GETITEMTEXT, item, &lvitem,, % "AHK_ID " ct_hwnd
|
||||
VarSetCapacity( itext, -1 )
|
||||
NumPut( Round( itext ), lparam + 0, offset_color, "UInt" )
|
||||
}
|
||||
If ( 0 < 0 | Colored_LV_%which_lv%_BG )
|
||||
{
|
||||
NumPut( Colored_LV_%which_lv%_BG - 1, lvitem, 8, "UInt" )
|
||||
SendMessage, LVM_GETITEMTEXT, item, &lvitem,, % "AHK_ID " ct_hwnd
|
||||
VarSetCapacity( itext, -1 )
|
||||
NumPut( Round( itext ), lparam + 0, offset_color + 4, "UInt" )
|
||||
}
|
||||
}
|
||||
; Else If ( draw_stage = 0x10002 ) ; CDDS_POSTPAINT = 0x2, CDDS_ITEM = 0x10001
|
||||
; {
|
||||
; ; Put here drawing to do after the item is drawn. E.g: draw custom grid lines.
|
||||
; }
|
||||
Static HDN_BEGINTRACKA = -306, HDN_BEGINTRACKW = -326
|
||||
Code := -(~NumGet(lParam+0, 8))-1
|
||||
Return, Code = HDN_BEGINTRACKA || Code = HDN_BEGINTRACKW ? True : ""
|
||||
}
|
||||
|
||||
ProfileSet(setting, value)
|
||||
{
|
||||
global db
|
||||
s := db.Query("UPDATE profile SET value = '" . SafeQuote(value) . "' WHERE setting = '" . setting . "'")
|
||||
return s
|
||||
}
|
||||
|
||||
FormatTime(Time="", Format="")
|
||||
{
|
||||
FormatTime, Out, %Time%, %Format%
|
||||
return Out
|
||||
}
|
||||
|
||||
ProfileGet(setting)
|
||||
{
|
||||
global db
|
||||
ProfileSet := db.OpenRecordSet("SELECT value FROM profile WHERE setting = '" . setting . "'")
|
||||
while (!ProfileSet.EOF)
|
||||
{
|
||||
Value := ProfileSet["value"]
|
||||
ProfileSet.MoveNext()
|
||||
}
|
||||
ProfileSet.Close()
|
||||
return Value
|
||||
}
|
||||
|
||||
Uppercase(String)
|
||||
{
|
||||
StringUpper, String, String
|
||||
return String
|
||||
}
|
||||
|
||||
Capitalize(String)
|
||||
{
|
||||
StringUpper, String, String, T
|
||||
return String
|
||||
}
|
||||
|
||||
; Call to refresh skills list after adding a new skill:
|
||||
RefreshSkillsList(SkillChosen="All")
|
||||
{
|
||||
global
|
||||
if (SkillChosen = "All" || SkillChosen = "")
|
||||
{
|
||||
GuiControl, , FilterSkill, |All||None|
|
||||
GuiControl, , FilterSkill, % ListSkills()
|
||||
}
|
||||
else if (SkillChosen = "None")
|
||||
{
|
||||
GuiControl, , FilterSkill, |All|None||
|
||||
GuiControl, , FilterSkill, % ListSkills()
|
||||
}
|
||||
else
|
||||
{
|
||||
PickSkill := ListSkills()
|
||||
if (InStr(PickSkill, SkillChosen))
|
||||
{
|
||||
GuiControl, , FilterSkill, |All|None|
|
||||
StringReplace, PickedSkill, PickSkill, %SkillChosen%, %SkillChosen%|
|
||||
GuiControl, , FilterSkill, % PickedSkill
|
||||
}
|
||||
else
|
||||
{
|
||||
GuiControl, , FilterSkill, |All||None|
|
||||
GuiControl, , FilterSkill, % ListSkills()
|
||||
}
|
||||
}
|
||||
GuiControlGet, FilterSkillSelected, , FilterSkill
|
||||
}
|
||||
|
||||
|
||||
ListSkills(Selected="")
|
||||
{
|
||||
global db
|
||||
SkillList := Object()
|
||||
Skills := db.OpenRecordSet("SELECT DISTINCT skill FROM projects ORDER BY skill")
|
||||
while(!Skills.EOF)
|
||||
{
|
||||
Skill := Skills["skill"]
|
||||
If (Skill <> "")
|
||||
SkillList.Insert(Skill)
|
||||
Skills.MoveNext()
|
||||
}
|
||||
Skills.Close()
|
||||
SkillComboList =
|
||||
For Num, Skill in SkillList
|
||||
{
|
||||
SkillComboList .= Skill . "|"
|
||||
if (Selected and Skill = Selected)
|
||||
SkillComboList .= "|"
|
||||
}
|
||||
return SkillComboList
|
||||
}
|
||||
|
||||
ListDifficulties(SetDifficulty="")
|
||||
{
|
||||
global Difficulties
|
||||
For k, diff in Difficulties
|
||||
{
|
||||
if (diff = SetDifficulty)
|
||||
diff := diff . "|"
|
||||
else if (k = 1)
|
||||
diff := diff . "|"
|
||||
DifficultyList .= diff . "|"
|
||||
}
|
||||
return DifficultyList
|
||||
}
|
||||
|
||||
ListPriorities(SetPriority="")
|
||||
{
|
||||
global Priorities
|
||||
For k, imp in Priorities
|
||||
{
|
||||
if (imp = SetPriority)
|
||||
imp := imp . "|"
|
||||
else if (k = 1 && SetPriority <> "All")
|
||||
imp := imp . "|"
|
||||
PriorityList .= imp . "|"
|
||||
}
|
||||
return PriorityList
|
||||
}
|
||||
|
||||
UpdateList(NextSelection="", ImportanceSelected="All", Skill="All")
|
||||
{
|
||||
global
|
||||
IDCol = 1
|
||||
DifficultyCol = 2
|
||||
ImportanceCol = 4
|
||||
ParentCol = 5
|
||||
Critical
|
||||
Gui, 1:Default
|
||||
GuiControlGet, SearchString, , SearchQuery
|
||||
GuiControl, -ReDraw, MainList
|
||||
LV_Delete()
|
||||
Filter=
|
||||
if (ImportanceSelected <> "" || FilterShowDone <> "" || Skill <> "" || SearchString <> "")
|
||||
Filter .= "WHERE "
|
||||
if (SearchString <> "")
|
||||
Filter .= "project LIKE '%" SafeQuote(SearchString) "%' AND"
|
||||
if (FilterShowDone <> 1)
|
||||
Filter .= " difficulty <> 'Done' "
|
||||
else if (FilterShowDone = 1)
|
||||
Filter .= " difficulty = 'Done' "
|
||||
if (ImportanceSelected <> "All")
|
||||
Filter .= " AND importance = '" SafeQuote(ImportanceSelected) "' "
|
||||
if (Skill = "None")
|
||||
filter .= " AND skill = '' "
|
||||
else if (Skill <> "All")
|
||||
Filter .= " AND skill = '" SafeQuote(Skill) "' "
|
||||
|
||||
;Notification("","Select * from projects " . Filter)
|
||||
|
||||
Projects := db.OpenRecordSet("Select * from projects " . Filter)
|
||||
while (!Projects.EOF)
|
||||
{
|
||||
ID := Projects["id"]
|
||||
Difficulty := Projects["difficulty"]
|
||||
Project := Projects["project"]
|
||||
Parent := Projects["parent"]
|
||||
Importance := Projects["importance"]
|
||||
for k, v in Priorities
|
||||
{
|
||||
If (Importance = v)
|
||||
Importance := k ". " v
|
||||
}
|
||||
If (Importance = "")
|
||||
Importance := "None"
|
||||
LV_Add("", ID,Difficulty,Project,Importance,Parent)
|
||||
Projects.MoveNext()
|
||||
}
|
||||
Projects.Close()
|
||||
GuiControl, -ReDraw, MainList
|
||||
LV_ModifyCol(1, "Integer sortdesc") ; Enable this to sort by ID, which could show most recent or oldest first, depending.
|
||||
LV_ModifyCol(ImportanceCol, "sort") ; First sort by importance
|
||||
LV_ModifyCol(DifficultyCol, "sortdesc") ; Then sort by difficulty, descending. Just so happens my scheme sorts alright on its own, what luck.
|
||||
|
||||
If (NextSelection)
|
||||
LV_Modify(NextSelection, "Focus Select Vis")
|
||||
Times := LV_GetCount()
|
||||
Loop % Times
|
||||
{
|
||||
ThisLine := A_Index
|
||||
LV_GetText(Text, ThisLine, ImportanceCol)
|
||||
for k, v in Priorities ; Remove those numbers added to the priorities to allow for proper sorting
|
||||
{
|
||||
P := k ". " v
|
||||
if (Text = P)
|
||||
{
|
||||
LV_Modify(ThisLine,"Col" . ImportanceCol,v)
|
||||
}
|
||||
}
|
||||
|
||||
LV_GetText(ParentID, ThisLine, ParentCol)
|
||||
|
||||
GetParent := db.OpenRecordSet("SELECT project FROM projects WHERE id = " ParentID)
|
||||
while (!GetParent.EOF)
|
||||
{
|
||||
ParentName := GetParent["project"]
|
||||
GetParent.MoveNext()
|
||||
}
|
||||
GetParent.Close()
|
||||
LV_Modify(ThisLine, "Col" . ParentCol,ParentName)
|
||||
}
|
||||
LV_ModifyCol()
|
||||
Loop % LV_GetCount("Col")
|
||||
LV_ModifyCol(A_Index,"AutoHdr")
|
||||
LV_ModifyCol(IDCol, 0) ; Hide ID column
|
||||
|
||||
Loop % LV_GetCount()
|
||||
{
|
||||
RowNum := A_Index
|
||||
LV_GetText(RowDiff, RowNum, 2)
|
||||
for kDiff, vDiff in Difficulties
|
||||
{
|
||||
for kCol, vCol in Colors
|
||||
{
|
||||
if (RowDiff = vDiff)
|
||||
{
|
||||
if (kDiff = kCol)
|
||||
LV_Modify(RowNum, "Col6", vCol)
|
||||
}
|
||||
else if (RowDiff = "Done")
|
||||
LV_Modify(RowNum, "Col6", BGR("F5FFFA"))
|
||||
}
|
||||
}
|
||||
}
|
||||
OnMessage( WM_NOTIFY := 0x4E, "WM_NOTIFY" )
|
||||
LV_ModifyCol(6, 0) ; Hide Color column
|
||||
GuiControl, +ReDraw, MainList
|
||||
return
|
||||
}
|
||||
|
||||
GetParentName()
|
||||
{
|
||||
global
|
||||
Times := LV_GetCount()
|
||||
Loop % Times
|
||||
{
|
||||
ThisLine := A_Index
|
||||
LV_GetText(ParentID, ThisLine, ParentCol)
|
||||
|
||||
GetParent := db.OpenRecordSet("SELECT project FROM projects WHERE id = " ParentID)
|
||||
while (!GetParent.EOF)
|
||||
{
|
||||
ParentName := GetParent["project"]
|
||||
GetParent.MoveNext()
|
||||
}
|
||||
GetParent.Close()
|
||||
LV_Modify(ThisLine, "Col" . ParentCol,ParentName)
|
||||
}
|
||||
}
|
||||
|
||||
SafeQuote(string) ; Escape single quotes for sql update. Insert doesn't seem to need it because the DB library handles it.
|
||||
{
|
||||
StringReplace, string, string, ','', All
|
||||
return string
|
||||
}
|
||||
|
||||
CenterX(w)
|
||||
{
|
||||
global WindowFind
|
||||
WinGetPos,Fx,Fy,Fw,Fh,A
|
||||
return Fx + Round(Fw/2) - Round(w/2)
|
||||
}
|
||||
|
||||
CenterY(h)
|
||||
{
|
||||
global WindowFind
|
||||
WinGetPos,Fx,Fy,Fw,Fh,A
|
||||
return Fy + Round(Fh/2) - Round(h/2)
|
||||
}
|
||||
|
||||
GuiMsgBox(Name, Title, Text, w=170, h=60)
|
||||
{
|
||||
GuiChildInit(Name)
|
||||
Gui, %Name%:Add, Text, w%w% Center, %Text%
|
||||
Gui, %Name%:Add, Button, % "Default g" Name "Yes w40 x" Round((w-80)/2), &Yes
|
||||
Gui, %Name%:Add, Button, Default x+1 g%Name%No w40, &No
|
||||
MX := CenterX(w)
|
||||
MY := CenterY(h)
|
||||
Gui, %Name%:Show, w%w% h%h% x%mx% y%my%, %Title%
|
||||
Gui, %Name%:-MinimizeBox -MaximizeBox
|
||||
return
|
||||
}
|
||||
|
||||
GuiChildInit(Child, Parent=1)
|
||||
{
|
||||
Gui, %Child%:New
|
||||
Gui, %Child%:+Owner%Parent%
|
||||
Gui, %Parent%:+Disabled
|
||||
Gui, %Child%:Default
|
||||
return
|
||||
}
|
||||
|
||||
GuiChildClose(Child, Parent=1)
|
||||
{
|
||||
Gui, %Parent%:-Disabled
|
||||
Gui, %Child%:Cancel
|
||||
Gui, %Parent%:Default
|
||||
return
|
||||
}
|
||||
343
HUD.ahk
Normal file
343
HUD.ahk
Normal file
|
|
@ -0,0 +1,343 @@
|
|||
;~ ===============================================================================
|
||||
; HUD and functions:
|
||||
|
||||
HUD_Color = 15384E
|
||||
HUD_Trans = 200
|
||||
HUD_Color2 = 48B1DF
|
||||
|
||||
; Create a new independent Guis for the HUD
|
||||
|
||||
; Level Module:
|
||||
LevelX = 80
|
||||
LevelY = 45
|
||||
LevelW = 450
|
||||
LevelH = 80
|
||||
Gui, HUD_Level:New
|
||||
Gui, HUD_Level:+LastFound +AlwaysOnTop -Caption +ToolWindow
|
||||
Gui, HUD_Level:Color, %HUD_Color%
|
||||
;Gui, HUD_Level:Add, Picture, x0 y0 w400 h70 , Res\BG.png
|
||||
Gui, HUD_Level:Font, S14 Q5 bold, Electrolize
|
||||
Gui, HUD_Level:Add, Progress, vHUD_Progress x12 y12 w425 h18 cWhite Background48B1DF
|
||||
NameSize = 260
|
||||
Gui, HUD_Level:Add, Text, vHUD_Name x12 y+1 w%NameSize% r1 c%HUD_Color2% BackgroundTrans, % ProfileGet("name")
|
||||
Gui, HUD_Level:Font, s10
|
||||
PointsSize := 424 - NameSize
|
||||
Gui, HUD_Level:Add, Text, vHUD_Points x+1 w%PointsSize% Right cWhite BackgroundTrans,
|
||||
Gui, HUD_Level:Font, s14
|
||||
Gui, HUD_Level:Add, Text, vHUD_Text x12 y+7 w425 cWhite BackgroundTrans ; Shows current level and temporarily shows new XP awards.
|
||||
HUD_LevelText := "LEVEL "
|
||||
HUD_LevelTitle :=
|
||||
;Gui, HUD_Level:Color, 15384E
|
||||
WinSet, Transparent, %HUD_Trans%
|
||||
Winset, ExStyle, +0x20
|
||||
Gui, HUD_Level:Show, x%LevelX% y%LevelY% w%LevelW% h%LevelH% NoActivate
|
||||
Gui, HUD_Level:Hide
|
||||
|
||||
; Momentum Module:
|
||||
Gui, HUD_Momentum:New
|
||||
Gui, HUD_Momentum:+LastFound +AlwaysOnTop -Caption +ToolWindow
|
||||
Gui, HUD_Momentum:Color, %HUD_Color%
|
||||
Gui, HUD_Momentum:Font, S14 Q5 bold, Electrolize
|
||||
Gui, HUD_Momentum:Add, Text, x9 y4 cWhite BackgroundTrans, MMT
|
||||
MMTStart := ProfileGet("momentum")
|
||||
Gui, HUD_Momentum:Add, Progress, vHUD_MomentumBar x+5 y8 w325 h13 cRed Background48B1DF, % MMTStart
|
||||
Gui, HUD_Momentum:Add, Text, vHUD_MomentumPerc x388 y4 w59 cWhite BackgroundTrans Center, % MMTStart . "%"
|
||||
WinSet, Transparent, %HUD_Trans%
|
||||
Winset, ExStyle, +0x20
|
||||
Gui, HUD_Momentum:Show, x80 y135 w450 h30 NoActivate
|
||||
Gui, HUD_Momentum:Hide
|
||||
|
||||
HUD_Refresh()
|
||||
{
|
||||
global
|
||||
; HUD Update:
|
||||
; name
|
||||
; level + title
|
||||
; points/threshold
|
||||
; momentum bar
|
||||
; progress bar!
|
||||
GuiControl, HUD_Level:, HUD_Progress, % ProgressGet()
|
||||
GuiControl, HUD_Level:, HUD_Name, % ProfileGet("name")
|
||||
GuiControl, HUD_Level:, HUD_Text, % HUD_LevelText . LevelCheck() . " " . ProfileGet("title")
|
||||
GuiControl, HUD_Level:, HUD_Points, % PointsCheck() . "/" . ThreshCheck()
|
||||
MMTNow := ProfileGet("momentum")
|
||||
GuiControl, HUD_Momentum:, HUD_MomentumBar, % MMTNow
|
||||
GuiControl, HUD_Momentum:, HUD_MomentumPerc, % MMTNow . "%"
|
||||
}
|
||||
|
||||
|
||||
HUD_MouseOverHide(ByRef hX, ByRef hY, ByRef hW, ByRef hH)
|
||||
{
|
||||
global HUD_Trans
|
||||
SetTimer, Mouse, 100
|
||||
|
||||
Mouse:
|
||||
CoordMode, Mouse, Screen
|
||||
MouseGetPos, x, y
|
||||
|
||||
;ToolTip, %GuiX% (%GuiW% + %GuiX%) `n %x% %y%
|
||||
; if the mouse (x) is located horizontally in a greater position than the hud's X starting position
|
||||
; and less than that x position plus the HUD's width
|
||||
; and vertically (y) greater than the HUD's y position
|
||||
; and lower than that y pos plus the HUD's height
|
||||
; then hide the HUD.
|
||||
if (((x >= hX && x <= (hX+hW))) && ((y >= hY) && (y <= (165)))) ; 80-530; 45-125 ; hY+hH+
|
||||
{
|
||||
Gui, HUD_Level:+LastFound
|
||||
WinSet, Transparent, 0
|
||||
WinSet, ExStyle, +0x20
|
||||
|
||||
Gui, HUD_Momentum:+LastFound
|
||||
WinSet, Transparent, 0
|
||||
WinSet, ExStyle, +0x20
|
||||
}
|
||||
else
|
||||
{
|
||||
Gui, HUD_Level:+LastFound
|
||||
WinSet, Transparent, %HUD_Trans%
|
||||
WinSet, AlwaysOnTop, On
|
||||
|
||||
Gui, HUD_Momentum:+LastFound
|
||||
WinSet, Transparent, %HUD_Trans%
|
||||
WinSet, AlwaysOnTop, On
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
HUD_Progress(PreviousLevelPoints="toggle",PreviousLevel="")
|
||||
{
|
||||
global
|
||||
split = 0
|
||||
;SetTimer, DestProg, Off
|
||||
SetTimer, ClearAwardText, off
|
||||
SetTimer, HideAgain, off
|
||||
static VisibState = 0
|
||||
Gui, HUD_Level:Default
|
||||
if (VisibState = 1) ; HUD is visible
|
||||
{
|
||||
if (PreviousLevelPoints = "toggle") ; toggle called, so hide HUD and return
|
||||
{
|
||||
Gui, HUD_Level:Hide
|
||||
Gui, HUD_Momentum:Hide
|
||||
VisibState = 0 ; HUD now hidden
|
||||
}
|
||||
else ; update progress bar and then clear award text from control after a few seconds.
|
||||
{
|
||||
HUD_Update(PreviousLevelPoints, PreviousLevel)
|
||||
SetTimer, ClearAwardText, 2000
|
||||
return
|
||||
|
||||
ClearAwardText:
|
||||
Critical
|
||||
Gui, HUD_Level:Default
|
||||
GuiControl, , HUD_Text, % HUD_LevelText . LevelCheck() . " " . ProfileGet("title")
|
||||
SetTimer, ClearAwardText, off
|
||||
return
|
||||
}
|
||||
}
|
||||
else if (VisibState = 0) ; HUD is not visible
|
||||
{
|
||||
if (PreviousLevelPoints = "toggle") ; toggle called, so show HUD
|
||||
{
|
||||
GuiControl,, HUD_Progress, % ProgressGet() ; Update progress bar
|
||||
GuiControl,, HUD_Text, % HUD_LevelText . LevelCheck() . " " . ProfileGet("title")
|
||||
GuiControl,, HUD_Points, % PointsCheck() . "/" . ThreshCheck()
|
||||
|
||||
Gui, HUD_Level:Show, x80 y45 NoActivate
|
||||
WinSet, AlwaysOnTop, On
|
||||
Gui, HUD_Momentum:Show, NoActivate
|
||||
WinSet, AlwaysOnTop, On
|
||||
HUD_MouseOverHide(LevelX, LevelY, LevelW, LevelH)
|
||||
|
||||
VisibState = 1 ; HUD now showing
|
||||
}
|
||||
else ; show HUD temporarily when points are awarded, update progress bar and text, and then hide again.
|
||||
{
|
||||
|
||||
Gui, HUD_Level:Show, x80 y45 NoActivate
|
||||
WinSet, AlwaysOnTop, On
|
||||
Gui, HUD_Momentum:Show, NoActivate
|
||||
WinSet, AlwaysOnTop, On
|
||||
|
||||
HUD_Update(PreviousLevelPoints, PreviousLevel)
|
||||
SetTimer, HideAgain, 2500
|
||||
return
|
||||
|
||||
HideAgain:
|
||||
Critical
|
||||
Gui, HUD_Level:Hide
|
||||
Gui, HUD_Momentum:Hide
|
||||
SetTimer, HideAgain, off
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
; Animate the progress bars and numbers and check for leveling up event:
|
||||
HUD_Update(PreviousLevelPoints, PreviousLevel)
|
||||
{
|
||||
global
|
||||
Gui, HUD_Level:Default ; Operate on the Level module
|
||||
CurrentLevelPoints := ProgressGet()
|
||||
if (PreviousLevelPoints < CurrentLevelPoints)
|
||||
{
|
||||
; slide up to sub100 value CurrentLevelPoints
|
||||
GuiControl,, HUD_Progress, % PreviousLevelPoints
|
||||
if (CurrentLevelPoints >= 100)
|
||||
{
|
||||
split = 1
|
||||
CurrentLevelPoints = 100
|
||||
}
|
||||
else
|
||||
split = 0
|
||||
AnimationCount := CurrentLevelPoints - PreviousLevelPoints
|
||||
AnimPoints := PointsCheck() - AnimationCount
|
||||
Loop % AnimationCount
|
||||
{
|
||||
GuiControl,, HUD_Progress, % PreviousLevelPoints + A_Index
|
||||
;GuiControl,, HUD_Text, % HUD_LevelText . PreviousLevel . " +" . A_Index . " XP"
|
||||
GuiControl,, HUD_Text, % HUD_LevelText . PreviousLevel . " +" . A_Index . " XP " . ProfileGet("title")
|
||||
GuiControl,, HUD_Points, % AnimPoints + A_Index . "/" . ThreshCheck()
|
||||
Sleep 50
|
||||
}
|
||||
if (split = 1)
|
||||
{
|
||||
GuiControl,, HUD_Progress, 0
|
||||
NewLevelPoints := ProgressGet() - 100
|
||||
Loop % NewLevelPoints
|
||||
{
|
||||
GuiControl,, HUD_Progress, % A_Index
|
||||
;GuiControl,, HUD_Text, % HUD_LevelText . LevelCheck() . " +" . A_Index
|
||||
GuiControl,, HUD_Text, % HUD_LevelText . LevelCheck() . " +" . A_Index . " XP " . ProfileGet("title")
|
||||
GuiControl,, HUD_Points, % (PointsCheck()-NewLevelPoints) + A_Index . "/" . ThreshCheck()
|
||||
Sleep 50
|
||||
}
|
||||
}
|
||||
}
|
||||
LevelCheck()
|
||||
}
|
||||
|
||||
|
||||
HUD_Message(message, duration="2500")
|
||||
{
|
||||
;Gui, 2:Destroy
|
||||
Gui, Message:New
|
||||
; Example: On-screen display (OSD) via transparent window:
|
||||
CustomColor = 9AFF9A ; Can be any RGB color (it will be made transparent below).
|
||||
Gui Message:+LastFound +AlwaysOnTop -Caption +ToolWindow ; +ToolWindow avoids a taskbar button and an alt-tab menu item.
|
||||
Gui, Message:Color, %CustomColor%
|
||||
Gui, Message:Font, s25 Q5, Electrolize ; Set a large font size (32-point).
|
||||
Gui, Message:Add, Text, Center cLime, %message% ; XX & YY serve to auto-size the window.
|
||||
; Make all pixels of this color transparent and make the text itself translucent (150):
|
||||
WinSet, TransColor, %CustomColor% 255
|
||||
|
||||
;VertPos := A_ScreenHeight - offset
|
||||
Gui, Message:Show, x60 y99 NoActivate ; NoActivate avoids deactivating the currently active window.
|
||||
;Sleep 2000
|
||||
SetTimer, DestroyMsg, %duration%
|
||||
return
|
||||
|
||||
DestroyMsg:
|
||||
Gui, Message:Destroy
|
||||
SetTimer, DestroyMsg, Off
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
PointsCheck()
|
||||
{
|
||||
; The current number of points I have
|
||||
global db
|
||||
PointsSet := db.OpenRecordSet("SELECT value FROM profile WHERE setting = 'points'")
|
||||
while (!PointsSet.EOF)
|
||||
{
|
||||
Points := PointsSet["value"]
|
||||
PointsSet.MoveNext()
|
||||
}
|
||||
PointsSet.Close()
|
||||
return Points
|
||||
}
|
||||
|
||||
; Could combine these two functions into one ^ \/, plus the writing ones:
|
||||
|
||||
ThreshCheck()
|
||||
{
|
||||
; The next upcoming point threshold to level up again
|
||||
global db
|
||||
ThresholdSet := db.OpenRecordSet("SELECT value FROM profile WHERE setting = 'threshold'")
|
||||
while (!ThresholdSet.EOF)
|
||||
{
|
||||
Threshold := ThresholdSet["value"]
|
||||
ThresholdSet.MoveNext()
|
||||
}
|
||||
ThresholdSet.Close()
|
||||
return Threshold
|
||||
}
|
||||
|
||||
|
||||
PointsWrite(Points)
|
||||
{
|
||||
;global PointsFile
|
||||
;IniWrite, %Points%, %PointsFile%, Data, Points ; Store certain number of awarded points in file
|
||||
global db
|
||||
bool := db.Query("UPDATE profile SET value = " . Points . " WHERE setting = 'points'")
|
||||
return
|
||||
}
|
||||
|
||||
ThreshWrite(Threshold)
|
||||
{
|
||||
;global PointsFile
|
||||
;IniWrite, %Threshold%, %PointsFile%, Data, Threshold
|
||||
global db
|
||||
bool := db.Query("UPDATE profile SET value = " . Threshold . " WHERE setting = 'threshold'")
|
||||
return
|
||||
}
|
||||
|
||||
ProgressGet() {
|
||||
CurrentProgress := 100 - (ThreshCheck() - PointsCheck()) ; How many points until next level up event
|
||||
return CurrentProgress ; What shows up on progress bar
|
||||
}
|
||||
|
||||
|
||||
LevelCheck() {
|
||||
global LevelUpSound
|
||||
; Threshold starts at 100, i.e. you start at level 1
|
||||
If (PointsCheck() >= ThreshCheck())
|
||||
{
|
||||
;Set next threshold
|
||||
;Threshold should go up.
|
||||
if (FileExist(LevelUpSound))
|
||||
SoundPlay, %LevelUpSound%
|
||||
ThreshWrite(ThreshCheck() + 100) ; Write new threshold
|
||||
LevelNow := Floor(ThreshCheck()/100)
|
||||
;HUD_Message("Level Up! Level " LevelNow, 5000) ; This *could* be a fancier notification than just a tray notification
|
||||
Notification("LEVEL UP!", "You have reached Level " . LevelNow)
|
||||
}
|
||||
Return Floor(ThreshCheck()/100)
|
||||
}
|
||||
|
||||
LevelGet()
|
||||
{
|
||||
return Floor(ThreshCheck()/100)
|
||||
}
|
||||
|
||||
; Main function to call to award points:
|
||||
UpdateProgress(Message, Award, Sound="") ; Call to give user some points and show a notification
|
||||
{
|
||||
PreviousLevelPoints := ProgressGet()
|
||||
PreviousLevel := LevelCheck()
|
||||
;SoundPlay, %Sound%
|
||||
;HUD_Message(Message) HUD_message should be altered to be a fancy HUD message
|
||||
Notification(Message, "+" . Award . " XP Awarded")
|
||||
PointsWrite(PointsCheck() + Award)
|
||||
HUD_Progress(PreviousLevelPoints, PreviousLevel)
|
||||
return
|
||||
}
|
||||
|
||||
Notification(Title, Message="", Duration=9)
|
||||
{
|
||||
Notify(Title, Message, Duration, "GC=15384E GR=0 GT=200 TS=14 TC=ffffff TF=Electrolize MS=14 MC=48B1DF MF=Electrolize BW=0 BR=0")
|
||||
return
|
||||
}
|
||||
38
Help.ahk
Normal file
38
Help.ahk
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
; Help menu items:========================================================================
|
||||
ReferenceHotkeys:
|
||||
GuiChildInit("RefHkeys")
|
||||
RHw = 300
|
||||
RHh = 250
|
||||
RHx := CenterX(RHw)
|
||||
RHy := CenterY(RHh)
|
||||
|
||||
HKRefText =
|
||||
(
|
||||
To toggle the Heads-Up Display, press: Alt+F2
|
||||
|
||||
To quickly add a project to your list for later, from anywhere; when you're doing anything, press:
|
||||
Ctrl+Alt+A
|
||||
|
||||
To quickly log a finished project without having to add it to the list first, press:
|
||||
Ctrl+Alt+D
|
||||
|
||||
To quickly give yourself points, use the following:
|
||||
5 Points: Ctrl+Shift+1
|
||||
10 Points: Ctrl+Shift+2
|
||||
25 Points: Ctrl+Shift+3
|
||||
100 Points (Instantly go up a whole level!): Ctrl+Shift+4
|
||||
)
|
||||
|
||||
Gui, RefHkeys:Add, Edit,% "ReadOnly w" RHw-20 " h" RHh-20, % HKRefText
|
||||
|
||||
Gui, RefHkeys:Show, w%RHw% h%RHh% x%RHx% y%RHy%, Reference
|
||||
return
|
||||
|
||||
RefHKeysGuiEscape:
|
||||
RefHKeysGuiClose:
|
||||
GuiChildClose("RefHKeys")
|
||||
return
|
||||
|
||||
Discussion:
|
||||
Run http://www.reddit.com/r/LifeRPG
|
||||
return
|
||||
48
Hotkeys.ahk
Normal file
48
Hotkeys.ahk
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
;~ ===============================================================================
|
||||
;~ Hotkeys:
|
||||
|
||||
;~ Pressing Alt+V focuses user on the ListView:
|
||||
#If WinActive(WindowFind)
|
||||
!x::
|
||||
GuiControl, Focus, MainList
|
||||
LV_Modify(1, "Select Focus")
|
||||
return
|
||||
|
||||
;~ Enables Ctrl+Backspace deletion in edit fields:
|
||||
#If WinActive("ahk_class AutoHotkeyGUI")
|
||||
^BS::
|
||||
send, ^+{left}{delete}
|
||||
return
|
||||
|
||||
;~ Give yourself points manually:
|
||||
#If ; Clear out context sensitivity
|
||||
; Easy tasks
|
||||
^+1::
|
||||
UpdateProgress("Really Easy Achievement", 5, "increase.wav")
|
||||
return
|
||||
|
||||
; Medium difficulty
|
||||
^+2::
|
||||
UpdateProgress("Pretty Easy Achievement", 10, "medium.wav")
|
||||
return
|
||||
|
||||
; Heavy lifting
|
||||
^+3::
|
||||
UpdateProgress("Medium Achievement", 25, "hard.wav")
|
||||
return
|
||||
|
||||
; Completed big project
|
||||
^+4::
|
||||
UpdateProgress("Hard Achievement", 100, "goal.wav")
|
||||
return
|
||||
|
||||
!F2::
|
||||
HUD_Progress()
|
||||
return
|
||||
|
||||
;~ !F1::
|
||||
;~ if (WinActive(WindowFind))
|
||||
;~ WinMinimize, %WindowFind%
|
||||
;~ else
|
||||
;~ WinActivate, %WindowFind%
|
||||
;~ return
|
||||
389
LVCustomColors.ahk
Normal file
389
LVCustomColors.ahk
Normal file
|
|
@ -0,0 +1,389 @@
|
|||
LV_Initialize(Gui_Number="", Control="", Column="")
|
||||
{
|
||||
local hGUI, hLV
|
||||
;Get either class or hWnd of control
|
||||
If !Control ;Control omitted
|
||||
{
|
||||
If (Gui_Number > 99)
|
||||
hLV := Gui_Number
|
||||
Else ;No hWnd => default
|
||||
Control = SysListView321
|
||||
}
|
||||
Else If RegExMatch(Control, "^[1-9]\d*$") ;ClassNN Number provided
|
||||
Control = SysListView32%Control%
|
||||
Else If !RegExMatch(Control, "^(SysListView32)?[1-9]\d*$") ;Not a ClassNN => control's associated var
|
||||
{
|
||||
If (!(Gui_Number > 0) || (Gui_Number > 99))
|
||||
Gui_Number = 1
|
||||
If _%Gui_Number%_%Control%_
|
||||
Return
|
||||
GuiControlGet, hLV, %Gui_Number%:hWnd, %Control%
|
||||
If ErrorLevel
|
||||
Return
|
||||
_%Gui_Number%_%Control%_ := hLV
|
||||
} ;Otherwise, ClassNN was provided.
|
||||
|
||||
If hLV
|
||||
{
|
||||
If (_%hLV%_ || !HWND2GuiNClass(hLV, Gui_Number, Control))
|
||||
Return
|
||||
}
|
||||
Else If Control ;Control found/provided
|
||||
{
|
||||
If (!(Gui_Number > 0) || (Gui_Number > 99))
|
||||
Gui_Number = 1
|
||||
If _%Gui_Number%_%Control%_
|
||||
Return
|
||||
Gui, %Gui_Number%:+LastFoundExist
|
||||
If !(hGUI := WinExist())
|
||||
Return
|
||||
GuiControlGet, hLV, %Gui_Number%:HWND, %Control%
|
||||
If ErrorLevel
|
||||
Return
|
||||
}
|
||||
Else
|
||||
Return
|
||||
|
||||
hLV+=0
|
||||
;Save handle to quickly get it from gui+control
|
||||
_%Gui_Number%_%Control%_ := hLV
|
||||
;Save gui and control to quickly get it from handle
|
||||
_%hLV%_ := Gui_Number "|" Control
|
||||
;Save column containing indexes
|
||||
If !Column
|
||||
_%hLV%_Col_ = 1
|
||||
Else
|
||||
_%hLV%_Col_ := Column
|
||||
;Maintain a list of registered handles for wm_notify to operate on every registered control
|
||||
If !_LTV_h_List_
|
||||
_LTV_h_List_ := "|" hLV "|"
|
||||
Else
|
||||
_LTV_h_List_ .= hLV "|"
|
||||
;Maintain a list of modified indexes for disposal
|
||||
;Colors bound to indexes
|
||||
_%hLV%_0_Text = |
|
||||
_%hLV%_0_Back = |
|
||||
;Colors bound to lines
|
||||
_%hLV%_0_LText = |
|
||||
_%hLV%_0_LBack = |
|
||||
OnMessage( 0x4E, "WM_NOTIFY" )
|
||||
Return hLV
|
||||
}
|
||||
|
||||
LV_Change(Gui_Number="", Control="", Select="", Column="")
|
||||
{
|
||||
local hLV
|
||||
;Get either class or hWnd of control
|
||||
If !Control ;Control omitted
|
||||
{
|
||||
If (Gui_Number > 99)
|
||||
hLV := Gui_Number
|
||||
Else ;No hWnd => default
|
||||
Control = SysListView321
|
||||
}
|
||||
Else If RegExMatch(Control, "^[1-9]\d*$") ;ClassNN Number provided
|
||||
Control = SysListView32%Control%
|
||||
Else If !RegExMatch(Control, "^(SysListView32)?[1-9]\d*$") ;Not a ClassNN or a NN => control's associated var
|
||||
{
|
||||
If (!(Gui_Number > 0) || (Gui_Number > 99))
|
||||
Gui_Number = 1
|
||||
If !(hLV := _%Gui_Number%_%Control%_) ;May not have been initialized
|
||||
{
|
||||
If !(hLV := LV_Initialize(Gui_Number, Control, Column))
|
||||
Return
|
||||
}
|
||||
} ;Otherwise, ClassNN was provided.
|
||||
|
||||
If hLV
|
||||
{
|
||||
hLV+=0
|
||||
If !_%hLV%_ ;May not have been initialized
|
||||
{
|
||||
If !LV_Initialize(hLV, "", Column)
|
||||
Return
|
||||
}
|
||||
Loop, Parse, _%hLV%_, |
|
||||
{
|
||||
If (A_Index = 1)
|
||||
Gui_Number := A_LoopField
|
||||
Else
|
||||
Control := A_LoopField
|
||||
}
|
||||
}
|
||||
Else If Control ;Control found/provided
|
||||
{
|
||||
If (!(Gui_Number > 0) || (Gui_Number > 99))
|
||||
Gui_Number = 1
|
||||
If !(hLV := _%Gui_Number%_%Control%_) ;May not have been initialized
|
||||
{
|
||||
If !(hLV := LV_Initialize(Gui_Number, Control, Column))
|
||||
Return
|
||||
}
|
||||
}
|
||||
Else
|
||||
Return
|
||||
|
||||
_LV_h_ := hLV+0
|
||||
If (Select != 0)
|
||||
{
|
||||
Gui, %Gui_Number%:Default
|
||||
Gui, ListView, %Control%
|
||||
}
|
||||
If (Column && (Column != _%hLV%_Col_))
|
||||
_%hLV%_Col_ := Column
|
||||
Return 1
|
||||
}
|
||||
|
||||
|
||||
LV_SetColor(Index="", TextColor="", BackColor="", Redraw=1)
|
||||
{
|
||||
local i, j, L
|
||||
If !_LV_h_
|
||||
Return
|
||||
Index+=0
|
||||
If (Index < 0)
|
||||
{
|
||||
L = L
|
||||
i = 1
|
||||
Index := -Index-1
|
||||
}
|
||||
Else If (Index > 0)
|
||||
{
|
||||
i = 1
|
||||
Index--
|
||||
}
|
||||
Else If ((Index = "-0") || (Index = "-"))
|
||||
{
|
||||
L = L
|
||||
Index = 0
|
||||
ControlGet, i, List, Count, , ahk_id %_LV_h_%
|
||||
}
|
||||
Else
|
||||
{
|
||||
Index = 0
|
||||
ControlGet, i, List, Count, , ahk_id %_LV_h_%
|
||||
}
|
||||
Loop, %i%
|
||||
{
|
||||
j := A_Index+Index
|
||||
If (TextColor != "")
|
||||
{
|
||||
If (TextColor >= 0)
|
||||
{
|
||||
If !InStr(_%_LV_h_%_0_%L%Text, "|" j "|")
|
||||
_%_LV_h_%_0_%L%Text .= j "|"
|
||||
_%_LV_h_%_%j%_%L%Text := TextColor
|
||||
}
|
||||
Else
|
||||
{
|
||||
_%_LV_h_%_%j%_%L%Text =
|
||||
StringReplace, _%_LV_h_%_0_%L%Text, _%_LV_h_%_0_%L%Text, |%j%|, |
|
||||
}
|
||||
}
|
||||
If (BackColor != "")
|
||||
{
|
||||
If (BackColor >= 0)
|
||||
{
|
||||
If !InStr(_%_LV_h_%_0_%L%Back, "|" j "|")
|
||||
_%_LV_h_%_0_%L%Back .= j "|"
|
||||
_%_LV_h_%_%j%_%L%Back := BackColor
|
||||
}
|
||||
Else
|
||||
{
|
||||
_%_LV_h_%_%j%_%L%Back =
|
||||
StringReplace, _%_LV_h_%_0_%L%Back, _%_LV_h_%_0_%L%Back, |%j%|, |
|
||||
}
|
||||
}
|
||||
}
|
||||
If Redraw
|
||||
WinSet, Redraw,, ahk_id %_LV_h_%
|
||||
Return 1
|
||||
}
|
||||
|
||||
|
||||
LV_GetColor(Index, T="Text") ;Index of the item from which to get color , T="Text" ; T="Back" , L=0 : linked to lines; L=1 : linked to rows
|
||||
{
|
||||
local L
|
||||
If (Index<0)
|
||||
{
|
||||
L = L
|
||||
Index := -Index
|
||||
}
|
||||
Return _%_LV_h_%_%Index%_%L%%T%
|
||||
}
|
||||
|
||||
|
||||
LV_Destroy(Gui_Number="", Control="", DeactivateWMNotify="")
|
||||
{
|
||||
local hLV
|
||||
;Get either class or hWnd of control
|
||||
If !Control ;Control omitted
|
||||
{
|
||||
If (Gui_Number > 99)
|
||||
hLV := Gui_Number
|
||||
Else ;No hWnd => default
|
||||
Control = SysListView321
|
||||
}
|
||||
Else If Control RegExMatch(Control, "^[1-9]\d*$") ;ClassNN Number provided
|
||||
Control = SysListView32%Control%
|
||||
Else If !RegExMatch(Control, "^(SysListView32)?[1-9]\d*$") ;Not a ClassNN or a NN => control's associated var
|
||||
{
|
||||
If (!(Gui_Number > 0) || (Gui_Number > 99))
|
||||
Gui_Number = 1
|
||||
If !(hLV := _%Gui_Number%_%Control%_)
|
||||
Return
|
||||
} ;Otherwise, ClassNN was provided.
|
||||
|
||||
If hLV
|
||||
{
|
||||
hLV+=0
|
||||
If !_%hLV%_
|
||||
Return
|
||||
Loop, Parse, _%hLV%_, |
|
||||
{
|
||||
If (A_Index = 1)
|
||||
Gui_Number := A_LoopField
|
||||
Else
|
||||
Control := A_LoopField
|
||||
}
|
||||
}
|
||||
Else If Control ;Control found/provided
|
||||
{
|
||||
If (!(Gui_Number > 0) || (Gui_Number > 99))
|
||||
Gui_Number = 1
|
||||
If !(hLV := _%Gui_Number%_%Control%_)
|
||||
Return
|
||||
}
|
||||
Else
|
||||
Return
|
||||
|
||||
Loop, Parse, _%hLV%_0_Text, |
|
||||
_%hLV%_%A_LoopField%_Text =
|
||||
_%hLV%_0_Text =
|
||||
Loop, Parse, _%hLV%_0_Back, |
|
||||
_%hLV%_%A_LoopField%_Back =
|
||||
_%hLV%_0_Back =
|
||||
Loop, Parse, _%hLV%_0_LText, |
|
||||
_%hLV%_%A_LoopField%_LText =
|
||||
_%hLV%_0_LText =
|
||||
Loop, Parse, _%hLV%_0_LBack, |
|
||||
_%hLV%_%A_LoopField%_LBack =
|
||||
_%hLV%_0_LBack =
|
||||
_%Gui_Number%_%Control%_ =
|
||||
_%hLV%_Col_ =
|
||||
_%hLV%_ =
|
||||
WinSet, Redraw,, ahk_id %hLV%
|
||||
StringReplace, _LTV_h_List_, _LTV_h_List_, |%hLV%|, |, A
|
||||
If ((_LTV_h_List_ = "|") && DeactivateWMNotify)
|
||||
OnMessage( 0x4E, "" )
|
||||
If (hLV = _LV_h_)
|
||||
_LV_h_ =
|
||||
|
||||
Return 1
|
||||
}
|
||||
|
||||
|
||||
DecodeInteger( p_type, p_address, p_offset) ;, p_hex=false )
|
||||
{
|
||||
;old_FormatInteger := A_FormatInteger
|
||||
;ifEqual, p_hex, 1, SetFormat, Integer, hex
|
||||
;else, SetFormat, Integer, dec
|
||||
StringRight, size, p_type, 1
|
||||
loop, %size%
|
||||
value += *( ( p_address+p_offset )+( A_Index-1 ) ) << ( 8*( A_Index-1 ) )
|
||||
if ( size <= 4 and InStr( p_type, "u" ) != 1 and *( p_address+p_offset+( size-1 ) ) & 0x80 )
|
||||
value := -( ( ~value+1 ) & ( ( 2**( 8*size ) )-1 ) )
|
||||
;SetFormat, Integer, %old_FormatInteger%
|
||||
return, value
|
||||
}
|
||||
|
||||
|
||||
EncodeInteger( p_value, p_size, p_address, p_offset )
|
||||
{
|
||||
loop, %p_size%
|
||||
DllCall( "RtlFillMemory", "uint", p_address+p_offset+A_Index-1, "uint", 1, "uchar", p_value >> ( 8*( A_Index-1 ) ) )
|
||||
}
|
||||
|
||||
|
||||
;Retrieves gui number and classNN from hwnd of a gui control
|
||||
HWND2GuiNClass(hWnd, ByRef Gui = "", ByRef Control = "")
|
||||
{
|
||||
WinGetClass, Cc, ahk_id %hWnd%
|
||||
Loop, 99
|
||||
{
|
||||
Gui, %A_Index%:+LastFoundExist
|
||||
If !WinExist()
|
||||
Continue
|
||||
Gui_Number := A_Index
|
||||
Loop
|
||||
{
|
||||
GuiControlGet, hWCc, %Gui_Number%:HWND, %Cc%%A_Index%
|
||||
If !hWCc
|
||||
Break
|
||||
If (hWnd = hWCc)
|
||||
{
|
||||
Ctrl := Cc A_Index
|
||||
Break
|
||||
}
|
||||
}
|
||||
If Ctrl
|
||||
{
|
||||
Gui := A_Index
|
||||
Control := Ctrl
|
||||
Return 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LV_WM_NOTIFY(p_l)
|
||||
{
|
||||
local draw_stage, Current_Line, hLV, Index1, Index
|
||||
static IndexList
|
||||
Critical
|
||||
If InStr(_LTV_h_List_, "|" (hLV := DecodeInteger( "uint4", p_l, 0 )) "|")
|
||||
{
|
||||
If (DecodeInteger( "int4", p_l, 8 ) = -12) ; NM_CUSTOMDRAW
|
||||
{
|
||||
draw_stage := DecodeInteger( "uint4", p_l, 12 )
|
||||
If ( draw_stage = 1 ) ; CDDS_PREPAINT
|
||||
{
|
||||
ControlGet, IndexList, List, % "Col" _%hLV%_Col_, , ahk_id %hLV%
|
||||
If !RegexMatch(IndexList, "S)^([1-9]\d*\n)*[1-9]\d*$") ;The index column must contain exclusively strictly positive decimal integers
|
||||
IndexList =
|
||||
Return, 0x20 ; CDRF_NOTIFYITEMDRAW
|
||||
}
|
||||
Else If ( draw_stage = 0x10001 ) ; CDDS_ITEM
|
||||
{
|
||||
Current_Line := DecodeInteger( "uint4", p_l, 36 )+1
|
||||
If IndexList
|
||||
RegexMatch(IndexList, "S)(?:.*?\n){" Current_Line-1 "}(.*?)(?:\n|$)", Index)
|
||||
If (IndexList && (_%hLV%_%Index1%_Text != ""))
|
||||
EncodeInteger( _%hLV%_%Index1%_Text, 4, p_l, 48 ) ; indexed foreground
|
||||
Else If (_%hLV%_%Current_Line%_LText != "")
|
||||
EncodeInteger( _%hLV%_%Current_Line%_LText, 4, p_l, 48 ) ; line foreground
|
||||
If (IndexList && (_%hLV%_%Index1%_Back != ""))
|
||||
EncodeInteger( _%hLV%_%Index1%_Back, 4, p_l, 52 ) ; indexed background
|
||||
Else If (_%hLV%_%Current_Line%_LBack != "")
|
||||
EncodeInteger( _%hLV%_%Current_Line%_LBack, 4, p_l, 52 ) ; line background
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
WM_NOTIFY( p_w, p_l, p_m )
|
||||
{
|
||||
Critical
|
||||
;/*
|
||||
;Prevents column resizing, uncomment if resizing is buggy
|
||||
Index := DecodeInteger( "int4", p_l, 8 )
|
||||
If ((Index = -326) || (Index = -306)) ; HDN_BEGINTRACKA = -306, HDN_BEGINTRACKW = -326
|
||||
Return 1
|
||||
;*/
|
||||
|
||||
;ADD YOUR CODE HERE
|
||||
|
||||
Return LV_WM_NOTIFY(p_l)
|
||||
}
|
||||
52
Lib/ADO.ahk
Normal file
52
Lib/ADO.ahk
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
|
||||
/*
|
||||
* Provides Static ADO Helper classes and Enums
|
||||
*
|
||||
*/
|
||||
class ADO
|
||||
{
|
||||
class CursorType
|
||||
{
|
||||
static adOpenUnspecified := -1
|
||||
static adOpenForwardOnly := 0
|
||||
static adOpenKeyset := 1
|
||||
static adOpenDynamic := 2
|
||||
static adOpenStatic := 3
|
||||
}
|
||||
|
||||
class LockType
|
||||
{
|
||||
static adLockUnspecified := -1
|
||||
static adLockReadOnly := 1
|
||||
static adLockPessimistic := 2
|
||||
static adLockOptimistic := 3
|
||||
static adLockBatchOptimistic := 4
|
||||
}
|
||||
|
||||
class CommandType
|
||||
{
|
||||
static adCmdUnspecified := -1
|
||||
static adCmdText := 1
|
||||
static adCmdTable := 2
|
||||
static adCmdStoredProc := 4
|
||||
static adCmdUnknown := 8
|
||||
static adCmdFile := 256
|
||||
static adCmdTableDirect := 512
|
||||
}
|
||||
|
||||
class AffectEnum
|
||||
{
|
||||
static adAffectCurrent := 1
|
||||
static adAffectGroup := 2
|
||||
}
|
||||
|
||||
class ObjectStateEnum
|
||||
{
|
||||
static adStateClosed := 0 ; The object is closed
|
||||
static adStateOpen := 1 ; The object is open
|
||||
static adStateConnecting := 2 ; The object is connecting
|
||||
static adStateExecuting := 4 ; The object is executing a command
|
||||
static adStateFetching := 8 ; The rows of the object are being retrieved
|
||||
}
|
||||
|
||||
}
|
||||
94
Lib/Base.ahk
Normal file
94
Lib/Base.ahk
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
/**************************************
|
||||
base classes
|
||||
***************************************
|
||||
*/
|
||||
|
||||
global null := 0 ; for better readability
|
||||
|
||||
|
||||
/*
|
||||
Check for same (base) Type
|
||||
*/
|
||||
is(obj, type){
|
||||
|
||||
if(IsObject(type))
|
||||
type := typeof(type)
|
||||
|
||||
while(IsObject(obj)){
|
||||
|
||||
if(obj.__Class == type){
|
||||
return true
|
||||
}
|
||||
obj := obj.base
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
typeof(obj){
|
||||
if(IsObject(obj)){
|
||||
cls := obj.__Class
|
||||
|
||||
if(cls != "")
|
||||
return cls
|
||||
|
||||
while(IsObject(obj)){
|
||||
if(obj.__Class != ""){
|
||||
return obj.__Class
|
||||
}
|
||||
obj := obj.base
|
||||
}
|
||||
return "Object"
|
||||
}
|
||||
return "NonObject"
|
||||
}
|
||||
|
||||
IsObjectMember(obj, memberStr){
|
||||
if(IsObject(obj)){
|
||||
return ObjHasKey(obj, memberStr) || IsMetaProperty(memberStr)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
IsMetaProperty(str){
|
||||
static metaProps := "__New,__Get,__Set,__Class"
|
||||
if str in %metaProps%
|
||||
return true
|
||||
else
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Provides some common used Exception Templates
|
||||
*
|
||||
*/
|
||||
class Exceptions
|
||||
{
|
||||
NotImplemented(){
|
||||
return Exception("A not implemented Method was called.",-1)
|
||||
}
|
||||
|
||||
MustOverride(){
|
||||
return Exception("This Method must be overriden",-1)
|
||||
}
|
||||
|
||||
ArgumentException(furtherInfo=""){
|
||||
return Exception("A wrong Argument has been passed to this Method`n" furtherInfo,-1)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
;Base
|
||||
{
|
||||
"".base.__Call := "Default__Warn"
|
||||
"".base.__Set := "Default__Warn"
|
||||
"".base.__Get := "Default__Warn"
|
||||
|
||||
Default__Warn(nonobj, p1="", p2="", p3="", p4="")
|
||||
{
|
||||
ListLines
|
||||
MsgBox A non-object value was improperly invoked.`n`nSpecifically: %nonobj%
|
||||
}
|
||||
}
|
||||
104
Lib/Collection.ahk
Normal file
104
Lib/Collection.ahk
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
#Include <Base>
|
||||
/*
|
||||
Basic Collection implementation
|
||||
*/
|
||||
class Collection
|
||||
{
|
||||
; Methoden Implementation
|
||||
/*
|
||||
Fügt ein Element der Collection hinzu
|
||||
*/
|
||||
Add(obj){
|
||||
this.Insert(obj)
|
||||
}
|
||||
|
||||
/*
|
||||
Fügt eine Auflistung dieser Collection hinzu
|
||||
*/
|
||||
AddRange(objs){
|
||||
if(IsObject(objs)){
|
||||
for each, item in objs
|
||||
this.Insert(item)
|
||||
} else
|
||||
throw Exceptions.ArgumentException("Must submit Array!")
|
||||
}
|
||||
|
||||
Clear(){
|
||||
this.Remove(this.MinIndex(), this.MaxIndex())
|
||||
}
|
||||
|
||||
RemoveItem(item){
|
||||
for k, e in this
|
||||
if(e = item)
|
||||
this.Remove(k)
|
||||
}
|
||||
|
||||
/*
|
||||
Returns the count of elements contained in this collection
|
||||
*/
|
||||
Count(){
|
||||
return this.SetCapacity(0)
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns true if this collection is empty
|
||||
*/
|
||||
IsEmpty(){
|
||||
return this.Count() == 0
|
||||
}
|
||||
|
||||
First(){
|
||||
return this[this.MinIndex()]
|
||||
}
|
||||
|
||||
Last(){
|
||||
return this[this.MaxIndex()]
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Sortiert die Liste
|
||||
*/
|
||||
Sort(comparer=""){
|
||||
if(IsFunc(comparer))
|
||||
comparer := "F " comparer
|
||||
|
||||
for each, num in this
|
||||
nums .= num "`n"
|
||||
Sort, nums, % comparer
|
||||
this.Clear()
|
||||
Loop, parse, nums, `,
|
||||
this.Add(A_LoopField)
|
||||
}
|
||||
|
||||
ToString(){
|
||||
str := ""
|
||||
for k, v in this
|
||||
{
|
||||
valStr := ""
|
||||
if(IsObject(v)){
|
||||
valStr := "{" . typeof(v) . "}"
|
||||
if(IsFunc(v.ToString)){
|
||||
valStr .= " " . v.ToString()
|
||||
}
|
||||
}else{
|
||||
valStr := "'" v "'"
|
||||
}
|
||||
|
||||
|
||||
str .= k ": " . valStr . "`n"
|
||||
}
|
||||
return str
|
||||
}
|
||||
|
||||
/*
|
||||
Konstruktor - erstellt eine neue, (leere) Collection
|
||||
|
||||
enum : Element die zubign vorhanden sein sollen
|
||||
*/
|
||||
__New(enum = 0){
|
||||
if(IsObject(enum)){
|
||||
this.AddRange(enum)
|
||||
}
|
||||
}
|
||||
}
|
||||
27
Lib/DBA.ahk
Normal file
27
Lib/DBA.ahk
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
DataBase NameSpace Import
|
||||
*/
|
||||
|
||||
#Include <Base>
|
||||
#Include <Collection>
|
||||
|
||||
;drivers
|
||||
#Include <SQLite_L>
|
||||
#Include <mySQL>
|
||||
#Include <ADO>
|
||||
|
||||
class DBA ; namespace DBA
|
||||
{
|
||||
#Include <DataBaseFactory>
|
||||
#Include <DataBaseAbstract>
|
||||
|
||||
|
||||
; Concrete SQL Providers
|
||||
#Include <DataBaseSQLLite>
|
||||
#Include <DataBaseMySQL>
|
||||
#Include <DataBaseADO>
|
||||
|
||||
#Include <RecordSetSqlLite>
|
||||
#Include <RecordSetADO>
|
||||
#Include <RecordSetMySQL>
|
||||
}
|
||||
200
Lib/DataBaseADO.ahk
Normal file
200
Lib/DataBaseADO.ahk
Normal file
|
|
@ -0,0 +1,200 @@
|
|||
;namespace DBA
|
||||
|
||||
/*
|
||||
Represents a Connection to a ADO Database
|
||||
*/
|
||||
class DataBaseADO extends DBA.DataBase
|
||||
{
|
||||
_connection := null
|
||||
_connectionData := ""
|
||||
|
||||
__New(connectionString){
|
||||
this._connectionData := connectionString
|
||||
this.Connect()
|
||||
}
|
||||
|
||||
/*
|
||||
(Re) Connects to the db with the given creditals
|
||||
*/
|
||||
Connect(){
|
||||
if(IsObject(this._connection))
|
||||
{
|
||||
this.Close()
|
||||
}
|
||||
this._connection := ComObjCreate("ADODB.connection")
|
||||
|
||||
;connection.Open connectionstring,userID,password,options
|
||||
this._connection.Open(this._connectionData)
|
||||
}
|
||||
|
||||
Close(){
|
||||
if(this.IsConnected())
|
||||
{
|
||||
this._connection.Close()
|
||||
this._connection := null
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Is this connection open?
|
||||
*/
|
||||
IsConnected(){
|
||||
return (IsObject(this._connection) && this._connection.State != ADO.ObjectStateEnum.adStateClosed)
|
||||
}
|
||||
|
||||
IsValid(){
|
||||
return IsObject(this._connection)
|
||||
}
|
||||
|
||||
GetLastError(){
|
||||
; todo
|
||||
}
|
||||
|
||||
GetLastErrorMsg(){
|
||||
|
||||
errMsg := ""
|
||||
for objErr in this._connection.Errors
|
||||
{
|
||||
errMsg .= objErr.Number " " objErr.Description " Source:" objErr.Source "`n"
|
||||
}
|
||||
|
||||
return errMsg
|
||||
}
|
||||
|
||||
SetTimeout(timeout = 1000){
|
||||
if(this.IsValid())
|
||||
this._connection.ConnectionTimeout := (timeout / 1000)
|
||||
}
|
||||
|
||||
|
||||
|
||||
Changes() {
|
||||
/*
|
||||
ToDo
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Querys the DB and returns a RecordSet
|
||||
*/
|
||||
OpenRecordSet(sql, editable = false){
|
||||
return new DBA.RecordSetADO(sql, this._connection, editable)
|
||||
}
|
||||
|
||||
/*
|
||||
Querys the DB and returns a ResultTable or true/false
|
||||
*/
|
||||
Query(sql){
|
||||
ret := false
|
||||
if(this.IsValid())
|
||||
{
|
||||
;Execute( commandtext,ra,options)
|
||||
affectedRows := 0
|
||||
rs := this._connection.Execute(sql, affectedRows)
|
||||
if(IsObject(rs) && rs.State != ADO.ObjectStateEnum.adStateClosed)
|
||||
{
|
||||
ret := this.FetchADORecordSet(rs)
|
||||
rs.Close()
|
||||
}else{
|
||||
ret := affectedRows
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
EscapeString(str){
|
||||
return Mysql_escape_string(str)
|
||||
}
|
||||
|
||||
|
||||
BeginTransaction(){
|
||||
if(this.IsValid())
|
||||
this._connection.BeginTrans()
|
||||
}
|
||||
|
||||
EndTransaction(){
|
||||
if(this.IsValid())
|
||||
this._connection.CommitTrans()
|
||||
}
|
||||
|
||||
Rollback(){
|
||||
if(this.IsValid())
|
||||
this._connection.RollbackTrans()
|
||||
}
|
||||
|
||||
FetchADORecordSet(adoRS){
|
||||
tbl := null
|
||||
if(IsObject(adoRS) && !adoRS.EOF)
|
||||
{
|
||||
columnNames := new Collection()
|
||||
myRows := new Collection()
|
||||
|
||||
|
||||
for field in adoRS.Fields
|
||||
columnNames.add(field.Name)
|
||||
|
||||
fetchedArray := adoRS.GetRows() ; returns a COM-SafeArray Wrapper
|
||||
colSize := fetchedArray.MaxIndex(1) + 1
|
||||
rowSize := fetchedArray.MaxIndex(2) + 1
|
||||
|
||||
loop, % rowSize
|
||||
{
|
||||
i := A_index - 1
|
||||
datafields := new Collection()
|
||||
loop, % colSize
|
||||
{
|
||||
j := A_index - 1
|
||||
datafields.add(fetchedArray[j,i])
|
||||
}
|
||||
myRows.Add(new DBA.Row(columnNames, datafields))
|
||||
}
|
||||
|
||||
tbl := new DBA.Table(myRows, columnNames)
|
||||
}
|
||||
return tbl
|
||||
}
|
||||
|
||||
InsertMany(records, tableName){
|
||||
|
||||
;objRecordset.Open source,actconn,cursortyp,locktyp,opt
|
||||
|
||||
rs := ComObjCreate("ADODB.Recordset")
|
||||
/* batch
|
||||
rs.Open(tableName, this._connection, ADO.CursorType.adOpenKeyset, ADO.LockType.adLockBatchOptimistic, ADO.CommandType.adCmdTable)
|
||||
|
||||
for each, record in records
|
||||
{
|
||||
rs.AddNew()
|
||||
|
||||
for column, value in record
|
||||
{
|
||||
rs.Fields[column].Value := value
|
||||
}
|
||||
}
|
||||
rs.UpdateBatch()
|
||||
*/
|
||||
|
||||
rs.Open(tableName, this._connection, ADO.CursorType.adOpenKeyset, ADO.LockType.adLockOptimistic, ADO.CommandType.adCmdTable)
|
||||
|
||||
for each, record in records
|
||||
{
|
||||
rs.AddNew()
|
||||
|
||||
for column, value in record
|
||||
{
|
||||
rs.Fields[column].Value := value
|
||||
}
|
||||
rs.Update()
|
||||
}
|
||||
|
||||
rs.Close()
|
||||
}
|
||||
|
||||
Insert(record, tableName){
|
||||
records := new Collection()
|
||||
records.Add(record)
|
||||
return this.InsertMany(records, tableName)
|
||||
}
|
||||
|
||||
}
|
||||
308
Lib/DataBaseAbstract.ahk
Normal file
308
Lib/DataBaseAbstract.ahk
Normal file
|
|
@ -0,0 +1,308 @@
|
|||
; namespace DBA
|
||||
|
||||
/*
|
||||
#####################################################################################
|
||||
Abstract Database Classes
|
||||
Base for all concrete implementations for the supported DataBases.
|
||||
#####################################################################################
|
||||
*/
|
||||
|
||||
/*
|
||||
data := Row[index]
|
||||
data := Row["ColumnName"]
|
||||
*/
|
||||
|
||||
class Row
|
||||
{
|
||||
_columns := 0
|
||||
_fields := new Collection()
|
||||
|
||||
Count(){
|
||||
return this._fields.Count()
|
||||
}
|
||||
|
||||
ToString(){
|
||||
return this._fields.ToString()
|
||||
}
|
||||
|
||||
__Get(param){
|
||||
|
||||
if(IsObject(param)){
|
||||
throw Exception("Expected Index or Column Name!", -1)
|
||||
}
|
||||
|
||||
if(!IsObjectMember(this, param)){
|
||||
if param is Integer
|
||||
{
|
||||
; // assume that an indexed access is desired
|
||||
; // return the corresponding ROW
|
||||
if(this.ContainsIndex(param))
|
||||
return this._fields[param]
|
||||
} else {
|
||||
; // assume that an columnname access is desired
|
||||
; // find index
|
||||
|
||||
index := 0
|
||||
for i, col in this._columns
|
||||
{
|
||||
if(col = param){
|
||||
index := i
|
||||
break
|
||||
}
|
||||
}
|
||||
if(this.ContainsIndex(index)){
|
||||
return this._fields[index]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ContainsIndex(index){
|
||||
return ((index > 0) && (index <= this._fields.Count()))
|
||||
}
|
||||
|
||||
/*
|
||||
Creates a New Row.
|
||||
columns : Collection of the Columnames
|
||||
fields: Collection of the Fields (Data)
|
||||
*/
|
||||
__New(columns, fields){
|
||||
|
||||
if(!is(columns, "Collection")){
|
||||
throw Exception("columns must be a Collection Object",-1)
|
||||
}
|
||||
|
||||
if(!is(fields, "Collection")){
|
||||
throw Exception("fields must be a Collection Object",-1)
|
||||
}
|
||||
|
||||
|
||||
this._fields := fields
|
||||
this._columns := columns
|
||||
}
|
||||
|
||||
__NewEnum() {
|
||||
return new DBA.Row.Enumerator(this)
|
||||
}
|
||||
|
||||
class Enumerator {
|
||||
__new(row) {
|
||||
this.columnEnum := ObjNewEnum(row.columns)
|
||||
this.fieldEnum := ObjNewEnum(row.fields)
|
||||
}
|
||||
|
||||
next(ByRef key, ByRef val) {
|
||||
return this.columnEnum.next("", key)
|
||||
&& this.fieldEnum.next("",val)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
row := table[index]
|
||||
*/
|
||||
|
||||
class Table
|
||||
{
|
||||
Rows := new Collection()
|
||||
Columns := new Collection()
|
||||
|
||||
Count(){
|
||||
return this.Rows.Count()
|
||||
}
|
||||
|
||||
ToString(){
|
||||
colstr := this.Columns.ToString()
|
||||
StringReplace, colstr, colstr, `n, |
|
||||
return "(" this.Rows.Count() ")" . colstr
|
||||
}
|
||||
|
||||
__Get(param){
|
||||
|
||||
if(IsObject(param)){
|
||||
throw Exception("Expected non-Object Index!",-1)
|
||||
}
|
||||
if(!IsObjectMember(this, param)){
|
||||
if param is Integer
|
||||
{
|
||||
; // assume that an indexed access is desired
|
||||
; // return the corresponding ROW
|
||||
if((param > 0) && (param < this.Rows.Count()) )
|
||||
return this.Rows[param]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Creates a New Table.
|
||||
rows: Collection of the Rows (Data)
|
||||
columns : Collection of the Columnames
|
||||
*/
|
||||
__New(rows, columns){
|
||||
|
||||
if(!is(rows, "Collection")){
|
||||
throw Exception("rows must be a Collection Object",-1)
|
||||
}
|
||||
|
||||
if(!is(columns, "Collection")){
|
||||
throw Exception("rows must be a Collection Object",-1)
|
||||
}
|
||||
|
||||
this.Rows := rows
|
||||
this.Columns := columns
|
||||
}
|
||||
|
||||
__NewEnum() {
|
||||
return ObjNewEnum(this.rows)
|
||||
}
|
||||
}
|
||||
|
||||
class DataBase
|
||||
{
|
||||
static NULL := Object()
|
||||
static TRUE := Object()
|
||||
static FALSE := Object()
|
||||
|
||||
__delete() {
|
||||
this.Close()
|
||||
}
|
||||
|
||||
IsValid(){
|
||||
throw Exceptions.MustOverride()
|
||||
}
|
||||
|
||||
Query(sql){
|
||||
throw Exceptions.MustOverride()
|
||||
}
|
||||
|
||||
QueryValue(sQry){
|
||||
rs := this.OpenRecordSet(sQry)
|
||||
value := rs[1]
|
||||
rs.Close()
|
||||
return value
|
||||
}
|
||||
|
||||
QueryRow(sQry){
|
||||
rs := this.OpenRecordSet(sQry)
|
||||
myrow := rs.getCurrentRow()
|
||||
rs.Close()
|
||||
return myrow
|
||||
}
|
||||
|
||||
OpenRecordSet(sql, editable = false){
|
||||
throw Exceptions.MustOverride()
|
||||
}
|
||||
|
||||
ToSqlLiteral(value) {
|
||||
if (IsObject(value)) {
|
||||
if (value == DBA.DataBase.NULL)
|
||||
return "NULL"
|
||||
if (value == DBA.DataBase.TRUE)
|
||||
return "TRUE"
|
||||
if (value == DBA.DataBase.FALSE)
|
||||
return "FALSE"
|
||||
}
|
||||
return "'" this.EscapeString(value) "'"
|
||||
}
|
||||
|
||||
EscapeString(string){
|
||||
throw Exceptions.MustOverride()
|
||||
}
|
||||
|
||||
QuoteIdentifier(identifier){
|
||||
throw Exceptions.MustOverride()
|
||||
}
|
||||
|
||||
BeginTransaction(){
|
||||
throw Exceptions.MustOverride()
|
||||
}
|
||||
|
||||
EndTransaction(){
|
||||
throw Exceptions.MustOverride()
|
||||
}
|
||||
|
||||
Rollback(){
|
||||
throw Exceptions.MustOverride()
|
||||
}
|
||||
|
||||
Insert(record, tableName){
|
||||
throw Exceptions.MustOverride()
|
||||
}
|
||||
|
||||
InsertMany(records, tableName){
|
||||
throw Exceptions.MustOverride()
|
||||
}
|
||||
|
||||
Update(fields, constraints, tableName, safe = True){
|
||||
throw Exceptions.MustOverride()
|
||||
}
|
||||
|
||||
Close(){
|
||||
throw Exceptions.MustOverride()
|
||||
}
|
||||
}
|
||||
|
||||
class RecordSet
|
||||
{
|
||||
_currentRow := 0 ; Row
|
||||
|
||||
__delete() {
|
||||
this.Close()
|
||||
}
|
||||
|
||||
AddNew(){
|
||||
throw Exceptions.MustOverride()
|
||||
}
|
||||
|
||||
MoveNext(){
|
||||
throw Exceptions.MustOverride()
|
||||
}
|
||||
|
||||
Delete(){
|
||||
throw Exceptions.MustOverride()
|
||||
}
|
||||
|
||||
Update(){
|
||||
throw Exceptions.MustOverride()
|
||||
}
|
||||
|
||||
Close(){
|
||||
throw Exceptions.MustOverride()
|
||||
}
|
||||
|
||||
getEOF(){
|
||||
throw Exceptions.MustOverride()
|
||||
}
|
||||
|
||||
IsValid(){
|
||||
throw Exceptions.MustOverride()
|
||||
}
|
||||
|
||||
getColumnNames(){
|
||||
throw Exceptions.MustOverride()
|
||||
}
|
||||
|
||||
getCurrentRow(){
|
||||
return this._currentRow
|
||||
}
|
||||
|
||||
__Get(param){
|
||||
|
||||
if(IsObject(param)){
|
||||
throw Exception("Expected Index or Column Name!",-1)
|
||||
}
|
||||
|
||||
if(param = "EOF")
|
||||
return this.getEOF()
|
||||
|
||||
|
||||
if(!IsObjectMember(this, param) && param != "_currentRow"){
|
||||
|
||||
if(!is(this._currentRow, DBA.Row))
|
||||
return ""
|
||||
|
||||
;// assume memberaccess are the column names/indexes
|
||||
return this._currentRow[param]
|
||||
}
|
||||
}
|
||||
}
|
||||
36
Lib/DataBaseFactory.ahk
Normal file
36
Lib/DataBaseFactory.ahk
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
class DataBaseFactory
|
||||
{
|
||||
static AvaiableTypes := ["SQLite", "MySQL", "ADO"]
|
||||
|
||||
/*
|
||||
This static Method returns an Instance of an DataBase derived Object
|
||||
*/
|
||||
OpenDataBase(dbType, connectionString){
|
||||
if(dbType = "SQLite")
|
||||
{
|
||||
OutputDebug, Open Database of known type [%dbType%]
|
||||
SQLite_Startup()
|
||||
;//parse connection string. for now assume its a path to the requested DB
|
||||
handle := SQLite_OpenDB(connectionString)
|
||||
|
||||
if(handle == 0)
|
||||
throw Exception("SQLite: The connection to the the given Datebase could not be etablished. Is the following SQLite connection string valid?`n`n" connectionString,-1)
|
||||
return new DBA.DataBaseSQLLite(handle)
|
||||
|
||||
} if(dbType = "MySQL") {
|
||||
OutputDebug, Open Database of known type [%dbType%]
|
||||
MySQL_StartUp()
|
||||
conData := MySQL_CreateConnectionData(connectionString)
|
||||
return new DBA.DataBaseMySQL(conData)
|
||||
} if(dbType = "ADO") {
|
||||
OutputDebug, Open Database of known type [%dbType%]
|
||||
return new DBA.DataBaseADO(connectionString)
|
||||
} else {
|
||||
throw Exception("The given Database Type is unknown! [" . dbType "]",-1)
|
||||
}
|
||||
}
|
||||
|
||||
__New(){
|
||||
throw Exception("This is a static class, dont instante it!",-1)
|
||||
}
|
||||
}
|
||||
249
Lib/DataBaseMySQL.ahk
Normal file
249
Lib/DataBaseMySQL.ahk
Normal file
|
|
@ -0,0 +1,249 @@
|
|||
;namespace DBA
|
||||
|
||||
/*
|
||||
Represents a Connection to a SQLite Database
|
||||
*/
|
||||
class DataBaseMySQL extends DBA.DataBase
|
||||
{
|
||||
_handleDB := 0
|
||||
_connectionData := []
|
||||
|
||||
__New(connectionData){
|
||||
if(!IsObject(connectionData))
|
||||
throw Exception("Expected connectionData Array!")
|
||||
this._connectionData := connectionData
|
||||
|
||||
this.Connect()
|
||||
}
|
||||
|
||||
/*
|
||||
(Re) Connects to the db with the given creditals
|
||||
*/
|
||||
Connect(){
|
||||
connectionData := this._connectionData
|
||||
|
||||
if(!connectionData.Port){
|
||||
dbHandle := MySQL_Connect(connectionData.Server, connectionData.Uid, connectionData.Pwd, connectionData.Database)
|
||||
} else {
|
||||
dbHandle := MySQL_Connect(connectionData.Server, connectionData.Uid, connectionData.Pwd, connectionData.Database, connectionData.Port)
|
||||
}
|
||||
this._handleDB := dbHandle
|
||||
}
|
||||
|
||||
Close(){
|
||||
/*
|
||||
ToDo!
|
||||
*/
|
||||
}
|
||||
|
||||
IsValid(){
|
||||
return (this._handleDB != 0)
|
||||
}
|
||||
|
||||
GetLastError(){
|
||||
return MySQL_GetLastErrorNo(this._handleDB)
|
||||
}
|
||||
|
||||
GetLastErrorMsg(){
|
||||
return MySQL_GetLastErrorMsg(this._handleDB)
|
||||
}
|
||||
|
||||
SetTimeout(timeout = 1000){
|
||||
/*
|
||||
todo
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
ErrMsg() {
|
||||
return DllCall("libmySQL.dll\mysql_error", "UInt", this._handleDB, "AStr")
|
||||
}
|
||||
|
||||
ErrCode() {
|
||||
return DllCall("libmySQL.dll\mysql_errno", "UInt", this._handleDB) ; "Cdecl UInt"
|
||||
}
|
||||
|
||||
Changes() {
|
||||
/*
|
||||
ToDo
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Querys the DB and returns a RecordSet
|
||||
*/
|
||||
OpenRecordSet(sql, editable = false){
|
||||
|
||||
result := MySQL_Query(this._handleDB, sql)
|
||||
|
||||
if (result != 0) {
|
||||
errCode := this.ErrCode()
|
||||
if(errCode == 2003 || errCode == 2006 || errCode == 0){ ;// we've lost the connection
|
||||
;// try reconnect
|
||||
this.Connect()
|
||||
result := MySQL_Query(this._handleDB, sql)
|
||||
if (result != 0)
|
||||
throw new Exception(BuildMySQLErrorStr(this._handleDB, "Query failed because of lost connection. Reconnect failed too." errCode, sql), -1)
|
||||
} else {
|
||||
throw new Exception(BuildMySQLErrorStr(this._handleDB, "Query Failed Error " errCode, sql), -1)
|
||||
}
|
||||
}
|
||||
|
||||
requestResult := MySQL_Use_Result(this._handleDB)
|
||||
if(!requestResult)
|
||||
return false
|
||||
|
||||
return new DBA.RecordSetMySQL(this._handleDB, requestResult)
|
||||
}
|
||||
|
||||
/*
|
||||
Querys the DB and returns a ResultTable or true/false
|
||||
*/
|
||||
Query(sql){
|
||||
return this._GetTableObj(sql)
|
||||
}
|
||||
|
||||
EscapeString(str){
|
||||
return Mysql_escape_string(str)
|
||||
}
|
||||
|
||||
QuoteIdentifier(identifier) {
|
||||
; ` characters are actually valid. Technically everthing but a literal null U+0000.
|
||||
; Everything else is fair game: http://dev.mysql.com/doc/refman/5.0/en/identifiers.html
|
||||
StringReplace, identifier, identifier, ``, ````, All
|
||||
return "``" identifier "``"
|
||||
}
|
||||
|
||||
BeginTransaction(){
|
||||
this.Query("START TRANSACTION;")
|
||||
}
|
||||
|
||||
EndTransaction(){
|
||||
this.Query("COMMIT;")
|
||||
}
|
||||
|
||||
Rollback(){
|
||||
this.Query("ROLLBACK;")
|
||||
}
|
||||
|
||||
InsertMany(records, tableName){
|
||||
|
||||
if(!is(records, Collection) || records.IsEmpty())
|
||||
return false
|
||||
|
||||
sql := "INSERT INTO " tableName "`n"
|
||||
colString := ""
|
||||
|
||||
for column, value in records.First()
|
||||
{
|
||||
colstring .= this.QuoteIdentifier(column) ","
|
||||
}
|
||||
StringTrimRight, colstring, colstring, 1
|
||||
sql .= "(" colstring ")`nVALUES`n"
|
||||
|
||||
for each, record in records
|
||||
{
|
||||
valString := ""
|
||||
for column, value in record
|
||||
{
|
||||
valString .= this.ToSqlLiteral(value) ","
|
||||
}
|
||||
StringTrimRight, valString, valString, 1
|
||||
sql .= "(" valString "),`n"
|
||||
}
|
||||
StringTrimRight, colstring, colstring, 1
|
||||
sql := Trim(sql," `t`r`n,") ";"
|
||||
|
||||
;FileAppend,`n---------`n%sql%`n, dba_sql.log
|
||||
return this.Query(sql)
|
||||
}
|
||||
|
||||
|
||||
Insert(record, tableName){
|
||||
records := new Collection()
|
||||
records.Add(record)
|
||||
return this.InsertMany(records, tableName)
|
||||
}
|
||||
|
||||
Update(fields, constraints, tableName, safe = True) {
|
||||
if (safe) ;limitation: information_schema doesn't work with temp tables
|
||||
for k, row in this.Query("SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE COLUMN_KEY = 'PRI' AND TABLE_NAME = " this.ToSqlLiteral(tableName)).Rows
|
||||
if (!constraints.HasKey(row[1]))
|
||||
return -1 ; error handling....
|
||||
|
||||
WHERE := ""
|
||||
for col, val in constraints
|
||||
WHERE .= ", " this.QuoteIdentifier(col) " = " this.ToSqlLiteral(val)
|
||||
WHERE := SubStr(WHERE, 3)
|
||||
|
||||
SET := ""
|
||||
for col, val in fields
|
||||
SET .= "AND " this.QuoteIdentifier(col) " = " this.EscapeString(val)
|
||||
SET := SubStr(SET, 5)
|
||||
|
||||
query := "UPDATE " this.QuoteIdentifier(tableName) " SET " SET " WHERE " WHERE
|
||||
return db.Query(query)
|
||||
}
|
||||
|
||||
_GetTableObj(sql, maxResult = -1) {
|
||||
|
||||
result := MySQL_Query(this._handleDB, sql)
|
||||
|
||||
/*
|
||||
* Instant reconnect attempt
|
||||
*/
|
||||
if (result != 0) {
|
||||
errCode := this.ErrCode()
|
||||
if(errCode == 2003 || errCode == 2006 || errCode == 0){ ;// we've lost the connection
|
||||
;// try reconnect
|
||||
this.Connect()
|
||||
result := MySQL_Query(this._handleDB, sql)
|
||||
if (result != 0)
|
||||
throw new Exception(BuildMySQLErrorStr(this._handleDB, "Query failed because of lost connection. Reconnect failed too." errCode, sql), -1)
|
||||
} else {
|
||||
throw new Exception(BuildMySQLErrorStr(this._handleDB, "Query Failed Error " errCode, sql), -1)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
requestResult := MySql_Store_Result(this._handleDB)
|
||||
|
||||
if (!requestResult) ; the query was a non {SELECT, SHOW, DESCRIBE, EXPLAIN or CHECK TABLE} statement which doesn't yield any resultset
|
||||
return
|
||||
|
||||
mysqlFields := MySQL_fetch_fields(requestResult)
|
||||
colNames := new Collection()
|
||||
columnCount := 0
|
||||
for each, mysqlField in mysqlFields
|
||||
{
|
||||
colNames.Add(mysqlField.Name())
|
||||
columnCount++
|
||||
}
|
||||
|
||||
rowptr := 0
|
||||
myRows := new Collection()
|
||||
while((rowptr := MySQL_fetch_row(requestResult)))
|
||||
{
|
||||
rowIndex := A_Index
|
||||
datafields := new Collection()
|
||||
|
||||
lengths := MySQL_fetch_lengths(requestResult)
|
||||
Loop, % columnCount
|
||||
{
|
||||
length := GetUIntAtAddress(lengths, A_Index - 1)
|
||||
fieldPointer := GetPtrAtAddress(rowptr, A_Index - 1)
|
||||
if (fieldPointer != 0) ; "NULL values in the row are indicated by NULL pointers." See http://dev.mysql.com/doc/refman/5.0/en/mysql-fetch-row.html
|
||||
fieldValue := StrGet(fieldPointer, length, "CP0")
|
||||
else
|
||||
fieldValue := "" ; Should use DBA.DataBase.NULL from database-types branch?
|
||||
datafields.Add(fieldValue)
|
||||
}
|
||||
myRows.Add(new DBA.Row(colNames, datafields))
|
||||
}
|
||||
MySQL_free_result(requestResult)
|
||||
|
||||
tbl := new DBA.Table(myRows, colNames)
|
||||
return tbl
|
||||
}
|
||||
}
|
||||
310
Lib/DataBaseSQLLite.ahk
Normal file
310
Lib/DataBaseSQLLite.ahk
Normal file
|
|
@ -0,0 +1,310 @@
|
|||
|
||||
; namespace DBA
|
||||
|
||||
class SQLite
|
||||
{
|
||||
GetVersion(){
|
||||
return SQLite_LibVersion()
|
||||
}
|
||||
|
||||
SQLiteExe(dbFile, commands, ByRef output){
|
||||
return SQLite_SQLiteExe(dbFile, commands, output)
|
||||
}
|
||||
|
||||
__New(){
|
||||
throw Exception("This is a static Class. Don't create Instances from it!",-1)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Represents a Connection to a SQLite Database
|
||||
*/
|
||||
class DataBaseSQLLite extends DBA.DataBase
|
||||
{
|
||||
_handleDB := 0
|
||||
|
||||
__New(handleDB){
|
||||
this._handleDB := handleDB
|
||||
if(!this.IsValid())
|
||||
{
|
||||
throw Exception("Can not create a DataBaseSQLLite instance, because the connection handle is not valid!")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Close(){
|
||||
return SQLite_CloseDB(this._handleDB)
|
||||
}
|
||||
|
||||
IsValid(){
|
||||
return (this._handleDB != 0)
|
||||
}
|
||||
|
||||
GetLastError(){
|
||||
code := 0
|
||||
SQLite_ErrCode(this._handleDB, code)
|
||||
return code
|
||||
}
|
||||
|
||||
GetLastErrorMsg(){
|
||||
msg := ""
|
||||
SQLite_ErrMsg(this._handleDB, msg)
|
||||
return msg
|
||||
}
|
||||
|
||||
SetTimeout(timeout = 1000){
|
||||
return SQLite_SetTimeout(this._handleDB, timeout)
|
||||
}
|
||||
|
||||
|
||||
ErrMsg() {
|
||||
if (RC := DllCall("SQLite3\sqlite3_errmsg", "UInt", this._handleDB, "Cdecl UInt"))
|
||||
return StrGet(RC, "UTF-8")
|
||||
return ""
|
||||
}
|
||||
|
||||
ErrCode() {
|
||||
return DllCall("SQLite3\sqlite3_errcode", "UInt", this._handleDB, "Cdecl UInt")
|
||||
}
|
||||
|
||||
Changes() {
|
||||
return DllCall("SQLite3\sqlite3_changes", "UInt", this._handleDB, "Cdecl UInt")
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Querys the DB and returns a RecordSet
|
||||
*/
|
||||
OpenRecordSet(sql, editable = false){
|
||||
return new DBA.RecordSetSqlLite(this, SQlite_Query(this._handleDB, sql))
|
||||
}
|
||||
|
||||
/*
|
||||
Querys the DB and returns a ResultTable or true/false
|
||||
*/
|
||||
Query(sql){
|
||||
|
||||
ret := null
|
||||
|
||||
if (RegExMatch(sql, "i)^\s*SELECT\s")){ ; check if this is a selection query
|
||||
|
||||
try
|
||||
{
|
||||
ret := this._GetTableObj(sql)
|
||||
} catch e
|
||||
throw Exception("Select Query failed.`n`n" sql "`n`nChild Exception:`n" e.What "`n" e.Message "`n" e.File "@" e.Line, -1)
|
||||
} else {
|
||||
|
||||
try
|
||||
{
|
||||
ret := SQLite_Exec(this._handleDB, sql)
|
||||
} catch e
|
||||
throw Exception("Non Selection Query failed.`n`n" sql "`n`nChild Exception:`n" e.What " `n" e.Message, -1)
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
EscapeString(str){
|
||||
StringReplace, str, str, ', '', All ; replace all single quotes with double single-quotes. pascal escape'
|
||||
return str
|
||||
}
|
||||
|
||||
QuoteIdentifier(identifier) {
|
||||
; ` characters are actually valid. Technically everthing but a literal null U+0000.
|
||||
; Everything else is fair game: http://dev.mysql.com/doc/refman/5.0/en/identifiers.html
|
||||
StringReplace, identifier, identifier, ``, ````, All
|
||||
return "``" identifier "``"
|
||||
}
|
||||
|
||||
|
||||
BeginTransaction(){
|
||||
this.Query("BEGIN TRANSACTION;")
|
||||
}
|
||||
|
||||
EndTransaction(){
|
||||
this.Query("COMMIT TRANSACTION;")
|
||||
}
|
||||
|
||||
Rollback(){
|
||||
this.Query("ROLLBACK TRANSACTION;")
|
||||
}
|
||||
|
||||
InsertMany(records, tableName){
|
||||
if(!is(records, Collection) || records.IsEmpty())
|
||||
return false
|
||||
|
||||
colString := ""
|
||||
valString := ""
|
||||
columns := {}
|
||||
|
||||
for column, value in records.First()
|
||||
{
|
||||
colString .= "," this.QuoteIdentifier(column)
|
||||
valString .= ",?"
|
||||
columns[column] := A_Index
|
||||
}
|
||||
sql := "INSERT INTO " this.QuoteIdentifier(tableName) "`n(" SubStr(colstring, 2) ")`nVALUES`n(" SubStr(valString, 2) ")"
|
||||
|
||||
types := []
|
||||
for i,row in this._GetTableObj("PRAGMA table_info(" this.QuoteIdentifier(tableName) ")").Rows
|
||||
{
|
||||
if columns.HasKey(row.name)
|
||||
types[columns[row.name]] := row.types
|
||||
}
|
||||
|
||||
this.BeginTransaction()
|
||||
|
||||
query := SQLite_Query(this._handleDB, sql) ;prepare the query
|
||||
if ErrorLevel
|
||||
msgbox % errorlevel
|
||||
|
||||
try
|
||||
{
|
||||
for i, record in records
|
||||
{
|
||||
for col, val in record
|
||||
{
|
||||
if (!columns.HasKey(col) || !types.HasKey(columns[col]))
|
||||
throw "Irregular params"
|
||||
SQLite_bind(query, columns[col], val, types[columns[col]])
|
||||
}
|
||||
SQLite_Step(query)
|
||||
SQLite_Reset(query)
|
||||
}
|
||||
}
|
||||
catch e
|
||||
{
|
||||
this.Rollback()
|
||||
throw Exception("InsertMany failed.`n`nChild Exception:`n" e.What " `n" e.Message, -1)
|
||||
}
|
||||
SQLite_QueryFinalize(query)
|
||||
this.EndTransaction()
|
||||
return True
|
||||
}
|
||||
|
||||
Insert(record, tableName){
|
||||
col := new Collection()
|
||||
col.Add(record)
|
||||
return this.InsertMany(col, tableName)
|
||||
}
|
||||
|
||||
|
||||
|
||||
_GetTableObj(sql, maxResult = -1) {
|
||||
|
||||
err := 0, rc := 0, GetRows := 0
|
||||
i := 0
|
||||
rows := cols := 0
|
||||
names := new Collection()
|
||||
dbh := this._handleDB
|
||||
|
||||
SQLite_LastError(" ")
|
||||
|
||||
if(!_SQLite_CheckDB(dbh)) {
|
||||
SQLite_LastError("ERROR: Invalid database handle " . dbh)
|
||||
ErrorLevel := _SQLite_ReturnCode("SQLITE_ERROR")
|
||||
return False
|
||||
}
|
||||
if maxResult Is Not Integer
|
||||
maxResult := -1
|
||||
if (maxResult < -1)
|
||||
maxResult := -1
|
||||
mytable := ""
|
||||
Err := 0
|
||||
|
||||
_SQLite_StrToUTF8(SQL, UTF8)
|
||||
RC := DllCall("SQlite3\sqlite3_get_table", "Ptr", dbh, "Ptr", &UTF8, "Ptr*", mytable
|
||||
, "Ptr*", rows, "Ptr*", cols, "Ptr*", err, "Cdecl Int")
|
||||
If (ErrorLevel) {
|
||||
SQLite_LastError("ERROR: DLLCall sqlite3_get_table failed!")
|
||||
Return False
|
||||
}
|
||||
If (rc) {
|
||||
SQLite_LastError(StrGet(err, "UTF-8"))
|
||||
DllCall("SQLite3\sqlite3_free", "Ptr", err, "cdecl")
|
||||
ErrorLevel := rc
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (maxResult = 0) {
|
||||
DllCall("SQLite3\sqlite3_free_table", "Ptr", mytable, "Cdecl")
|
||||
If (ErrorLevel) {
|
||||
SQLite_LastError("ERROR: DLLCall sqlite3_close failed!")
|
||||
Return False
|
||||
}
|
||||
Return True
|
||||
}
|
||||
|
||||
if (maxResult = 1)
|
||||
GetRows := 0
|
||||
else if (maxResult > 1) && (maxResult < rows)
|
||||
GetRows := MaxResult
|
||||
else
|
||||
GetRows := rows
|
||||
Offset := 0
|
||||
|
||||
Loop, % cols
|
||||
{
|
||||
names.Add(StrGet(NumGet(mytable+0, Offset), "UTF-8"))
|
||||
Offset += A_PtrSize
|
||||
}
|
||||
|
||||
myRows := new Collection()
|
||||
Loop, %GetRows% {
|
||||
i := A_Index
|
||||
fields := new Collection()
|
||||
Loop, % Cols
|
||||
{
|
||||
fields.Add(StrGet(NumGet(mytable+0, Offset), "UTF-8"))
|
||||
Offset += A_PtrSize
|
||||
}
|
||||
myRows.Add(new DBA.Row(Names, fields))
|
||||
}
|
||||
tbl := new DBA.Table(myRows, Names)
|
||||
|
||||
; Free Results Memory
|
||||
DllCall("SQLite3\sqlite3_free_table", "Ptr", mytable, "Cdecl")
|
||||
if (ErrorLevel) {
|
||||
SQLite_LastError("ERROR: DLLCall sqlite3_close failed!")
|
||||
return false
|
||||
}
|
||||
return tbl
|
||||
}
|
||||
|
||||
|
||||
ReturnCode(RC) {
|
||||
static RCODE := {SQLITE_OK: 0 ; Successful result
|
||||
, SQLITE_ERROR: 1 ; SQL error or missing database
|
||||
, SQLITE_INTERNAL: 2 ; NOT USED. Internal logic error in SQLite
|
||||
, SQLITE_PERM: 3 ; Access permission denied
|
||||
, SQLITE_ABORT: 4 ; Callback routine requested an abort
|
||||
, SQLITE_BUSY: 5 ; The database file is locked
|
||||
, SQLITE_LOCKED: 6 ; A table in the database is locked
|
||||
, SQLITE_NOMEM: 7 ; A malloc() failed
|
||||
, SQLITE_READONLY: 8 ; Attempt to write a readonly database
|
||||
, SQLITE_INTERRUPT: 9 ; Operation terminated by sqlite3_interrupt()
|
||||
, SQLITE_IOERR: 10 ; Some kind of disk I/O error occurred
|
||||
, SQLITE_CORRUPT: 11 ; The database disk image is malformed
|
||||
, SQLITE_NOTFOUND: 12 ; NOT USED. Table or record not found
|
||||
, SQLITE_FULL: 13 ; Insertion failed because database is full
|
||||
, SQLITE_CANTOPEN: 14 ; Unable to open the database file
|
||||
, SQLITE_PROTOCOL: 15 ; NOT USED. Database lock protocol error
|
||||
, SQLITE_EMPTY: 16 ; Database is empty
|
||||
, SQLITE_SCHEMA: 17 ; The database schema changed
|
||||
, SQLITE_TOOBIG: 18 ; String or BLOB exceeds size limit
|
||||
, SQLITE_CONSTRAINT: 19 ; Abort due to constraint violation
|
||||
, SQLITE_MISMATCH: 20 ; Data type mismatch
|
||||
, SQLITE_MISUSE: 21 ; Library used incorrectly
|
||||
, SQLITE_NOLFS: 22 ; Uses OS features not supported on host
|
||||
, SQLITE_AUTH: 23 ; Authorization denied
|
||||
, SQLITE_FORMAT: 24 ; Auxiliary database format error
|
||||
, SQLITE_RANGE: 25 ; 2nd parameter to sqlite3_bind out of range
|
||||
, SQLITE_NOTADB: 26 ; File opened that is not a database file
|
||||
, SQLITE_ROW: 100 ; sqlite3_step() has another row ready
|
||||
, SQLITE_DONE: 101} ; sqlite3_step() has finished executing
|
||||
return RCODE.HasKey(RC) ? RCODE[RC] : ""
|
||||
}
|
||||
}
|
||||
415
Lib/Notify.ahk
Normal file
415
Lib/Notify.ahk
Normal file
|
|
@ -0,0 +1,415 @@
|
|||
;——————————————————————————————————————————————————————
|
||||
;———————— Notify() 0.4991 by gwarble ————————
|
||||
;————— —————
|
||||
;——— easy multiple tray area notifications ———
|
||||
;—— http://www.autohotkey.net/~gwarble/Notify/ ——
|
||||
;——————————————————————————————————————————————————————
|
||||
;
|
||||
; Notify([Title,Message,Duration,Options])
|
||||
;
|
||||
; Duration seconds to show notification [Default: 30]
|
||||
; 0 for permanent/remain until clicked (flashing)
|
||||
; -3 negative value to ExitApp on click/timeout
|
||||
; "-0" for permanent and ExitApp when clicked (needs "")
|
||||
;
|
||||
; Options string of options, single-space seperated, ie:
|
||||
; "TS=16 TM=8 TF=Times New Roman GC_=Blue SI_=1000"
|
||||
; most options are remembered (static), some not (local)
|
||||
; Option_= can be used for non-static call, ie:
|
||||
; "GC=Blue" makes all future blue, "GC_=Blue" only takes effect once
|
||||
; "Wait=ID" to wait for a notification
|
||||
; "Update=ID" to change Title, Message, and Progress Bar (with 'Duration')
|
||||
;
|
||||
; Return ID (Gui Number used)
|
||||
; 0 if failed (too many open most likely)
|
||||
; VarValue if Options includes: Return=VarName
|
||||
;——————————————————————————————————————————————————————
|
||||
|
||||
Notify(Title="Notify()",Message="",Duration="",Options="")
|
||||
{
|
||||
static GNList, ACList, ATList, AXList, Exit, _Wallpaper_, _Title_, _Message_, _Progress_, _Image_, Saved
|
||||
static GF := 50 ; Gui First Number
|
||||
static GL := 74 ; Gui Last Number (which defines range and allowed count)
|
||||
static GC,GR,GT,BC,BK,BW,BR,BT,BF ; static options, remembered between calls
|
||||
static TS,TW,TC,TF,MS,MW,MC,MF
|
||||
static SI,SC,ST,IW,IH,IN,XC,XS,XW,PC,PB
|
||||
|
||||
If (Options) ; skip parsing steps if Options param isn't used
|
||||
{
|
||||
If (A_AutoTrim = "Off")
|
||||
{
|
||||
AutoTrim, On
|
||||
_AutoTrim = 1
|
||||
} ; ¶
|
||||
Options = %Options%
|
||||
Options.=" " ; poor whitespace handling for next parsing step (ensures last option is parsed)
|
||||
Loop,Parse,Options,= ; parse options string at "="s, needs better whitespace handling
|
||||
{
|
||||
If A_Index = 1 ; first option handling
|
||||
Option := A_LoopField ; sets options VarName
|
||||
Else ; for the rest after the first,
|
||||
{ ; split at the last space, apply the first chunk to the VarValue for the last Option
|
||||
%Option% := SubStr(A_LoopField, 1, (pos := InStr(A_LoopField, A_Space, false, 0))-1)
|
||||
%Option% = % %Option%
|
||||
Option := SubStr(A_LoopField, pos+1) ; and set the next option to the last chunk (from the last space to the "=")
|
||||
}
|
||||
}
|
||||
If _AutoTrim
|
||||
AutoTrim, Off
|
||||
If Wait <> ; option Wait=ID used, normal Notify window not being created
|
||||
{
|
||||
If Wait Is Number ; waits for a specific notify
|
||||
{
|
||||
Gui %Wait%:+LastFound ; i'd like to remove this to not affect calling script...
|
||||
If NotifyGuiID := WinExist() ; but think i have to use hWnd's for reference instead of gui numbers which will
|
||||
{ ; probably happen in my AHK_L transition since gui numbers won't matter anymore
|
||||
WinWaitClose, , , % Abs(Duration) ; wait to close for duration
|
||||
If (ErrorLevel && Duration < 1) ; destroys window when done waiting if duration is negative
|
||||
{ ; otherwise lets the calling script procede after waiting the duration (without destroying)
|
||||
Gui, % Wait + GL - GF + 1 ":Destroy" ; destroys border gui
|
||||
If ST
|
||||
DllCall("AnimateWindow","UInt",NotifyGuiID,"Int",ST,"UInt","0x00050001") ; slides window out to the right if ST or SC are used
|
||||
Gui, %Wait%:Destroy ; and destroys it
|
||||
}
|
||||
}
|
||||
}
|
||||
Else ; wait for all notify's if "Wait=All" is used in the options string
|
||||
{ ; loops through all existing notify's and performs the same wait logic
|
||||
Loop, % GL-GF ; (with or without destroying if negative or not)
|
||||
{
|
||||
Wait := A_Index + GF - 1
|
||||
Gui %Wait%:+LastFound
|
||||
If NotifyGuiID := WinExist()
|
||||
{
|
||||
WinWaitClose, , , % Abs(Duration)
|
||||
If (ErrorLevel && Duration < 1)
|
||||
{
|
||||
Gui, % Wait + GL - GF + 1 ":Destroy" ; destroys border gui
|
||||
If ST
|
||||
DllCall("AnimateWindow","UInt",NotifyGuiID,"Int",ST,"UInt","0x00050001") ; slides window out to the right if ST or SC are used
|
||||
Gui, %Wait%:Destroy ; and destroys it
|
||||
}
|
||||
}
|
||||
}
|
||||
GNList := ACList := ATList := AXList := "" ; clears internal variables since they're all destroyed now
|
||||
}
|
||||
Return
|
||||
}
|
||||
If Update <> ; option "Update=ID" being used, Notify window will not be created
|
||||
{ ; title, message, image and progress position can be updated
|
||||
If Title <>
|
||||
GuiControl, %Update%:,_Title_,%Title%
|
||||
If Message <>
|
||||
GuiControl, %Update%:,_Message_,%Message%
|
||||
If Duration <>
|
||||
GuiControl, %Update%:,_Progress_,%Duration%
|
||||
If Image <>
|
||||
GuiControl, %Update%:,_Image_,%Image%
|
||||
If Wallpaper <>
|
||||
GuiControl, %Update%:,_Wallpaper_,%Image%
|
||||
Return
|
||||
}
|
||||
If Style = Save ; option "Style=Save" is used to save the existing window style
|
||||
{ ; and call it back later with "Style=Load"
|
||||
Saved := Options " GC=" GC " GR=" GR " GT=" GT " BC=" BC " BK=" BK " BW=" BW " BR=" BR " BT=" BT " BF=" BF
|
||||
Saved .= " TS=" TS " TW=" TW " TC=" TC " TF=" TF " MS=" MS " MW=" MW " MC=" MC " MF=" MF
|
||||
Saved .= " IW=" IW " IH=" IH " IN=" IN " PW=" PW " PH=" PH " PC=" PC " PB=" PB " XC=" XC " XS=" MS " XW=" XW
|
||||
Saved .= " SI=" SI " SC=" SC " ST=" ST " WF=" Image " IF=" IF
|
||||
} ; this needs some major improvement to have multiple saved instead of just one, otherwise pointless
|
||||
If Return <>
|
||||
Return, % (%Return%)
|
||||
If Style <> ; option "Style=Default will reset all variables back to defaults... except options also specified
|
||||
{ ; so "Style=Default GC=Blue" is allowed, which will reset all defaults and then set GC=Blue
|
||||
If Style = Default
|
||||
Return % Notify(Title,Message,Duration, ; maybe handled poorly by calling itself, but it saves having to have the defaults set in two areas... thoughts?
|
||||
(
|
||||
"GC= GR= GT= BC= BK= BW= BR= BT= BF= TS= TW= TC= TF=
|
||||
MS= MW= MC= MF= SI= ST= SC= IW=
|
||||
IH= IN= XC= XS= XW= PC= PB= " Options "Style=")
|
||||
) ; below are more internally saved styles, which may move to an auxiliary function at some point, but could use some improvement
|
||||
Else If Style = ToolTip
|
||||
Return % Notify(Title,Message,Duration,"SI=50 GC=FFFFAA BC=00000 GR=0 BR=0 BW=1 BT=255 TS=8 MS=8 " Options "Style=")
|
||||
Else If Style = BalloonTip
|
||||
Return % Notify(Title,Message,Duration,"SI=350 GC=FFFFAA BC=00000 GR=13 BR=15 BW=1 BT=255 TS=10 MS=8 AX=1 XC=999922 IN=8 Image=" A_WinDir "\explorer.exe " Options "Style=")
|
||||
Else If Style = Error
|
||||
Return % Notify(Title,Message,Duration,"SI=250 GC=Default BC=00000 GR=0 BR=0 BW=1 BT=255 TS=12 MS=12 AX=1 XC=666666 IN=10 IW=32 IH=32 Image=" A_WinDir "\explorer.exe " Options "Style=")
|
||||
Else If Style = Warning
|
||||
Return % Notify(Title,Message,Duration,"SI=250 GC=Default BC=00000 GR=0 BR=0 BW=1 BT=255 TS=12 MS=12 AX=1 XC=666666 IN=9 IW=32 IH=32 Image=" A_WinDir "\explorer.exe " Options "Style=")
|
||||
Else If Style = Info
|
||||
Return % Notify(Title,Message,Duration,"SI=250 GC=Default BC=00000 GR=0 BR=0 BW=1 BT=255 TS=12 MS=12 AX=1 XC=666666 IN=8 IW=32 IH=32 Image=" A_WinDir "\explorer.exe " Options "Style=")
|
||||
Else If Style = Question
|
||||
Return % Notify(Title,Message,Duration,"SI=250 GC=Default BC=00000 GR=0 BR=0 BW=1 BT=255 TS=12 MS=12 AX=1 XC=666666 Image=24 IW=32 IH=32 " Options "Style=")
|
||||
Else If Style = Progress
|
||||
Return % Notify(Title,Message,Duration,"SI=100 GC=Default BC=00000 GR=9 BR=13 BW=2 BT=105 TS=10 MS=10 PG=100 PH=10 GW=300 " Options "Style=")
|
||||
Else If Style = Huge
|
||||
Return % Notify(Title,Message,Duration,"SI=100 ST=200 SC=200 GC=FFFFAA BC=00000 GR=27 BR=39 BW=6 BT=105 TS=24 MS=22 " Options "Style=")
|
||||
Else If Style = Load
|
||||
Return % Notify(Title,Message,Duration,Saved)
|
||||
}
|
||||
}
|
||||
;—————— end if options ————————————————————————————————————————————————————————————————————————————
|
||||
|
||||
GC_ := GC_<>"" ? GC_ : GC := GC<>"" ? GC : "FFFFAA" ; defaults are set here, and static overrides are used and saved
|
||||
GR_ := GR_<>"" ? GR_ : GR := GR<>"" ? GR : 9 ; and non static options (with OP_=) are used but not saved
|
||||
GT_ := GT_<>"" ? GT_ : GT := GT<>"" ? GT : "Off"
|
||||
BC_ := BC_<>"" ? BC_ : BC := BC<>"" ? BC : "000000"
|
||||
BK_ := BK_<>"" ? BK_ : BK := BK<>"" ? BK : "Silver"
|
||||
BW_ := BW_<>"" ? BW_ : BW := BW<>"" ? BW : 2
|
||||
BR_ := BR_<>"" ? BR_ : BR := BR<>"" ? BR : 13
|
||||
BT_ := BT_<>"" ? BT_ : BT := BT<>"" ? BT : 105
|
||||
BF_ := BF_<>"" ? BF_ : BF := BF<>"" ? BF : 350
|
||||
TS_ := TS_<>"" ? TS_ : TS := TS<>"" ? TS : 10
|
||||
TW_ := TW_<>"" ? TW_ : TW := TW<>"" ? TW : 625
|
||||
TC_ := TC_<>"" ? TC_ : TC := TC<>"" ? TC : "Default"
|
||||
TF_ := TF_<>"" ? TF_ : TF := TF<>"" ? TF : "Default"
|
||||
MS_ := MS_<>"" ? MS_ : MS := MS<>"" ? MS : 10
|
||||
MW_ := MW_<>"" ? MW_ : MW := MW<>"" ? MW : "Default"
|
||||
MC_ := MC_<>"" ? MC_ : MC := MC<>"" ? MC : "Default"
|
||||
MF_ := MF_<>"" ? MF_ : MF := MF<>"" ? MF : "Default"
|
||||
SI_ := SI_<>"" ? SI_ : SI := SI<>"" ? SI : 0
|
||||
SC_ := SC_<>"" ? SC_ : SC := SC<>"" ? SC : 0
|
||||
ST_ := ST_<>"" ? ST_ : ST := ST<>"" ? ST : 0
|
||||
IW_ := IW_<>"" ? IW_ : IW := IW<>"" ? IW : 32
|
||||
IH_ := IH_<>"" ? IH_ : IH := IH<>"" ? IH : 32
|
||||
IN_ := IN_<>"" ? IN_ : IN := IN<>"" ? IN : 0
|
||||
XF_ := XF_<>"" ? XF_ : XF := XF<>"" ? XF : "Arial Black"
|
||||
XC_ := XC_<>"" ? XC_ : XC := XC<>"" ? XC : "Default"
|
||||
XS_ := XS_<>"" ? XS_ : XS := XS<>"" ? XS : 12
|
||||
XW_ := XW_<>"" ? XW_ : XW := XW<>"" ? XW : 800
|
||||
PC_ := PC_<>"" ? PC_ : PC := PC<>"" ? PC : "Default"
|
||||
PB_ := PB_<>"" ? PB_ : PB := PB<>"" ? PB : "Default"
|
||||
|
||||
wPW := ((PW<>"") ? ("w" PW) : ("")) ; needs improvement, poor handling of explicit sizes and progress widths
|
||||
hPH := ((PH<>"") ? ("h" PH) : (""))
|
||||
If GW <>
|
||||
{
|
||||
wGW = w%GW%
|
||||
wPW := "w" GW - 20
|
||||
}
|
||||
hGH := ((GH<>"") ? ("h" GH) : (""))
|
||||
wGW_ := ((GW<>"") ? ("w" GW - 20) : (""))
|
||||
hGH_ := ((GH<>"") ? ("h" GH - 20) : (""))
|
||||
;————————————————————————————————————————————————————————————————————————
|
||||
If Duration = ; default if duration is not used or set to ""
|
||||
Duration = 30
|
||||
GN := GF ; find the next available gui number to use, starting from GF (default 50)
|
||||
Loop ; within the defined range GF to GL
|
||||
IfNotInString, GNList, % "|" GN
|
||||
Break
|
||||
Else
|
||||
If (++GN > GL) ;=== too many notifications open, returns 0, handle this error in the calling script
|
||||
Return 0 ; this is uncommon as the screen is too cluttered by this point anyway
|
||||
GNList .= "|" GN
|
||||
GN2 := GN + GL - GF + 1
|
||||
|
||||
If AC <> ; saves the action to be used when clicked or timeout (or x-button is clicked)
|
||||
ACList .= "|" GN "=" AC ; need to add different clicks for Title, Message, Image as well
|
||||
If AT <> ; saved internally in a list, then parsed by the timer or click routine
|
||||
ATList .= "|" GN "=" AT ; to run the script-side subroutine/label "AC=LabelName"
|
||||
If AX <>
|
||||
AXList .= "|" GN "=" AX
|
||||
|
||||
|
||||
P_DHW := A_DetectHiddenWindows ; start finding location based on what other Notify() windows are on the screen
|
||||
P_TMM := A_TitleMatchMode ; saved to restore these settings after changing them, so the calling script won't know
|
||||
DetectHiddenWindows On ; as they are needed to find all as they are being made as well... or hidden for some reason...
|
||||
SetTitleMatchMode 1 ; and specific window title match is a little more failsafe
|
||||
If (WinExist("_Notify()_GUI_")) ;=== find all Notifications from ALL scripts, for placement
|
||||
WinGetPos, OtherX, OtherY ;=== change this to a loop for all open notifications and find the highest?
|
||||
DetectHiddenWindows %P_DHW% ;=== using the last Notify() made at this point, which may be better
|
||||
SetTitleMatchMode %P_TMM% ; and the global settings are restored for the calling thread
|
||||
|
||||
Gui, %GN%:-Caption +ToolWindow +AlwaysOnTop -Border ; here begins the creation of the window
|
||||
Gui, %GN%:Color, %GC_% ; with the logic to add or not add certain controls, Wallpaper, Image, Title, Progress, Message
|
||||
If FileExist(WP) ; and some placement logic depending if they are used or not... could definitely be improved
|
||||
{
|
||||
Gui, %GN%:Add, Picture, x0 y0 w0 h0 v_Wallpaper_, % WP ; wallpaper added first, stretched to size later
|
||||
ImageOptions = x+8 y+4
|
||||
}
|
||||
If Image <> ; icon image added next, sized, and spacing added for whats next
|
||||
{
|
||||
If FileExist(Image)
|
||||
Gui, %GN%:Add, Picture, w%IW_% h%IH_% Icon%IN_% v_Image_ %ImageOptions%, % Image
|
||||
Else
|
||||
Gui, %GN%:Add, Picture, w%IW_% h%IH_% Icon%Image% v_Image_ %ImageOptions%, %A_WinDir%\system32\shell32.dll
|
||||
ImageOptions = x+10
|
||||
}
|
||||
If Title <> ; title text control added next, if used
|
||||
{
|
||||
Gui, %GN%:Font, w%TW_% s%TS_% c%TC_%, %TF_%
|
||||
Gui, %GN%:Add, Text, %ImageOptions% BackgroundTrans v_Title_, % Title
|
||||
}
|
||||
If PG ; then the progress bar, if called for
|
||||
Gui, %GN%:Add, Progress, Range0-%PG% %wPW% %hPH% c%PC_% Background%PB_% v_Progress_
|
||||
Else
|
||||
If ((Title) && (Message)) ; some spacing tweaks if both used
|
||||
Gui, %GN%:Margin, , -5
|
||||
If Message <> ; and finally the message text control if used
|
||||
{
|
||||
Gui, %GN%:Font, w%MW_% s%MS_% c%MC_%, %MF_%
|
||||
Gui, %GN%:Add, Text, BackgroundTrans v_Message_, % Message
|
||||
}
|
||||
If ((Title) && (Message)) ; final spacing
|
||||
Gui, %GN%:Margin, , 8
|
||||
Gui, %GN%:Show, Hide %wGW% %hGH%, _Notify()_GUI_ ; final sizing
|
||||
Gui %GN%:+LastFound ; would like to get rid of this to prevent calling script being affected
|
||||
WinGetPos, GX, GY, GW, GH ; final positioning
|
||||
GuiControl, %GN%:, _Wallpaper_, % "*w" GW " *h" GH " " WP ; stretch that wallpaper to size
|
||||
GuiControl, %GN%:MoveDraw, _Title_, % "w" GW-20 " h" GH-10 ; poor handling of text wrapping when gui has explicit size called
|
||||
GuiControl, %GN%:MoveDraw, _Message_, % "w" GW-20 " h" GH-10 ; needs improvement (and if image is used or not)
|
||||
If AX <> ; add the corner "X" for closing with a different action than otherwise clicked
|
||||
{
|
||||
GW += 10
|
||||
Gui, %GN%:Font, w%XW_% s%XS_% c%XC_%, Arial Black ; × (multiply) is the character used for the X-Button
|
||||
Gui, %GN%:Add, Text, % "x" GW-15 " y-2 Center w12 h20 g_Notify_Kill_" GN - GF + 1, % chr(0x00D7) ;××
|
||||
}
|
||||
Gui, %GN%:Add, Text, x0 y0 w%GW% h%GH% BackgroundTrans g_Notify_Action_Clicked_ ; to catch clicks anywhere on the gui
|
||||
If (GR_) ; may have to be removed for seperate title/message/etc actions
|
||||
WinSet, Region, % "0-0 w" GW " h" GH " R" GR_ "-" GR_
|
||||
If (GT_) ; non-functioning GT option, since the border gui gets in the way
|
||||
WinSet, Transparent, % GT_ ; will be addressed someday, leaving it in
|
||||
|
||||
SysGet, Workspace, MonitorWorkArea ; positioning
|
||||
NewX := WorkSpaceRight-GW-5
|
||||
If (OtherY)
|
||||
NewY := OtherY-GH-2-BW_*2
|
||||
Else
|
||||
NewY := WorkspaceBottom-GH-5
|
||||
If NewY < % WorkspaceTop
|
||||
NewY := WorkspaceBottom-GH-5
|
||||
|
||||
Gui, %GN2%:-Caption +ToolWindow +AlwaysOnTop -Border +E0x20 ; border gui
|
||||
Gui, %GN2%:Color, %BC_%
|
||||
Gui %GN2%:+LastFound
|
||||
If (BR_)
|
||||
WinSet, Region, % "0-0 w" GW+(BW_*2) " h" GH+(BW_*2) " R" BR_ "-" BR_
|
||||
If (BT_)
|
||||
WinSet, Transparent, % BT_
|
||||
|
||||
Gui, %GN2%:Show, % "Hide x" NewX-BW_ " y" NewY-BW_ " w" GW+(BW_*2) " h" GH+(BW_*2), _Notify()_BGGUI_ ; actual creation of border gui! but still not shown
|
||||
Gui, %GN%:Show, % "Hide x" NewX " y" NewY " w" GW, _Notify()_GUI_ ; actual creation of Notify() gui! but still not shown
|
||||
Gui %GN%:+LastFound ; need to get rid of this so calling script isn't affected
|
||||
If SI_
|
||||
DllCall("AnimateWindow","UInt",WinExist(),"Int",SI_,"UInt","0x00040008") ; animated in, if SI is used
|
||||
Else
|
||||
Gui, %GN%:Show, NA, _Notify()_GUI_ ; otherwise, just shown
|
||||
Gui, %GN2%:Show, NA, _Notify()_BGGUI_ ; and the border shown
|
||||
WinSet, AlwaysOnTop, On ; and set to Always on Top
|
||||
|
||||
If ((Duration < 0) OR (Duration = "-0")) ; saves internally that ExitApp should happen when this
|
||||
Exit := GN ; notify dissappears
|
||||
If (Duration)
|
||||
SetTimer, % "_Notify_Kill_" GN - GF + 1, % - Abs(Duration) * 1000 ; timer set depending on Duration parameter
|
||||
Else
|
||||
SetTimer, % "_Notify_Flash_" GN - GF + 1, % BF_ ; timer set to flash border if the Notify has 0 (infinite) duration
|
||||
|
||||
Return %GN% ; end of Notify(), returns Gui ID number used
|
||||
|
||||
;==========================================================================
|
||||
;========================================== when a notification is clicked:
|
||||
_Notify_Action_Clicked_: ; option AC=Label means Label: subroutine will be called here when clicked
|
||||
; Critical
|
||||
SetTimer, % "_Notify_Kill_" A_Gui - GF + 1, Off
|
||||
Gui, % A_Gui + GL - GF + 1 ":Destroy"
|
||||
If SC
|
||||
{
|
||||
Gui, %A_Gui%:+LastFound
|
||||
DllCall("AnimateWindow","UInt",WinExist(),"Int",SC,"UInt", "0x00050001")
|
||||
}
|
||||
Gui, %A_Gui%:Destroy
|
||||
If (ACList)
|
||||
Loop,Parse,ACList,|
|
||||
If ((Action := SubStr(A_LoopField,1,2)) = A_Gui)
|
||||
{
|
||||
Temp_Notify_Action:= SubStr(A_LoopField,4)
|
||||
StringReplace, ACList, ACList, % "|" A_Gui "=" Temp_Notify_Action, , All
|
||||
If IsLabel(_Notify_Action := Temp_Notify_Action)
|
||||
Gosub, %_Notify_Action%
|
||||
_Notify_Action =
|
||||
Break
|
||||
}
|
||||
StringReplace, GNList, GNList, % "|" A_Gui, , All
|
||||
SetTimer, % "_Notify_Flash_" A_Gui - GF + 1, Off
|
||||
If (Exit = A_Gui)
|
||||
ExitApp
|
||||
Return
|
||||
|
||||
;==========================================================================
|
||||
;=========================================== when a notification times out:
|
||||
_Notify_Kill_1:
|
||||
_Notify_Kill_2: ; this needs a different method, too many labels
|
||||
_Notify_Kill_3: ; they are used for Timers, different for each Notify() based on duration...
|
||||
_Notify_Kill_4:
|
||||
_Notify_Kill_5:
|
||||
_Notify_Kill_6:
|
||||
_Notify_Kill_7:
|
||||
_Notify_Kill_8:
|
||||
_Notify_Kill_9:
|
||||
_Notify_Kill_10:
|
||||
_Notify_Kill_11:
|
||||
_Notify_Kill_12:
|
||||
_Notify_Kill_13:
|
||||
_Notify_Kill_14:
|
||||
_Notify_Kill_15:
|
||||
_Notify_Kill_16:
|
||||
_Notify_Kill_17:
|
||||
_Notify_Kill_18:
|
||||
_Notify_Kill_19:
|
||||
_Notify_Kill_20:
|
||||
_Notify_Kill_21:
|
||||
_Notify_Kill_22:
|
||||
_Notify_Kill_23:
|
||||
_Notify_Kill_24:
|
||||
_Notify_Kill_25:
|
||||
Critical
|
||||
StringReplace, GK, A_ThisLabel, _Notify_Kill_
|
||||
SetTimer, _Notify_Flash_%GK%, Off
|
||||
GK := GK + GF - 1
|
||||
Gui, % GK + GL - GF + 1 ":Destroy"
|
||||
If ST
|
||||
{
|
||||
Gui, %GK%:+LastFound
|
||||
DllCall("AnimateWindow","UInt",WinExist(),"Int",ST,"UInt", "0x00050001")
|
||||
}
|
||||
Gui, %GK%:Destroy
|
||||
StringReplace, GNList, GNList, % "|" GK, , All
|
||||
If (Exit = GK)
|
||||
ExitApp
|
||||
Return 1
|
||||
|
||||
;==========================================================================
|
||||
;======================================== flashes a permanent notification:
|
||||
_Notify_Flash_1:
|
||||
_Notify_Flash_2:
|
||||
_Notify_Flash_3:
|
||||
_Notify_Flash_4: ; this needs a different method, too many labels
|
||||
_Notify_Flash_5: ; they are used for Timers, different for each Notify() based on flash speed...
|
||||
_Notify_Flash_6: ; when duration is 0 (infinite)
|
||||
_Notify_Flash_7: ; this may feature may be removed completely, Update given the ability to affect GC and BC
|
||||
_Notify_Flash_8: ; and then the flashing could be handled script-side via returned gui number and a script-side timer
|
||||
_Notify_Flash_9:
|
||||
_Notify_Flash_10:
|
||||
_Notify_Flash_11:
|
||||
_Notify_Flash_12:
|
||||
_Notify_Flash_13:
|
||||
_Notify_Flash_14:
|
||||
_Notify_Flash_15:
|
||||
_Notify_Flash_16:
|
||||
_Notify_Flash_17:
|
||||
_Notify_Flash_18:
|
||||
_Notify_Flash_19:
|
||||
_Notify_Flash_20:
|
||||
_Notify_Flash_21:
|
||||
_Notify_Flash_22:
|
||||
_Notify_Flash_23:
|
||||
_Notify_Flash_24:
|
||||
_Notify_Flash_25:
|
||||
StringReplace, FlashGN, A_ThisLabel, _Notify_Flash_
|
||||
FlashGN += GF - 1
|
||||
FlashGN2 := FlashGN + GL - GF + 1
|
||||
If Flashed%FlashGN2% := !Flashed%FlashGN2%
|
||||
Gui, %FlashGN2%:Color, %BK%
|
||||
Else
|
||||
Gui, %FlashGN2%:Color, %BC%
|
||||
Return
|
||||
}
|
||||
109
Lib/RecordSetADO.ahk
Normal file
109
Lib/RecordSetADO.ahk
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
;namespace DBA
|
||||
|
||||
/*
|
||||
Represents a result set of ADO
|
||||
http://www.w3schools.com/ado/ado_ref_recordset.asp
|
||||
*/
|
||||
class RecordSetADO extends DBA.RecordSet
|
||||
{
|
||||
_adoRS := 0 ; ado recordset
|
||||
|
||||
__New(sql, adoConnection, editable = false){
|
||||
this._adoRS := ComObjCreate("ADODB.Recordset")
|
||||
if(editable)
|
||||
this._adoRS.Open(sql, adoConnection, ADO.CursorType.adOpenKeyset, ADO.LockType.adLockOptimistic, ADO.CommandType.adCmdTable)
|
||||
else
|
||||
this._adoRS.Open(sql, adoConnection)
|
||||
}
|
||||
|
||||
/*
|
||||
Is this RecordSet valid?
|
||||
*/
|
||||
IsValid(){
|
||||
return (IsObject(this._adoRS))
|
||||
}
|
||||
|
||||
/*
|
||||
Returns an Array with all Column Names
|
||||
*/
|
||||
getColumnNames(){
|
||||
|
||||
colNames := new Collection()
|
||||
|
||||
for adoField in this._adoRS.Fields
|
||||
colNames.add(adoField.Name)
|
||||
|
||||
return colNames
|
||||
}
|
||||
|
||||
getEOF(){
|
||||
return this._adoRS.EOF
|
||||
}
|
||||
|
||||
AddNew(){
|
||||
if(this.IsValid())
|
||||
{
|
||||
this._adoRS.AddNew()
|
||||
}
|
||||
}
|
||||
|
||||
MoveNext() {
|
||||
if(this.IsValid())
|
||||
{
|
||||
this._adoRS.MoveNext()
|
||||
}
|
||||
}
|
||||
|
||||
Delete(){
|
||||
if(this.IsValid() && !this.getEOF())
|
||||
{
|
||||
this._adoRS.Delete(ADO.AffectEnum.adAffectCurrent)
|
||||
}
|
||||
}
|
||||
|
||||
Update(){
|
||||
if(this.IsValid() && !this.getEOF())
|
||||
{
|
||||
this._adoRS.Update()
|
||||
}
|
||||
}
|
||||
|
||||
Reset() {
|
||||
if(this.IsValid()){
|
||||
this._adoRS.MoveFirst()
|
||||
}
|
||||
}
|
||||
|
||||
Count(){
|
||||
cnt := 0
|
||||
if(this.IsValid())
|
||||
cnt := this._adoRS.RecordCount
|
||||
return cnt
|
||||
}
|
||||
|
||||
|
||||
Close() {
|
||||
if(this.IsValid())
|
||||
this._adoRS.Close()
|
||||
}
|
||||
|
||||
|
||||
__Get(param){
|
||||
|
||||
if(IsObject(param)){
|
||||
throw Exception("Expected Index or Column Name!",-1)
|
||||
}
|
||||
|
||||
if(param = "EOF")
|
||||
return this.getEOF()
|
||||
|
||||
if(!IsObjectMember(this, param) && param != "_currentRow"){
|
||||
if(this.IsValid())
|
||||
{
|
||||
df := this._adoRS.Fields[param]
|
||||
return df.Value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
109
Lib/RecordSetMySQL.ahk
Normal file
109
Lib/RecordSetMySQL.ahk
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
;namespace DBA
|
||||
|
||||
/*
|
||||
Represents a result set of an MySQL Query
|
||||
*/
|
||||
class RecordSetMySQL extends DBA.RecordSet
|
||||
{
|
||||
_colNames := 0 ; Collection<ColumnNames>
|
||||
_colCount := 0
|
||||
_query := 0 ; ptr to Resultset/Query
|
||||
_db := 0 ; ptr to DataBase
|
||||
_eof := false ; bool
|
||||
CurrentRow := 0 ; int - row number
|
||||
|
||||
|
||||
__New(db, requestResult){
|
||||
this._db := db
|
||||
this._query := requestResult
|
||||
|
||||
if(this._query != 0){
|
||||
this._colNames := this.getColumnNames()
|
||||
this.MoveNext()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Is this RecordSet valid?
|
||||
*/
|
||||
IsValid(){
|
||||
return (this._query != 0)
|
||||
}
|
||||
|
||||
/*
|
||||
Returns an Array with all Column Names
|
||||
*/
|
||||
getColumnNames(){
|
||||
mysqlFields := MySQL_fetch_fields(this._query)
|
||||
colNames := new Collection()
|
||||
i := 0
|
||||
for each, mysqlField in mysqlFields
|
||||
{
|
||||
colNames.Add(mysqlField.Name())
|
||||
i++
|
||||
}
|
||||
this._colCount := i
|
||||
return colNames
|
||||
}
|
||||
|
||||
getEOF(){
|
||||
return this._eof
|
||||
}
|
||||
|
||||
|
||||
MoveNext() {
|
||||
static EOR := -1
|
||||
this.ErrorMsg := ""
|
||||
this.ErrorCode := 0
|
||||
this._currentRow := 0
|
||||
|
||||
if (!this._query) {
|
||||
this.ErrorMsg := "Invalid query handle!"
|
||||
this._eof := true
|
||||
return false
|
||||
}
|
||||
|
||||
rowptr := MySQL_fetch_row(this._query)
|
||||
if (!rowptr){
|
||||
; // we reached eof
|
||||
this.ErrorMsg := "RecordSet is empty! (eof)"
|
||||
this.ErrorCode := 1
|
||||
this._eof := true
|
||||
return false
|
||||
}
|
||||
|
||||
lengths := MySQL_fetch_lengths(this._query)
|
||||
datafields := new Collection()
|
||||
Loop % this._colCount
|
||||
{
|
||||
length := GetUIntAtAddress(lengths, A_Index - 1)
|
||||
fieldPointer := GetPtrAtAddress(rowptr, A_Index - 1)
|
||||
fieldValue := StrGet(fieldPointer, length, "CP0")
|
||||
datafields.Add(fieldValue)
|
||||
}
|
||||
this._currentRow := new DBA.Row(this._colNames, datafields)
|
||||
this.CurrentRow++
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reset() {
|
||||
throw Exception("Not Supported!",-1)
|
||||
}
|
||||
|
||||
|
||||
Close() {
|
||||
this.ErrorMsg := ""
|
||||
this.ErrorCode := 0
|
||||
if(this._query == 0)
|
||||
return true
|
||||
|
||||
MySQL_free_result(this._query)
|
||||
|
||||
this._query := 0
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
139
Lib/RecordSetSqlLite.ahk
Normal file
139
Lib/RecordSetSqlLite.ahk
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
;namespace DBA
|
||||
|
||||
/*
|
||||
Represents a result set of an SQLite Query
|
||||
*/
|
||||
class RecordSetSqlLite extends DBA.RecordSet
|
||||
{
|
||||
_currentRow := 0 ; Row
|
||||
_colNames := 0 ; Collection<ColumnNames>
|
||||
_query := 0 ; int Handle to the Query
|
||||
_db := 0 ; SQLiteDataBase
|
||||
_eof := false ; bool
|
||||
|
||||
/*
|
||||
Is this RecordSet valid?
|
||||
*/
|
||||
IsValid(){
|
||||
return (this._query != 0)
|
||||
}
|
||||
|
||||
/*
|
||||
Returns an Array with all Column Names
|
||||
*/
|
||||
getColumnNames(){
|
||||
SQLite_FetchNames(this._query, names)
|
||||
return new Collection(names)
|
||||
}
|
||||
|
||||
getEOF(){
|
||||
return this._eof
|
||||
}
|
||||
|
||||
|
||||
MoveNext() {
|
||||
static SQLITE_NULL := 5
|
||||
static EOR := -1
|
||||
|
||||
this.ErrorMsg := ""
|
||||
this.ErrorCode := 0
|
||||
this._currentRow := 0
|
||||
|
||||
if (!this._query) {
|
||||
this.ErrorMsg := "Invalid query handle!"
|
||||
this._eof := true
|
||||
return false
|
||||
}
|
||||
rc := DllCall("SQlite3\sqlite3_step", "UInt", this._query, "Cdecl Int")
|
||||
|
||||
if (rc != this._db.ReturnCode("SQLITE_ROW")) {
|
||||
if (rc = this._db.ReturnCode("SQLITE_DONE")) {
|
||||
this.ErrorMsg := "EOR"
|
||||
this.ErrorCode := rc
|
||||
this._eof := true
|
||||
return EOR
|
||||
}
|
||||
this.ErrorMessage := This._db.ErrMsg()
|
||||
this.ErrorCode := rc
|
||||
this._eof := true
|
||||
return false
|
||||
}
|
||||
rc := DllCall("SQlite3\sqlite3_data_count", "UInt", this._query, "Cdecl Int")
|
||||
|
||||
if (rc < 1) {
|
||||
this.ErrorMsg := "RecordSet is empty!"
|
||||
this.ErrorCode := this._db.ReturnCode("SQLITE_EMPTY")
|
||||
this._eof := true
|
||||
return false
|
||||
}
|
||||
|
||||
; fill the internal row structure
|
||||
;_currentRow := new Row()
|
||||
fields := new Collection()
|
||||
Loop, %rc% {
|
||||
ctype := DllCall("SQlite3\sqlite3_column_type", "UInt", this._query, "Int", A_Index - 1, "Cdecl Int")
|
||||
if (ctype == SQLITE_NULL) {
|
||||
fields[A_Index] := ""
|
||||
} else {
|
||||
strPtr := DllCall("SQlite3\sqlite3_column_text", "UInt", this._query, "Int", A_Index - 1, "Cdecl UInt")
|
||||
fields[A_Index] := StrGet(strPtr, "UTF-8")
|
||||
}
|
||||
}
|
||||
this._currentRow := new DBA.Row(this._colNames, fields)
|
||||
this.CurrentRow++
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reset() {
|
||||
this.ErrorMsg := ""
|
||||
this.ErrorCode := 0
|
||||
|
||||
if (!this._query) {
|
||||
this.ErrorMsg := "Invalid query handle!"
|
||||
return false
|
||||
}
|
||||
rc := DllCall("SQlite3\sqlite3_reset", "UInt", this._query, "Cdecl Int")
|
||||
|
||||
if (rc) {
|
||||
this.ErrorMsg := This._db.ErrMsg()
|
||||
this.ErrorCode := rc
|
||||
return false
|
||||
}
|
||||
this.CurrentRow := 0
|
||||
this.MoveNext()
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
Close() {
|
||||
this.ErrorMsg := ""
|
||||
this.ErrorCode := 0
|
||||
if(this._query == 0)
|
||||
return true
|
||||
|
||||
rc := DllCall("SQlite3\sqlite3_finalize", "UInt", this._query, "Cdecl Int")
|
||||
|
||||
if (rc) {
|
||||
this.ErrorMsg := this._db.ErrMsg()
|
||||
this.ErrorCode := rc
|
||||
return false
|
||||
}
|
||||
this._query := 0
|
||||
return true
|
||||
}
|
||||
|
||||
__New(db, query){
|
||||
if(!is(db, DBA.DataBaseSQLLite)){
|
||||
throw Exception("db must be a DataBaseSQLLite Object",-1)
|
||||
}
|
||||
this._db := db
|
||||
this._query := query
|
||||
if(query != 0){
|
||||
this._colNames := this.getColumnNames()
|
||||
this.MoveNext()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
1044
Lib/SQLite_L.ahk
Normal file
1044
Lib/SQLite_L.ahk
Normal file
File diff suppressed because it is too large
Load Diff
1
Lib/clean.bat
Normal file
1
Lib/clean.bat
Normal file
|
|
@ -0,0 +1 @@
|
|||
del *.bak
|
||||
15
Lib/license.txt
Normal file
15
Lib/license.txt
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
AHK DBA - OOP Database Access Framework
|
||||
Copyright (C) 2012 IsNull and other contributors
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
431
Lib/mySQL.ahk
Normal file
431
Lib/mySQL.ahk
Normal file
|
|
@ -0,0 +1,431 @@
|
|||
/*============================================================
|
||||
mysql.ahk
|
||||
Provides a set of functions to connect and query a mysql database
|
||||
|
||||
Based upon the published lib of panofish
|
||||
http://www.autohotkey.com/forum/topic67280.html
|
||||
|
||||
|
||||
Offical Documentation of the C-API
|
||||
http://dev.mysql.com/doc/refman/5.0/en/c.html
|
||||
============================================================
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
Parses the given Connectionstring to a ConnectionData
|
||||
|
||||
An typical Connectionstring looks like:
|
||||
Server=myServerAddress;Port=1234;Database=myDataBase;Uid=myUsername;Pwd=myPassword;
|
||||
|
||||
Further Info: http://www.connectionstrings.com/mysql
|
||||
*/
|
||||
MySQL_CreateConnectionData(connectionString){
|
||||
connectionData := {}
|
||||
StringSplit, connstr, connectionString, `;
|
||||
Loop, % connstr0
|
||||
{
|
||||
StringSplit, segment, connstr%a_index%, =
|
||||
connectionData[segment1] := segment2
|
||||
}
|
||||
return connectionData
|
||||
}
|
||||
|
||||
|
||||
|
||||
MySQL_StartUp(){
|
||||
global MySQL_ExternDir
|
||||
MySQL_ExternDir := A_WorkingDir
|
||||
|
||||
libDllpath := MySQL_DLLPath()
|
||||
|
||||
if(!FileExist(libDllpath))
|
||||
{
|
||||
msg := "MySQL Libaray not found!`n" libDllpath " (file missing)"
|
||||
OutputDebug, %msg%
|
||||
throw Exception(msg,-1)
|
||||
}
|
||||
|
||||
|
||||
hModule := DllCall("LoadLibrary", "Str", libDllpath)
|
||||
|
||||
if (hModule == 0)
|
||||
{
|
||||
msg := "LoadLibrary failed, can't load module:`n" libDllpath
|
||||
OutputDebug, %msg%
|
||||
throw Exception(msg, -1)
|
||||
}else
|
||||
return hModule
|
||||
}
|
||||
|
||||
MySQL_DLLPath(forcedPath = "") {
|
||||
static DLLPath := ""
|
||||
static dllname := "libmySQL.dll"
|
||||
|
||||
if(DLLPath == ""){
|
||||
; search the dll
|
||||
prefix := (A_PtrSize == 8) ? "x64\" : ""
|
||||
dllpath := prefix . dllname
|
||||
|
||||
if (FileExist(A_ScriptDir . "\" . dllpath))
|
||||
DLLPath := A_ScriptDir . "\" . dllpath
|
||||
else
|
||||
DLLPath := A_ScriptDir . "\Lib\" . dllpath
|
||||
}
|
||||
|
||||
if (forcedPath != "")
|
||||
DLLPath := forcedPath
|
||||
|
||||
return DLLPath
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************
|
||||
Connect to mysql database and return db handle
|
||||
|
||||
host:
|
||||
user:
|
||||
password:
|
||||
database:
|
||||
port: 3306(default)
|
||||
******************************************************************
|
||||
*/
|
||||
MySQL_Connect(host, user, password, database, port = 3306){
|
||||
|
||||
|
||||
db := DllCall("libmySQL.dll\mysql_init", "ptr", 0)
|
||||
|
||||
if (db = 0)
|
||||
throw Exception("MySQL Error 445, Not enough memory to connect to MySQL", -1)
|
||||
|
||||
connection := DllCall("libmySQL.dll\mysql_real_connect"
|
||||
, "ptr", db
|
||||
, "AStr", host ; host name
|
||||
, "AStr", user ; user name
|
||||
, "AStr", password ; password
|
||||
, "AStr", database ; database name
|
||||
, "UInt", port ; port
|
||||
, "UInt", 0 ; unix_socket
|
||||
, "UInt", 0) ; client_flag
|
||||
|
||||
If (connection == 0)
|
||||
throw Exception(BuildMySQLErrorStr(db, "Cannot connect to database"), -1)
|
||||
|
||||
;debugging only:
|
||||
;MsgBox % "Ping database: " . MySQL_Ping(db) . "`nServer version: " . MySQL_GetVersion(db)
|
||||
|
||||
return db
|
||||
}
|
||||
|
||||
MySQL_Close(db){
|
||||
DllCall("libmySQL.dll\mysql_close", "ptr", db)
|
||||
}
|
||||
|
||||
|
||||
|
||||
MySQL_GetVersion(db){
|
||||
serverVersion := DllCall("libmySQL.dll\mysql_get_server_info", "ptr", db, "AStr")
|
||||
return serverVersion
|
||||
}
|
||||
MySQL_Ping(db){
|
||||
return DllCall("libmySQL.dll\mysql_ping", "ptr", db)
|
||||
}
|
||||
|
||||
MySQL_GetLastErrorNo(db){
|
||||
return DllCall("libmySQL.dll\mysql_errno", "ptr", db)
|
||||
}
|
||||
|
||||
MySQL_GetLastErrorMsg(db){
|
||||
return DllCall("libmySQL.dll\mysql_error", "ptr", db, "AStr")
|
||||
}
|
||||
|
||||
/*
|
||||
Retrieves a complete result set to the client.
|
||||
*/
|
||||
MySQL_Store_Result(db) {
|
||||
return DllCall("libmySQL.dll\mysql_store_result", "ptr", db)
|
||||
}
|
||||
|
||||
/*
|
||||
Retrieves the resultset row-by-row
|
||||
*/
|
||||
MySQL_Use_Result(db) {
|
||||
return DllCall("libmySQL.dll\mysql_use_result", "ptr", db)
|
||||
}
|
||||
|
||||
/*
|
||||
Returns a requestResult for the given query
|
||||
*/
|
||||
MySQL_Query(db, query){
|
||||
return DllCall("libmySQL.dll\mysql_query", "ptr", db , "AStr", query)
|
||||
}
|
||||
|
||||
MySQL_free_result(requestResult){
|
||||
return DllCall("libmySQL.dll\mysql_free_result", "ptr", requestResult)
|
||||
}
|
||||
|
||||
/*
|
||||
Returns the number of columns in a result set.
|
||||
*/
|
||||
MySQL_num_fields(requestResult) {
|
||||
Return DllCall("libmySQL.dll\mysql_num_fields", "ptr", requestResult)
|
||||
}
|
||||
|
||||
/*
|
||||
Returns the lengths of all columns in the current row.
|
||||
*/
|
||||
MySQL_fetch_lengths(requestResult) {
|
||||
Return , DllCall("libmySQL.dll\mysql_fetch_lengths", "ptr", requestResult)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Fetches the next row from the result set.
|
||||
*/
|
||||
MySQL_fetch_row(requestResult) {
|
||||
Return , DllCall("libmySQL.dll\mysql_fetch_row", "ptr", requestResult)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Fetches given Field
|
||||
*/
|
||||
Mysql_fetch_field_direct(requestResult, fieldnum) {
|
||||
return DllCall("libmySQL.dll\mysql_fetch_field_direct", "ptr", requestResult, "Uint", fieldnum)
|
||||
}
|
||||
|
||||
/*
|
||||
Fetches the next field from the result set.
|
||||
*/
|
||||
Mysql_fetch_field(requestResult) {
|
||||
return DllCall("libmySQL.dll\mysql_fetch_field", "ptr", requestResult)
|
||||
}
|
||||
|
||||
/*
|
||||
Fetches all fields of the resultSet
|
||||
*/
|
||||
MySQL_fetch_fields(requestResult){
|
||||
global MySQL_Field
|
||||
|
||||
fields := []
|
||||
fieldCount := MySQL_num_fields(requestResult)
|
||||
|
||||
Loop, % fieldCount
|
||||
{
|
||||
fptr := Mysql_fetch_field(requestResult)
|
||||
fields[A_index] := new MySQL_Field(fptr)
|
||||
}
|
||||
return fields
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
; mysql error handling
|
||||
*/
|
||||
BuildMySQLErrorStr(db, message, query="") {
|
||||
errorCode := DllCall("libmySQL.dll\mysql_errno", "UInt", db)
|
||||
errorStr := DllCall("libmySQL.dll\mysql_error", "UInt", db, "AStr")
|
||||
Return, "MySQL Error: " message "Error " errorCode ": " errorStr "`n`n" query
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
;============================================================
|
||||
; mysql get address
|
||||
;============================================================
|
||||
|
||||
|
||||
GetUIntAtAddress(_addr, _offset)
|
||||
{
|
||||
return NumGet(_addr+0,_offset * 4, "uint")
|
||||
}
|
||||
|
||||
GetPtrAtAddress(_addr, _offset)
|
||||
{
|
||||
return NumGet(_addr+0,_offset * A_PtrSize, "ptr")
|
||||
}
|
||||
|
||||
|
||||
;============================================================
|
||||
; internal: dump resultset from given Query to string
|
||||
;============================================================
|
||||
__MySQL_Query_Dump(_db, _query)
|
||||
{
|
||||
local resultString, result, requestResult, fieldCount
|
||||
local row, lengths, length, fieldPointer, field
|
||||
|
||||
|
||||
result := DllCall("libmySQL.dll\mysql_query", "UInt", _db , "AStr", _query)
|
||||
|
||||
If (result != 0)
|
||||
throw new Exception(BuildMySQLErrorStr(_db, "dbQuery Fail", RegExReplace(_query , "\t", " ")), -1)
|
||||
|
||||
|
||||
requestResult := MySql_Store_Result(_db)
|
||||
|
||||
if (requestResult = 0) { ; call must have been an insert or delete ... a select would return results to pass back
|
||||
return
|
||||
}
|
||||
|
||||
fieldCount := MySQL_num_fields(requestResult)
|
||||
|
||||
|
||||
myfields := MySQL_fetch_fields(requestResult)
|
||||
for each, fifi in myfields
|
||||
{
|
||||
MsgBox % "name: " fifi.Name() "`n org name: " fifi.OrgName() "`ntable: " fifi.Table() "`norg table: " fifi.OrgTable()
|
||||
}
|
||||
|
||||
Loop
|
||||
{
|
||||
row := MySQL_fetch_row(requestResult)
|
||||
if (!row)
|
||||
break
|
||||
|
||||
; Get a pointer on a table of lengths (unsigned long)
|
||||
lengths := MySQL_fetch_lengths(requestResult)
|
||||
|
||||
Loop %fieldCount%
|
||||
{
|
||||
length := GetUIntAtAddress(lengths, A_Index - 1)
|
||||
fieldPointer := GetPtrAtAddress(row, A_Index - 1)
|
||||
field := StrGet(fieldPointer, length, "CP0")
|
||||
resultString := resultString . field
|
||||
if (A_Index < fieldCount)
|
||||
resultString := resultString . "|" ; seperator for fields
|
||||
}
|
||||
resultString := resultString . "`n" ; seperator for records
|
||||
}
|
||||
MySQL_free_result(requestResult)
|
||||
resultString := RegExReplace(resultString , "`n$", "")
|
||||
|
||||
return resultString
|
||||
}
|
||||
|
||||
|
||||
|
||||
;============================================================
|
||||
; Escape mysql special characters
|
||||
; This must be done to sql insert columns where the characters might contain special characters, such as user input fields
|
||||
;
|
||||
; Escape Sequence Character Represented by Sequence
|
||||
; \' A single quote (“'”) character.
|
||||
; \" A double quote (“"”) character.
|
||||
; \n A newline (linefeed) character.
|
||||
; \r A carriage return character.
|
||||
; \t A tab character.
|
||||
; \\ A backslash (“\”) character.
|
||||
; \% A “%” character. Usually indicates a wildcard character
|
||||
; \_ A “_” character. Usually indicates a wildcard character
|
||||
; \b A backspace character.
|
||||
;
|
||||
; these 2 have not yet been included yet
|
||||
; \Z ASCII 26 (Control+Z). Stands for END-OF-FILE on Windows
|
||||
; \0 An ASCII NUL (0x00) character.
|
||||
;
|
||||
; example call:
|
||||
; description := mysql_escape_string(description)
|
||||
;============================================================
|
||||
|
||||
Mysql_escape_string(unescaped_string)
|
||||
{
|
||||
escaped_string := RegExReplace(unescaped_string, "\\", "\\") ; \
|
||||
escaped_string := RegExReplace(escaped_string, "'", "\'") ; '
|
||||
|
||||
escaped_string := RegExReplace(escaped_string, "`t", "\t") ; \t
|
||||
escaped_string := RegExReplace(escaped_string, "`n", "\n") ; \n
|
||||
escaped_string := RegExReplace(escaped_string, "`r", "\r") ; \r
|
||||
escaped_string := RegExReplace(escaped_string, "`b", "\b") ; \b
|
||||
|
||||
; these characters appear to insert fine in mysql
|
||||
;escaped_string := RegExReplace(escaped_string, "%", "\%") ; %
|
||||
;escaped_string := RegExReplace(escaped_string, "_", "\_") ; _
|
||||
;escaped_string := RegExReplace(escaped_string, """", "\""") ; "
|
||||
|
||||
return escaped_string
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
typedef struct st_mysql_field {
|
||||
char *name; /* Name of column */
|
||||
char *org_name; /* Original column name, if an alias */
|
||||
char *table; /* Table of column if column was a field */
|
||||
char *org_table; /* Org table name, if table was an alias */
|
||||
char *db; /* Database for table */
|
||||
char *catalog; /* Catalog for table */
|
||||
char *def; /* Default value (set by mysql_list_fields) */
|
||||
unsigned long length; /* Width of column (create length) */
|
||||
unsigned long max_length; /* Max width for selected set */
|
||||
unsigned int name_length;
|
||||
unsigned int org_name_length;
|
||||
unsigned int table_length;
|
||||
unsigned int org_table_length;
|
||||
unsigned int db_length;
|
||||
unsigned int catalog_length;
|
||||
unsigned int def_length;
|
||||
unsigned int flags; /* Div flags */
|
||||
unsigned int decimals; /* Number of decimals in field */
|
||||
unsigned int charsetnr; /* Character set */
|
||||
enum enum_field_types type; /* Type of field. See mysql_com.h for types */
|
||||
void *extension;
|
||||
} MYSQL_FIELD;
|
||||
*/
|
||||
|
||||
/*
|
||||
'mysql_port is a long
|
||||
'mysql_unix port is a long (pointer)
|
||||
'sizeof(MYSQL_FIELD)=32
|
||||
Public Type API_MYSQL_FIELD
|
||||
name As Long
|
||||
table As Long
|
||||
def As Long
|
||||
type As API_enum_field_types
|
||||
length As Long
|
||||
max_length As Long
|
||||
flags As Long
|
||||
decimals As Long
|
||||
End Type
|
||||
*/
|
||||
class MySQL_Field
|
||||
{
|
||||
ptr := 0
|
||||
|
||||
__new(ptr){
|
||||
this.ptr := ptr
|
||||
}
|
||||
|
||||
Name(){
|
||||
adr := GetPtrAtAddress(this.ptr, 0)
|
||||
return StrGet(adr, 255, "CP0")
|
||||
}
|
||||
|
||||
OrgName(){
|
||||
adr := GetPtrAtAddress(this.ptr, 4)
|
||||
return StrGet(adr, 255, "CP0")
|
||||
}
|
||||
|
||||
Table(){
|
||||
adr := GetPtrAtAddress(this.ptr, 8)
|
||||
return StrGet(adr, 255, "CP0")
|
||||
}
|
||||
|
||||
OrgTable(){
|
||||
adr := GetPtrAtAddress(this.ptr, 12)
|
||||
return StrGet(adr, 255, "CP0")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
27
Lib/readme.txt
Normal file
27
Lib/readme.txt
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
|
||||
AHK DBA - OOP Database Access Framework for AutoHotkey (_L)
|
||||
|
||||
Currently DBA supports SQLite, MySQL and ADO.
|
||||
|
||||
|
||||
DBA is an object oriented wrapper around several different
|
||||
databases/database providers to standardize the access interface.
|
||||
It is similar to ADO from MS or the jdbc driver in Java.
|
||||
|
||||
|
||||
|
||||
|
||||
Copyright (C) 2012 IsNull and other contributors
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
203
Lib/sqlite3.def
Normal file
203
Lib/sqlite3.def
Normal file
|
|
@ -0,0 +1,203 @@
|
|||
EXPORTS
|
||||
sqlite3_aggregate_context
|
||||
sqlite3_aggregate_count
|
||||
sqlite3_auto_extension
|
||||
sqlite3_backup_finish
|
||||
sqlite3_backup_init
|
||||
sqlite3_backup_pagecount
|
||||
sqlite3_backup_remaining
|
||||
sqlite3_backup_step
|
||||
sqlite3_bind_blob
|
||||
sqlite3_bind_double
|
||||
sqlite3_bind_int
|
||||
sqlite3_bind_int64
|
||||
sqlite3_bind_null
|
||||
sqlite3_bind_parameter_count
|
||||
sqlite3_bind_parameter_index
|
||||
sqlite3_bind_parameter_name
|
||||
sqlite3_bind_text
|
||||
sqlite3_bind_text16
|
||||
sqlite3_bind_value
|
||||
sqlite3_bind_zeroblob
|
||||
sqlite3_blob_bytes
|
||||
sqlite3_blob_close
|
||||
sqlite3_blob_open
|
||||
sqlite3_blob_read
|
||||
sqlite3_blob_reopen
|
||||
sqlite3_blob_write
|
||||
sqlite3_busy_handler
|
||||
sqlite3_busy_timeout
|
||||
sqlite3_changes
|
||||
sqlite3_clear_bindings
|
||||
sqlite3_close
|
||||
sqlite3_collation_needed
|
||||
sqlite3_collation_needed16
|
||||
sqlite3_column_blob
|
||||
sqlite3_column_bytes
|
||||
sqlite3_column_bytes16
|
||||
sqlite3_column_count
|
||||
sqlite3_column_database_name
|
||||
sqlite3_column_database_name16
|
||||
sqlite3_column_decltype
|
||||
sqlite3_column_decltype16
|
||||
sqlite3_column_double
|
||||
sqlite3_column_int
|
||||
sqlite3_column_int64
|
||||
sqlite3_column_name
|
||||
sqlite3_column_name16
|
||||
sqlite3_column_origin_name
|
||||
sqlite3_column_origin_name16
|
||||
sqlite3_column_table_name
|
||||
sqlite3_column_table_name16
|
||||
sqlite3_column_text
|
||||
sqlite3_column_text16
|
||||
sqlite3_column_type
|
||||
sqlite3_column_value
|
||||
sqlite3_commit_hook
|
||||
sqlite3_compileoption_get
|
||||
sqlite3_compileoption_used
|
||||
sqlite3_complete
|
||||
sqlite3_complete16
|
||||
sqlite3_config
|
||||
sqlite3_context_db_handle
|
||||
sqlite3_create_collation
|
||||
sqlite3_create_collation16
|
||||
sqlite3_create_collation_v2
|
||||
sqlite3_create_function
|
||||
sqlite3_create_function16
|
||||
sqlite3_create_function_v2
|
||||
sqlite3_create_module
|
||||
sqlite3_create_module_v2
|
||||
sqlite3_data_count
|
||||
sqlite3_db_config
|
||||
sqlite3_db_filename
|
||||
sqlite3_db_handle
|
||||
sqlite3_db_mutex
|
||||
sqlite3_db_readonly
|
||||
sqlite3_db_release_memory
|
||||
sqlite3_db_status
|
||||
sqlite3_declare_vtab
|
||||
sqlite3_enable_load_extension
|
||||
sqlite3_enable_shared_cache
|
||||
sqlite3_errcode
|
||||
sqlite3_errmsg
|
||||
sqlite3_errmsg16
|
||||
sqlite3_exec
|
||||
sqlite3_expired
|
||||
sqlite3_extended_errcode
|
||||
sqlite3_extended_result_codes
|
||||
sqlite3_file_control
|
||||
sqlite3_finalize
|
||||
sqlite3_free
|
||||
sqlite3_free_table
|
||||
sqlite3_get_autocommit
|
||||
sqlite3_get_auxdata
|
||||
sqlite3_get_table
|
||||
sqlite3_global_recover
|
||||
sqlite3_initialize
|
||||
sqlite3_interrupt
|
||||
sqlite3_last_insert_rowid
|
||||
sqlite3_libversion
|
||||
sqlite3_libversion_number
|
||||
sqlite3_limit
|
||||
sqlite3_load_extension
|
||||
sqlite3_log
|
||||
sqlite3_malloc
|
||||
sqlite3_memory_alarm
|
||||
sqlite3_memory_highwater
|
||||
sqlite3_memory_used
|
||||
sqlite3_mprintf
|
||||
sqlite3_mutex_alloc
|
||||
sqlite3_mutex_enter
|
||||
sqlite3_mutex_free
|
||||
sqlite3_mutex_leave
|
||||
sqlite3_mutex_try
|
||||
sqlite3_next_stmt
|
||||
sqlite3_open
|
||||
sqlite3_open16
|
||||
sqlite3_open_v2
|
||||
sqlite3_os_end
|
||||
sqlite3_os_init
|
||||
sqlite3_overload_function
|
||||
sqlite3_prepare
|
||||
sqlite3_prepare16
|
||||
sqlite3_prepare16_v2
|
||||
sqlite3_prepare_v2
|
||||
sqlite3_profile
|
||||
sqlite3_progress_handler
|
||||
sqlite3_randomness
|
||||
sqlite3_realloc
|
||||
sqlite3_release_memory
|
||||
sqlite3_reset
|
||||
sqlite3_reset_auto_extension
|
||||
sqlite3_result_blob
|
||||
sqlite3_result_double
|
||||
sqlite3_result_error
|
||||
sqlite3_result_error16
|
||||
sqlite3_result_error_code
|
||||
sqlite3_result_error_nomem
|
||||
sqlite3_result_error_toobig
|
||||
sqlite3_result_int
|
||||
sqlite3_result_int64
|
||||
sqlite3_result_null
|
||||
sqlite3_result_text
|
||||
sqlite3_result_text16
|
||||
sqlite3_result_text16be
|
||||
sqlite3_result_text16le
|
||||
sqlite3_result_value
|
||||
sqlite3_result_zeroblob
|
||||
sqlite3_rollback_hook
|
||||
sqlite3_rtree_geometry_callback
|
||||
sqlite3_set_authorizer
|
||||
sqlite3_set_auxdata
|
||||
sqlite3_shutdown
|
||||
sqlite3_sleep
|
||||
sqlite3_snprintf
|
||||
sqlite3_soft_heap_limit
|
||||
sqlite3_soft_heap_limit64
|
||||
sqlite3_sourceid
|
||||
sqlite3_sql
|
||||
sqlite3_status
|
||||
sqlite3_step
|
||||
sqlite3_stmt_busy
|
||||
sqlite3_stmt_readonly
|
||||
sqlite3_stmt_status
|
||||
sqlite3_stricmp
|
||||
sqlite3_strnicmp
|
||||
sqlite3_table_column_metadata
|
||||
sqlite3_test_control
|
||||
sqlite3_thread_cleanup
|
||||
sqlite3_threadsafe
|
||||
sqlite3_total_changes
|
||||
sqlite3_trace
|
||||
sqlite3_transfer_bindings
|
||||
sqlite3_update_hook
|
||||
sqlite3_uri_boolean
|
||||
sqlite3_uri_int64
|
||||
sqlite3_uri_parameter
|
||||
sqlite3_user_data
|
||||
sqlite3_value_blob
|
||||
sqlite3_value_bytes
|
||||
sqlite3_value_bytes16
|
||||
sqlite3_value_double
|
||||
sqlite3_value_int
|
||||
sqlite3_value_int64
|
||||
sqlite3_value_numeric_type
|
||||
sqlite3_value_text
|
||||
sqlite3_value_text16
|
||||
sqlite3_value_text16be
|
||||
sqlite3_value_text16le
|
||||
sqlite3_value_type
|
||||
sqlite3_vfs_find
|
||||
sqlite3_vfs_register
|
||||
sqlite3_vfs_unregister
|
||||
sqlite3_vmprintf
|
||||
sqlite3_vsnprintf
|
||||
sqlite3_vtab_config
|
||||
sqlite3_vtab_on_conflict
|
||||
sqlite3_wal_autocheckpoint
|
||||
sqlite3_wal_checkpoint
|
||||
sqlite3_wal_checkpoint_v2
|
||||
sqlite3_wal_hook
|
||||
sqlite3_win32_mbcs_to_utf8
|
||||
sqlite3_win32_utf8_to_mbcs
|
||||
BIN
Lib/sqlite3.dll
Normal file
BIN
Lib/sqlite3.dll
Normal file
Binary file not shown.
BIN
Lib/x64/sqlite3.dll
Normal file
BIN
Lib/x64/sqlite3.dll
Normal file
Binary file not shown.
43
Main.ahk
Normal file
43
Main.ahk
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
|
||||
;#Warn ; Recommended for catching common errors.
|
||||
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
|
||||
SetWorkingDir, %A_ScriptDir% ; Ensures a consistent starting directory.
|
||||
SetBatchLines -1
|
||||
#SingleInstance force
|
||||
#NoTrayIcon
|
||||
|
||||
/* ===============================================================================
|
||||
* LifeRPG r2 - Motivation and Confidence Building System
|
||||
* Initial Release 9/20/2012
|
||||
*
|
||||
* Copyright (c) 2012 by Jayvant Javier Pujara
|
||||
* Licensed under GPL
|
||||
* JJPujara@gmail.com
|
||||
*
|
||||
*
|
||||
* ===============================================================================
|
||||
*/
|
||||
|
||||
#Include <DBA>
|
||||
#Include Settings.ahk
|
||||
#Include HUD.ahk
|
||||
#Include Momentum.ahk
|
||||
#Include Functions.ahk
|
||||
#Include MenuBar.ahk
|
||||
#Include ProjectsView.ahk
|
||||
#Include Hotkeys.ahk
|
||||
#Include Search.ahk
|
||||
#Include ProjectManage.ahk
|
||||
#Include ProjectRemove.ahk
|
||||
#Include ProjectComplete.ahk
|
||||
#Include SubprojectAdd.ahk
|
||||
#Include SkillsView.ahk
|
||||
#Include ProjectLog.ahk
|
||||
#Include ProfileEdit.ahk
|
||||
#Include SettingsEdit.ahk
|
||||
#Include About.ahk
|
||||
#Include Help.ahk
|
||||
#Include FileManage.ahk
|
||||
|
||||
MenuHandler:
|
||||
return
|
||||
39
MenuBar.ahk
Normal file
39
MenuBar.ahk
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
; Menu Bar: ===================================================================================
|
||||
Gui, 1:Default
|
||||
; File:==========================================
|
||||
Menu, FileMenu, Add, &New...`tCtrl+N, FileNew
|
||||
Menu, FileMenu, Add, &Open...`tCtrl+O, FileOpen
|
||||
|
||||
;~ ; Create another menu destined to become a submenu of the above menu.
|
||||
;~ Menu, Submenu1, Add, Item1, MenuHandler
|
||||
;~ Menu, Submenu1, Add, Item2, MenuHandler
|
||||
;~ ; Create a submenu in the first menu (a right-arrow indicator). When the user selects it, the second menu is displayed.
|
||||
;~ Menu, FileMenu, Add, Recently Opened, :Submenu1
|
||||
|
||||
;~ ^ Leave for later release
|
||||
|
||||
Menu, FileMenu, Add
|
||||
Menu, FileMenu, Add, E&xit, GuiClose
|
||||
|
||||
; View:===========================================
|
||||
Menu, ViewMenu, Add, &Skill Stats...`tCtrl+K, SkillsView
|
||||
Menu, ViewMenu, Add, &Project Log...`tCtrl+L, ProjectLog
|
||||
|
||||
; Options:=========================================
|
||||
Menu, OptionsMenu, Add, &Profile...`tCtrl+P, ProfileEdit
|
||||
Menu, OptionsMenu, Add, &Settings...`tCtrl+S, SettingsEdit
|
||||
|
||||
; Help:===========================================
|
||||
Menu, HelpMenu, Add, &Reference..., ReferenceHotkeys
|
||||
Menu, HelpMenu, Add, &Discussion, Discussion
|
||||
Menu, HelpMenu, Add
|
||||
Menu, HelpMenu, Add, &About, About
|
||||
|
||||
|
||||
; Attach the sub-menus that were created above.
|
||||
Menu, MenuBar, Add, &File, :FileMenu
|
||||
Menu, MenuBar, Add, &View, :ViewMenu
|
||||
Menu, MenuBar, Add, &Options, :OptionsMenu
|
||||
Menu, MenuBar, Add, &Help, :HelpMenu
|
||||
|
||||
Gui, Menu, MenuBar
|
||||
41
Momentum.ahk
Normal file
41
Momentum.ahk
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
; Momentum Bar: ==================================================
|
||||
; Get date momentum bar last updated:
|
||||
MomentumLastUpdate := ProfileGet("MMTLastUpdate")
|
||||
|
||||
MomentumTimer()
|
||||
|
||||
MomentumTimer(){
|
||||
global db, HUD_MomentumBar, HUD_MomentumPerc, MomentumLastUpdate
|
||||
; Start timer to check current date:
|
||||
gosub MomentumUpdate
|
||||
SetTimer, MomentumUpdate, 1000
|
||||
return
|
||||
|
||||
MomentumUpdate:
|
||||
CurrentDate := FormatTime(,"yyyyMMdd")
|
||||
; When current date does not match date momentum bar last updated,
|
||||
if (MomentumLastUpdate <> CurrentDate) ; Momentum bar needs to be lowered:
|
||||
{
|
||||
; Compare both dates to see how long ago in days last update was:
|
||||
DateDiff := CurrentDate
|
||||
DateDiff -= MomentumLastUpdate, Days
|
||||
; Multiply difference in days by percentage loss in MMT bar,
|
||||
MMTLoss := DateDiff * 15
|
||||
; and move MMT down:
|
||||
; Check the database to see what the current momentum level is.
|
||||
MMTCurrent := ProfileGet("momentum")
|
||||
; Calculate current level minus calculated loss.
|
||||
MMTNew := MMTCurrent - MMTLoss
|
||||
; If result is 0 or less than 0, just make the MMT level 0:
|
||||
if (MMTNew <= 0)
|
||||
MMTNew = 0
|
||||
; Update database and HUD momentum bar:
|
||||
db.Query("UPDATE profile SET value = " . MMTNew . " WHERE setting = 'momentum'") ; update momentum value in database
|
||||
db.Query("UPDATE profile SET value = " . CurrentDate . " WHERE setting = 'MMTLastUpdate'") ; update when MMT last updated
|
||||
MMTNow := ProfileGet("momentum")
|
||||
GuiControl, HUD_Momentum:, HUD_MomentumBar, % MMTNow
|
||||
GuiControl, HUD_Momentum:, HUD_MomentumPerc, % MMTNow . "%"
|
||||
MomentumLastUpdate := ProfileGet("MMTLastUpdate")
|
||||
}
|
||||
return
|
||||
}
|
||||
93
OFL.txt
Normal file
93
OFL.txt
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
Copyright (c) 2011, Cyreal (www.cyreal.org),
|
||||
with Reserved Font Name "Electrolize".
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
41
ProfileEdit.ahk
Normal file
41
ProfileEdit.ahk
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
; Edit User Profile:================================================================
|
||||
ProfileEdit:
|
||||
; Initialize modal child GUI window:
|
||||
GuiChildInit("Profile")
|
||||
; Define size and title etc:
|
||||
ProfileW = 230
|
||||
ProfileH = 140
|
||||
ProfileX := CenterX(ProfileW)
|
||||
ProfileY := CenterY(ProfileH)
|
||||
ProfileTitle := "Edit Your Profile"
|
||||
|
||||
; Create content and fields:
|
||||
; Name:
|
||||
Gui, Profile:Add, Text, , Name:
|
||||
Gui, Profile:Add, Edit, vProfileNameEdit w120 Limit21 r1, % ProfileGet("name")
|
||||
; Title:
|
||||
Gui, Profile:Add, Text, , Title:
|
||||
Gui, Profile:Add, Edit, vProfileTitleEdit w200 r1, % ProfileGet("title")
|
||||
; Save button:
|
||||
Gui, Profile:Add, Button, Default y+10 w80 gProfileSubmit, Save
|
||||
; Cancel:
|
||||
Gui, Profile:Add, Button, x+10 w80 gProfileGuiClose, Cancel
|
||||
|
||||
; Show GUI:
|
||||
Gui, Show, w%ProfileW% h%ProfileH% x%ProfileX% y%ProfileY%, %ProfileTitle%
|
||||
; hang out here until user saves or closes:
|
||||
return
|
||||
|
||||
; What do to when user submits:
|
||||
ProfileSubmit:
|
||||
Gui, Profile:Submit, NoHide
|
||||
db.Query("UPDATE profile SET value = '" . SafeQuote(ProfileNameEdit) . "' WHERE setting = 'name'")
|
||||
db.Query("UPDATE profile SET value = '" . SafeQuote(ProfileTitleEdit) . "' WHERE setting = 'title'")
|
||||
GuiControl, HUD_Level:, HUD_Name, % ProfileGet("name")
|
||||
GuiControl, HUD_Level:, HUD_Text, % HUD_LevelText . LevelCheck() . " " . ProfileGet("title")
|
||||
|
||||
; What to do when user closes or escapes window:
|
||||
ProfileGuiClose:
|
||||
ProfileGuiEscape:
|
||||
GuiChildClose("Profile") ; Close up GUI child window.
|
||||
return
|
||||
88
ProjectComplete.ahk
Normal file
88
ProjectComplete.ahk
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
;~ ===============================================================================
|
||||
;~ Confirm Project completion:
|
||||
|
||||
CompleteProject:
|
||||
Selection := LV_GetNext("","F")
|
||||
LV_GetText(SelectedProjectID, Selection, 1)
|
||||
LV_GetText(ProjectCompletionState, Selection, 2)
|
||||
If (SelectedProjectID == "ID" || ProjectCompletionState = "Done")
|
||||
{
|
||||
return
|
||||
}
|
||||
else
|
||||
{
|
||||
GuiMsgBox("CompleteProject", "Complete Project", "Done with project?")
|
||||
return
|
||||
|
||||
CompleteProjectYes:
|
||||
Gui, CompleteProject:Submit, NoHide
|
||||
GuiChildClose("CompleteProject")
|
||||
|
||||
CompleteProject(SelectedProjectID)
|
||||
MomentumPrev := ProfileGet("momentum")
|
||||
if (MomentumPrev < 100)
|
||||
{
|
||||
Anim := 100 - MomentumPrev
|
||||
Loop % Anim
|
||||
{
|
||||
GuiControl, HUD_Momentum:, HUD_MomentumBar, % MomentumPrev + A_Index
|
||||
GuiControl, HUD_Momentum:, HUD_MomentumPerc, % MomentumPrev + A_Index . "%"
|
||||
Sleep 10
|
||||
}
|
||||
ProfileSet("momentum", 100)
|
||||
Notification(Uppercase("Momentum Restored"), "Your MMT is back to 100%")
|
||||
}
|
||||
gosub FilterUpdate
|
||||
RefreshSkillsList(FilterSkillSelected)
|
||||
return
|
||||
|
||||
CompleteProjectNo:
|
||||
CompleteProjectGuiClose:
|
||||
CompleteProjectGuiEscape:
|
||||
GuiChildClose("CompleteProject")
|
||||
return
|
||||
}
|
||||
return
|
||||
|
||||
CompleteProject(SelectedProjectID)
|
||||
{
|
||||
global db, Difficulties, Awards
|
||||
; Get the difficulty to know how many points to award and the skill to show in notification
|
||||
CompletedProject := db.OpenRecordSet("SELECT * FROM projects WHERE id = " SelectedProjectID)
|
||||
while (!CompletedProject.EOF)
|
||||
{
|
||||
DifficultyToAward := CompletedProject["difficulty"]
|
||||
SkillToIncrease := CompletedProject["skill"]
|
||||
CompletedProject.MoveNext()
|
||||
}
|
||||
CompletedProject.Close()
|
||||
|
||||
; Mark project as done:
|
||||
db.Query("UPDATE projects SET difficulty = 'Done', importance = '', dateDone = " . A_Now . ", levelDone = " . LevelGet() . " WHERE id = " SelectedProjectID)
|
||||
|
||||
; Get the level count for the skill if the project has one:
|
||||
if (SkillToIncrease)
|
||||
{
|
||||
Table := db.Query("SELECT COUNT(skill) FROM projects WHERE skill = '" . SkillToIncrease . "' AND difficulty = 'Done'")
|
||||
columnCount := table.Columns.Count()
|
||||
for each, row in table.Rows
|
||||
{
|
||||
Loop, % columnCount
|
||||
SkillLevel := row[A_index]
|
||||
}
|
||||
}
|
||||
|
||||
; Get the amount of points to award for the chosen level
|
||||
for Num, Difficulty in Difficulties
|
||||
{
|
||||
if (DifficultyToAward = Difficulty)
|
||||
for Key, Award in Awards
|
||||
{
|
||||
if (Num = Key)
|
||||
AwardGiven := Award
|
||||
}
|
||||
}
|
||||
UpdateProgress(DifficultyToAward . " Achievement", AwardGiven)
|
||||
if (SkillToIncrease)
|
||||
Notification("SKILL INCREASED", SkillToIncrease . " increased to " . SkillLevel)
|
||||
}
|
||||
78
ProjectLog.ahk
Normal file
78
ProjectLog.ahk
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
; Project Log Dialog/Window: ============================================
|
||||
|
||||
;#If !WinActive(ProjectLogTitle . " ahk_class AutoHotkeyGUI") && WinActive("LifeRPG ahk_class AutoHotkeyGUI")
|
||||
;^l::
|
||||
ProjectLog:
|
||||
ProjectLogTitle := "Project Log"
|
||||
GuiChildInit("ProjectLog")
|
||||
;Notification(FilterSkillSelected,"")
|
||||
Gui, ProjectLog:Add, Button, gProjectLogDateMoveBack, <
|
||||
Gui, ProjectLog:Add, DateTime, vProjectLogDate gProjectLogRefresh x+1, LongDate
|
||||
Gui, ProjectLog:Add, Button, gProjectLogDateMoveForward x+1, >
|
||||
ColProjLogTime = 1
|
||||
ColProjLogName = 2
|
||||
ColProjLogSkill = 3
|
||||
ColProjLogLevel = 4
|
||||
PLw = 600
|
||||
PLh = 400
|
||||
Gui, ProjectLog:Add, ListView, y+1 xm w%PLw% r10 -Multi vProjectLogList gProjectLogRefresh, Time|Project|Skill|Level ; Set up skills list LV
|
||||
PLx := CenterX(PLw)
|
||||
PLy := CenterY(PLh)
|
||||
gosub ProjectLogRefresh
|
||||
Gui, ProjectLog:Show, x%PLx% y%PLy%, % ProjectLogTitle ;Project Log ; Show Project Log window
|
||||
Send {Right 2}
|
||||
return
|
||||
|
||||
ProjectLogRefresh:
|
||||
Gui, ProjectLog:ListView, ProjectLogList
|
||||
GuiControlGet, ProjectLogDate, , ProjectLogDate
|
||||
LV_Delete()
|
||||
ProjectLogSet := db.OpenRecordSet("SELECT * FROM projects WHERE dateDone LIKE '" . FormatTime(ProjectLogDate,"yyyyMMdd") . "%'")
|
||||
while (!ProjectLogSet.EOF)
|
||||
{
|
||||
ProjectLogTime := ProjectLogSet["dateDone"]
|
||||
ProjectLogName := ProjectLogSet["project"]
|
||||
ProjectLogSkill := ProjectLogSet["skill"]
|
||||
ProjectLogLevel := ProjectLogSet["levelDone"]
|
||||
LV_Add("", ProjectLogTime, ProjectLogName, ProjectLogSkill, ProjectLogLevel)
|
||||
ProjectLogSet.MoveNext()
|
||||
}
|
||||
ProjectLogSet.Close()
|
||||
GuiControl, -Redraw, ProjectLogList
|
||||
LV_ModifyCol(ColProjLogTime, "sortasc")
|
||||
Loop % LV_GetCount()
|
||||
{
|
||||
LV_GetText(PLRow, A_Index, ColProjLogTime)
|
||||
LV_Modify(A_Index, "", FormatTime(PLRow, "Time"))
|
||||
}
|
||||
LV_ModifyCol()
|
||||
Loop % LV_GetCount("Col")
|
||||
{
|
||||
LV_ModifyCol(A_Index, "AutoHDR")
|
||||
}
|
||||
GuiControl, +Redraw, ProjectLogList
|
||||
return
|
||||
|
||||
ProjectLogDateMoveBack:
|
||||
ProjectLogDateMove("Backward")
|
||||
return
|
||||
|
||||
ProjectLogDateMoveForward:
|
||||
ProjectLogDateMove("Forward")
|
||||
return
|
||||
|
||||
ProjectLogDateMove(Direction)
|
||||
{
|
||||
GuiControlGet, ProjLogCurrDate, , ProjectLogDate
|
||||
if (Direction = "Forward")
|
||||
ProjLogCurrDate += 1, Days
|
||||
else if (Direction = "Backward")
|
||||
ProjLogCurrDate += -1, Days
|
||||
GuiControl, ProjectLog:, ProjectLogDate, % ProjLogCurrDate
|
||||
gosub ProjectLogRefresh
|
||||
}
|
||||
|
||||
ProjectLogGuiEscape:
|
||||
ProjectLogGuiClose:
|
||||
GuiChildClose("ProjectLog")
|
||||
return
|
||||
215
ProjectManage.ahk
Normal file
215
ProjectManage.ahk
Normal file
|
|
@ -0,0 +1,215 @@
|
|||
; QuickAdd:
|
||||
#If !WinExist("ahk_group exclude")
|
||||
^!d::
|
||||
Action := "QuickDone"
|
||||
ProjectManage(Action)
|
||||
return
|
||||
#If
|
||||
|
||||
#If !WinExist("ahk_group exclude")
|
||||
^!a::
|
||||
Action := "QuickAdd"
|
||||
ProjectManage(Action)
|
||||
return
|
||||
#If
|
||||
|
||||
; Add a new project:
|
||||
AddProject:
|
||||
Action := "Add"
|
||||
ProjectManage(Action)
|
||||
return
|
||||
|
||||
; Edit a selected project:
|
||||
EditProject:
|
||||
Action := "Edit"
|
||||
ProjectManage(Action)
|
||||
return
|
||||
|
||||
SkillAutoComplete:
|
||||
Critical
|
||||
Gui, ProjectManager:Submit, NoHide
|
||||
If (!GetKeyState("BackSpace","P") && ProjectSkillEdit && Pos := InStr(SkillsDB, "|" . ProjectSkillEdit))
|
||||
{
|
||||
Found := SubStr(SkillsDB, pos+1, InStr(SkillsDB, "|", 1, Pos + 1) - Pos - 1)
|
||||
GuiControl, ProjectManager:Text, ProjectSkillEdit, %Found%
|
||||
SendInput % "{End}" . "+{Left " . StrLen(Found) - StrLen(ProjectSkillEdit) . "}"
|
||||
}
|
||||
return
|
||||
|
||||
ProjectManagerSubmit:
|
||||
Gui, ProjectManager:Submit, NoHide
|
||||
if (ProjectNameEdit = "")
|
||||
{
|
||||
MsgBox, 8192, Error, Can't make a project with no name!
|
||||
return
|
||||
}
|
||||
if (ProjectSkillEdit = "All" || ProjectSkillEdit = "None")
|
||||
{
|
||||
MsgBox, 8192, Error, "All" and "None" can't be used as skill names!
|
||||
return
|
||||
}
|
||||
if (Action = "Add" || Action = "QuickDone" || Action = "QuickAdd")
|
||||
{
|
||||
Record := {}
|
||||
Record.Project := ProjectNameEdit
|
||||
Record.Difficulty := ProjectDifficultyEdit
|
||||
Record.Importance := ProjectImportanceEdit
|
||||
Record.Skill := Capitalize(ProjectSkillEdit)
|
||||
Record.dateEntered := A_Now
|
||||
S := db.Insert(Record, "projects")
|
||||
if (Action = "QuickDone" || Action = "QuickAdd")
|
||||
{
|
||||
Gui, ProjectManager:Cancel
|
||||
Gui, 1:Default
|
||||
if (Action = "QuickDone")
|
||||
{
|
||||
table := db.Query("SELECT MAX(id) FROM projects")
|
||||
columnCount := table.Columns.Count()
|
||||
for each, row in table.Rows
|
||||
{
|
||||
Loop, % columnCount
|
||||
QuickID := row[A_index]
|
||||
}
|
||||
CompleteProject(QuickID)
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (Action = "Edit")
|
||||
{
|
||||
db.Query("UPDATE projects SET project = '" SafeQuote(ProjectNameEdit) "' WHERE ID = " SelectedProjectID )
|
||||
db.Query("UPDATE projects SET difficulty = '" SafeQuote(ProjectDifficultyEdit) "' WHERE ID = " SelectedProjectID )
|
||||
db.Query("UPDATE projects SET importance = '" SafeQuote(ProjectImportanceEdit) "' WHERE ID = " SelectedProjectID )
|
||||
; Make sure skill is title cased, just to look good:
|
||||
StringUpper, ProjectSkillEdit, ProjectSkillEdit, T
|
||||
db.Query("UPDATE projects SET skill = '" SafeQuote(ProjectSkillEdit) "' WHERE ID = " SelectedProjectID )
|
||||
}
|
||||
;UpdateList(Selection, FilterImportanceSelected, FilterSkillSelected)
|
||||
;Notification(Selection . FilterImportanceSelected . FilterSkillSelected, "")
|
||||
;GuiControlGet, FilterSkillSelected, , FilterSkill
|
||||
if (Action = "Add" || Action = "Edit")
|
||||
{
|
||||
GuiChildClose("ProjectManager")
|
||||
}
|
||||
else if (Action = "QuickAdd" || Action = "QuickDone")
|
||||
{
|
||||
Gui, ProjectManager:Cancel
|
||||
Gui, 1:Default
|
||||
}
|
||||
gosub FilterUpdate
|
||||
RefreshSkillsList(FilterSkillSelected)
|
||||
return
|
||||
|
||||
; Fall through below to close window.
|
||||
ProjectManagerGuiEscape:
|
||||
ProjectManagerGuiClose:
|
||||
if (Action = "Add" || Action = "Edit")
|
||||
{
|
||||
GuiChildClose("ProjectManager")
|
||||
}
|
||||
else if (Action = "QuickAdd" || Action = "QuickDone")
|
||||
{
|
||||
Gui, ProjectManager:Cancel
|
||||
Gui, 1:Default
|
||||
}
|
||||
return
|
||||
|
||||
|
||||
ProjectManage(Action)
|
||||
{
|
||||
;global db, ProjectNameEdit, ProjectDifficultyEdit, ProjectImportanceEdit, ProjectSkillEdit
|
||||
global
|
||||
ProjectNameEdit =
|
||||
ProjectDifficultyEdit =
|
||||
ProjectImportanceEdit =
|
||||
ProjectSkillEdit =
|
||||
; Get the row number of the selected project from the main project ListView:
|
||||
Selection := LV_GetNext("","F")
|
||||
; If editing, get the ID number of that project:
|
||||
if (Action = "Edit")
|
||||
{
|
||||
LV_GetText(SelectedProjectID, Selection, 1) ; Get project ID number from hidden column of ListView
|
||||
; If no row is selected and edit is called, do nothing and go back:
|
||||
If (SelectedProjectID == "ID")
|
||||
{
|
||||
return
|
||||
}
|
||||
else ; Get the data for the selected project to populate the edit fields:
|
||||
{
|
||||
ProjectInfo := db.OpenRecordSet("SELECT * FROM projects WHERE id = " SelectedProjectID )
|
||||
while(!ProjectInfo.EOF)
|
||||
{
|
||||
ProjectName := ProjectInfo["project"]
|
||||
ProjectDifficulty := ProjectInfo["difficulty"]
|
||||
ProjectImportance := ProjectInfo["importance"]
|
||||
ProjectSkill := ProjectInfo["skill"]
|
||||
ProjectInfo.MoveNext()
|
||||
}
|
||||
ProjectInfo.Close()
|
||||
}
|
||||
}
|
||||
else if (Action = "Add" || Action = "QuickDone" || Action = "QuickAdd")
|
||||
{
|
||||
ProjectName =
|
||||
ProjectDifficulty =
|
||||
ProjectImportance =
|
||||
ProjectSkill =
|
||||
}
|
||||
; Build the GUI window to either add or edit a project:
|
||||
; Initiate a modal child window owned by the main window (by default):
|
||||
if (Action = "Add" || Action = "Edit")
|
||||
GuiChildInit("ProjectManager")
|
||||
else if (Action = "QuickDone" || Action = "QuickAdd")
|
||||
{
|
||||
Gui, ProjectManager:New
|
||||
Gui, ProjectManager:Default
|
||||
}
|
||||
|
||||
; Name of project:
|
||||
Gui, ProjectManager:Add, Text, , &Project Name:
|
||||
Gui, ProjectManager:Add, Edit, vProjectNameEdit W270 r1, %ProjectName%
|
||||
|
||||
; Difficulty:
|
||||
Gui, ProjectManager:Add, Text, , &Difficulty:
|
||||
DifficultyList := ListDifficulties(ProjectDifficulty)
|
||||
Gui, ProjectManager:Add, DropDownList, vProjectDifficultyEdit, %DifficultyList%
|
||||
|
||||
; Importance:
|
||||
if (Action <> "QuickDone")
|
||||
{
|
||||
Gui, ProjectManager:Add, Text, , &Importance:
|
||||
PriorityList := ListPriorities(ProjectImportance)
|
||||
Gui, ProjectManager:Add, DropDownList, vProjectImportanceEdit, %PriorityList%
|
||||
}
|
||||
|
||||
; Skill:
|
||||
Gui, ProjectManager:Add, Text, x+20 y52, Set S&kill:
|
||||
; To set this, we need to go through all the skills on the table and get all the distinct skills:
|
||||
SkillsDB := ListSkills(ProjectSkill)
|
||||
Gui, ProjectManager:Add, ComboBox, vProjectSkillEdit gSkillAutoComplete w130 r7, % SkillsDB ;% ListSkills(ProjectSkill) ;Diplomacy|Art|Piracy|Cleaning|Hunting
|
||||
|
||||
; Submit button:
|
||||
Gui, ProjectManager:Add, Button, Default gProjectManagerSubmit w80 x15 y+70, &Submit
|
||||
|
||||
; Set size of this window:
|
||||
Width = 300
|
||||
Height = 200
|
||||
|
||||
; Calculate position for centering this child GUI window on wherever the main project list window is:
|
||||
xc := CenterX(300)
|
||||
yc := CenterY(200)
|
||||
; Show window:
|
||||
StringUpper, Action, Action, T
|
||||
if (Action = "QuickDone")
|
||||
{
|
||||
|
||||
StringReplace, PMTitle, Action, done, Done
|
||||
}
|
||||
else if (Action = "QuickAdd")
|
||||
StringReplace, PMTitle, Action, add, Add
|
||||
else
|
||||
PMTitle := Action
|
||||
Gui, ProjectManager:Show, w%Width% h%Height% x%xc% y%yc%, %PMTitle% Project
|
||||
return
|
||||
}
|
||||
|
||||
; Kind of duplicate with other skills get function I just made
|
||||
33
ProjectRemove.ahk
Normal file
33
ProjectRemove.ahk
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
;~ ===============================================================================
|
||||
;~ Confirm project deletion/removal:
|
||||
|
||||
RemoveProject:
|
||||
Selection := LV_GetNext("","F")
|
||||
LV_GetText(SelectedProjectID, Selection, 1)
|
||||
If (SelectedProjectID == "ID")
|
||||
{
|
||||
return
|
||||
}
|
||||
else
|
||||
{
|
||||
GuiMsgBox("RemoveProject", "Remove Project", "Delete this project?")
|
||||
return
|
||||
|
||||
RemoveProjectYes:
|
||||
Gui, RemoveProject:Submit, NoHide
|
||||
db.Query("DELETE FROM projects WHERE id = " SelectedProjectID )
|
||||
GuiChildClose("RemoveProject")
|
||||
RefreshSkillsList(FilterSkillSelected)
|
||||
;Notification("RefreshSkillList(",FilterSkillSelected)
|
||||
gosub FilterUpdate
|
||||
;Notification(Selection . ", " . FilterImportanceSelected . ", " . FilterSkillSelected,"")
|
||||
UpdateList(Selection, FilterImportanceSelected, FilterSkillSelected)
|
||||
return
|
||||
|
||||
RemoveProjectNo:
|
||||
RemoveProjectGuiClose:
|
||||
RemoveProjectGuiEscape:
|
||||
GuiChildClose("RemoveProject")
|
||||
return
|
||||
}
|
||||
return
|
||||
78
ProjectsView.ahk
Normal file
78
ProjectsView.ahk
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
;~ ===============================================================================
|
||||
;~ Building and Displaying the Main GUI:
|
||||
Send !{F2}
|
||||
|
||||
; Improves performance for adding elements to ListView:
|
||||
CountUp := db.Query("SELECT * FROM projects")
|
||||
CountUp := CountUp.Rows.Count()
|
||||
|
||||
WinVis = true
|
||||
; Buttons for Main Gui Window:
|
||||
Gui, 1:Default
|
||||
Gui, Add, Button, y3 x15 gAddProject, &Add Project ; Press Alt+A to add project
|
||||
Gui, Add, Button, y3 x+1 gEditProject, &Edit Project ; Edit project (Alt+E, and so on)
|
||||
Gui, Add, Button, y3 x+1 gAddSubproject, Su&bproject ; Create subproject for selected task
|
||||
Gui, Add, Button, y3 x+1 gCompleteProject, Project &Done ; Confirm project is done
|
||||
Gui, Add, Button, y3 x+1 gRemoveProject, &Remove Project ; Confirm project deletion
|
||||
|
||||
;~ Search bar:
|
||||
Gui, Add, Text, x15 y+1, &Search:%A_Space% ; Pressing Alt+C once focuses on search box
|
||||
try {
|
||||
Gui, Add, Edit, vSearchQuery gSearch x+1 w320 h20,
|
||||
Gui, Add, Button, gClearSearch vClearSearchButton x+1, &Clear ; Pressing Alt+C again clears the search and thus resets the ListView
|
||||
|
||||
|
||||
;~ Filter view by importance:
|
||||
Gui, Add, Text, x+10 vImpChooseText, &Importance:
|
||||
Gui, Add, DropDownList, vImportanceChoose gImportanceUpdate x+5 w60, All|| ; Filtering subroutines are located in Search.ahk
|
||||
GuiControl, , ImportanceChoose, % ListPriorities("All")
|
||||
|
||||
; Filter view by skill:
|
||||
Gui, Add, Text, x+10 vSkillChooseText, S&kill:
|
||||
Gui, Add, DropDownList, vFilterSkill gFilterSkillUpdate x+5 r10, All||None|
|
||||
GuiControl, , FilterSkill, % ListSkills()
|
||||
|
||||
; Show done or not:
|
||||
Gui, Add, Checkbox, vFilterShowDone gFilterUpdate x+10, Show do&ne
|
||||
|
||||
|
||||
;~ ListView:
|
||||
Gui, Add, ListView, x0 y+15 r20 Grid AltSubmit -Multi Count%CountUp% vMainList hwndColored_LV_1, ID|Difficulty|Project|Importance|Parent|Color
|
||||
}
|
||||
Colored_LV_1_BG = 6
|
||||
GuiControl, Focus, SearchQuery ; Focus on search bar by default
|
||||
Gui, Show, w827 h600, %AppTitle% ; Show the GUI we've created
|
||||
UpdateList() ; Show all projects
|
||||
Gui, +Resize +MinSize621x ; Make GUI resizable
|
||||
return
|
||||
|
||||
;~ ===============================================================================
|
||||
;~ Main GUI Resizing information:
|
||||
|
||||
GuiSize:
|
||||
if A_EventInfo = 1 ; The window has been minimized. No action needed.
|
||||
return
|
||||
; Otherwise, the window has been resized or maximized. Resize the controls to match.
|
||||
GuiControl, Move, Mainlist, % "H" . (A_GuiHeight - 55) . " W" . (A_GuiWidth)
|
||||
; Resize search bar to fit dropdown filter controls:
|
||||
if (A_GuiWidth > 811) ;827)
|
||||
{
|
||||
SearchBarWidth := Round(A_GuiWidth*.40)
|
||||
}
|
||||
else if (A_GuiWidth <= 811)
|
||||
{
|
||||
SearchBarWidth := Round(A_GuiWidth*.20)
|
||||
}
|
||||
GuiControl, MoveDraw, SearchQuery, % "w" SearchBarWidth
|
||||
GuiControl, MoveDraw, ClearSearchButton, % "x" 50 + SearchBarWidth + 10
|
||||
GuiControl, MoveDraw, ImpChooseText, % "x" 50 + SearchBarWidth + 55
|
||||
GuiControl, MoveDraw, ImportanceChoose, % "x" 50 + SearchBarWidth + 120
|
||||
GuiControl, MoveDraw, SkillChooseText, % "x" 50 + SearchBarWidth + 190
|
||||
GuiControl, MoveDraw, FilterSkill, % "x" 50 + SearchBarWidth + 220
|
||||
GuiControl, MoveDraw, FilterShowDone, % "x" 50 + SearchBarWidth + 350
|
||||
return
|
||||
|
||||
;~ ===============================================================================
|
||||
;~ What to do when main window is closed:
|
||||
GuiClose:
|
||||
ExitApp
|
||||
168
Res/.gitignore
vendored
Normal file
168
Res/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,168 @@
|
|||
*.exe
|
||||
*.org
|
||||
*.wav
|
||||
*.db
|
||||
|
||||
#################
|
||||
## Eclipse
|
||||
#################
|
||||
|
||||
*.pydevproject
|
||||
.project
|
||||
.metadata
|
||||
bin/
|
||||
tmp/
|
||||
*.tmp
|
||||
*.bak
|
||||
*.swp
|
||||
*~.nib
|
||||
local.properties
|
||||
.classpath
|
||||
.settings/
|
||||
.loadpath
|
||||
|
||||
# External tool builders
|
||||
.externalToolBuilders/
|
||||
|
||||
# Locally stored "Eclipse launch configurations"
|
||||
*.launch
|
||||
|
||||
# CDT-specific
|
||||
.cproject
|
||||
|
||||
# PDT-specific
|
||||
.buildpath
|
||||
|
||||
|
||||
#################
|
||||
## Visual Studio
|
||||
#################
|
||||
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
*.sln.docstates
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Rr]elease/
|
||||
*_i.c
|
||||
*_p.c
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.vspscc
|
||||
.builds
|
||||
*.dotCover
|
||||
|
||||
## TODO: If you have NuGet Package Restore enabled, uncomment this
|
||||
#packages/
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish
|
||||
|
||||
# Others
|
||||
[Bb]in
|
||||
[Oo]bj
|
||||
sql
|
||||
TestResults
|
||||
*.Cache
|
||||
ClientBin
|
||||
stylecop.*
|
||||
~$*
|
||||
*.dbmdl
|
||||
Generated_Code #added for RIA/Silverlight projects
|
||||
|
||||
# Backup & report files from converting an old project file to a newer
|
||||
# Visual Studio version. Backup files are not needed, because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
|
||||
|
||||
|
||||
############
|
||||
## Windows
|
||||
############
|
||||
|
||||
# Windows image file caches
|
||||
Thumbs.db
|
||||
|
||||
# Folder config file
|
||||
Desktop.ini
|
||||
|
||||
|
||||
#############
|
||||
## Python
|
||||
#############
|
||||
|
||||
*.py[co]
|
||||
|
||||
# Packages
|
||||
*.egg
|
||||
*.egg-info
|
||||
dist
|
||||
build
|
||||
eggs
|
||||
parts
|
||||
bin
|
||||
var
|
||||
sdist
|
||||
develop-eggs
|
||||
.installed.cfg
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
.coverage
|
||||
.tox
|
||||
|
||||
#Translations
|
||||
*.mo
|
||||
|
||||
#Mr Developer
|
||||
.mr.developer.cfg
|
||||
|
||||
# Mac crap
|
||||
.DS_Store
|
||||
BIN
Res/128px-Role-playing_video_game_icon.svg.png
Normal file
BIN
Res/128px-Role-playing_video_game_icon.svg.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
BIN
Res/WP_RPG_VG.ico
Normal file
BIN
Res/WP_RPG_VG.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 98 KiB |
45
Search.ahk
Normal file
45
Search.ahk
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
;~ ===============================================================================
|
||||
;~ Filter ListView by priority:
|
||||
|
||||
|
||||
;~ UpdateList(,FilterImportanceSelected,FilterSkillSelected)
|
||||
;~ return
|
||||
|
||||
;~ ===============================================================================
|
||||
; Filter main projects ListView by available skills:
|
||||
FilterUpdate:
|
||||
ImportanceUpdate:
|
||||
FilterSkillUpdate:
|
||||
GuiControlGet, FilterImportanceSelected, 1:, ImportanceChoose
|
||||
GuiControlGet, FilterSkillSelected, 1:, FilterSkill
|
||||
GuiControlGet, FilterShowDone, 1:, FilterShowDone
|
||||
UpdateList(Selection,FilterImportanceSelected,FilterSkillSelected)
|
||||
return
|
||||
|
||||
;~ ===============================================================================
|
||||
;~ Clear the search bar and reset the ListView:
|
||||
|
||||
ClearSearch:
|
||||
Critical
|
||||
GuiControl, , ImportanceChoose, |All||
|
||||
GuiControl, , ImportanceChoose, % ListPriorities()
|
||||
|
||||
GuiControl, , FilterSkill, |All||None| ; Put | at start to reset out the DDL
|
||||
GuiControl, , FilterSkill, % ListSkills()
|
||||
|
||||
GuiControl, , FilterShowDone, 0
|
||||
GuiControl, , SearchQuery
|
||||
GuiControl, Focus, SearchQuery
|
||||
return
|
||||
|
||||
;~ ===============================================================================
|
||||
;~ Search subroutine:
|
||||
|
||||
Search:
|
||||
Critical
|
||||
GuiControlGet, SearchString, , SearchQuery
|
||||
GuiControlGet, FilterImportanceSelected, , ImportanceChoose
|
||||
GuiControlGet, FilterSkillSelected, , FilterSkill
|
||||
GuiControlGet, FilterShowDone,
|
||||
UpdateList(Selection, FilterImportanceSelected, FilterSkillSelected)
|
||||
return
|
||||
86
Settings.ahk
Normal file
86
Settings.ahk
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
;~ Autoload and initial settings loading section:============================================
|
||||
|
||||
;~ "Character" class, disabled for now b/c have to make HUD progress bar automatically fit:
|
||||
;CharacterClass := "Artist"
|
||||
|
||||
;~ Set icon for window corner:
|
||||
IconFile := "res/WP_RPG_VG.ico"
|
||||
if FileExist(IconFile)
|
||||
Menu, Tray, Icon, %IconFile%
|
||||
Menu, Tray, NoStandard
|
||||
|
||||
;~ Project difficulties:
|
||||
Difficulties := ["Really Easy", "Pretty Easy", "Medium", "Hard"]
|
||||
|
||||
; Award points for each difficulty:
|
||||
Awards := [5, 10, 25, 100]
|
||||
|
||||
; Difficulty colors:
|
||||
Colors := [BGR("ADFF2F"), BGR("87CEFA"), BGR("FFD700"), BGR("FF6347")]
|
||||
|
||||
;~ Priorities:
|
||||
Priorities := ["Must", "Should", "Could", "Want"]
|
||||
|
||||
BGR(RGB)
|
||||
{
|
||||
R := SubStr(RGB, 1, 2)
|
||||
G := SubStr(RGB, 3, 2)
|
||||
B := SubStr(RGB, 5, 2)
|
||||
return "0x" . B . G . R
|
||||
}
|
||||
|
||||
;~ The window title text:
|
||||
AppTitle := "LifeRPG"
|
||||
|
||||
;~ Make it easier for the script to identify its own window if need be:
|
||||
WindowFind := AppTitle . " ahk_class AutoHotkeyGUI"
|
||||
|
||||
;~ Level up sound location:
|
||||
LevelUpSound := SettingGet("Sound", "LevelUp")
|
||||
if (LevelUpSound = "Error" || !FileExist(LevelUpSound))
|
||||
LevelUpSound := ""
|
||||
|
||||
; Open connection to SQLite database:
|
||||
ConnectionString := SettingGet("File", "LastOpened") ; Get last used database from settings.
|
||||
if (ConnectionString = "Error" || ConnectionString = "") ; That means it's the first time it was run, so load the default db.
|
||||
ConnectionString := "data/LifeRPG.db"
|
||||
AskLoad:
|
||||
if (!FileExist(ConnectionString)) ; User must have deleted or moved last used db, so ask to pick another or make a new one.
|
||||
{
|
||||
Gui +OwnDialogs
|
||||
MsgBox, 51, %AppTitle% Error, Last loaded database `n"%connectionString%" `nwas not found.`n`nWould you like to open a different database?`nIf not, you must create a new one before you can continue.`n`nOtherwise, hit Cancel to quit the program.
|
||||
IfMsgBox Yes
|
||||
{
|
||||
gosub FileOpen
|
||||
if (!IsObject(db))
|
||||
gosub AskLoad
|
||||
}
|
||||
else IfMsgBox No
|
||||
{
|
||||
gosub FileNew
|
||||
if (!IsObject(db))
|
||||
gosub AskLoad
|
||||
}
|
||||
else
|
||||
ExitApp
|
||||
}
|
||||
else ; we can go ahead and load the last used db:
|
||||
db := DBA.DataBaseFactory.OpenDataBase("SQLite", ConnectionString)
|
||||
|
||||
; Hotkey do not activate list:
|
||||
GroupAdd, exclude, New projects database
|
||||
GroupAdd, exclude, Open a projects database
|
||||
GroupAdd, exclude, Add Project ahk_class AutoHotkeyGUI
|
||||
GroupAdd, exclude, Reference ahk_class AutoHotkeyGUI
|
||||
GroupAdd, exclude, Edit Project ahk_class AutoHotkeyGUI
|
||||
GroupAdd, exclude, Add Subproject ahk_class AutoHotkeyGUI
|
||||
GroupAdd, exclude, Remove Project ahk_class AutoHotkeyGUI
|
||||
GroupAdd, exclude, Complete Project ahk_class AutoHotkeyGUI
|
||||
GroupAdd, exclude, QuickDone Project ahk_class AutoHotkeyGUI
|
||||
GroupAdd, exclude, QuickAdd Project ahk_class AutoHotkeyGUI
|
||||
GroupAdd, exclude, Skill Stats ahk_class AutoHotkeyGUI
|
||||
GroupAdd, exclude, About ahk_class AutoHotkeyGUI
|
||||
GroupAdd, exclude, Edit Your Profile ahk_class AutoHotkeyGUI
|
||||
GroupAdd, exclude, Project Log ahk_class AutoHotkeyGUI
|
||||
SettingsTitle := "Edit LifeRPG Settings"
|
||||
GroupAdd, exclude, % SettingsTitle . " ahk_class AutoHotkeyGUI"
|
||||
59
SettingsEdit.ahk
Normal file
59
SettingsEdit.ahk
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
; Edit app settings: ===================================================
|
||||
;#If !WinActive("Skill Stats ahk_class AutoHotkeyGUI") && WinActive("LifeRPG ahk_class AutoHotkeyGUI")
|
||||
;^s::
|
||||
SettingsEdit:
|
||||
GuiChildInit("SettingsEdit")
|
||||
; Define size and positions:
|
||||
SettingsW = 400
|
||||
SettingsH = 140
|
||||
SettingsX := CenterX(SettingsW)
|
||||
SettingsY := CenterY(SettingsH)
|
||||
|
||||
; Create content and fields:
|
||||
; Level Up Sound:
|
||||
Gui, SettingsEdit:Add, Text, , Select sound file to use for &Level-Up Sound:
|
||||
SettingLocationLevelUp := SettingGet("Sound","LevelUp")
|
||||
if (SettingLocationLevelUp = "Error")
|
||||
SettingLocationLevelUp := ""
|
||||
Gui, SettingsEdit:Add, Edit, vSettingsEditLevelUpEdit w300 r1, % SettingLocationLevelUp
|
||||
Gui, SettingsEdit:Add, Button, x+1 gLevelUpSoundBrowse w80, &Browse
|
||||
Gui, SettingsEdit:Add, Button, y+1 xm gSoundTestLevelUp w40, Test
|
||||
Gui, SettingsEdit:Add, Button, x+1 gSoundTestLevelUpStop w40, Stop
|
||||
|
||||
; Save button:
|
||||
Gui, SettingsEdit:Add, Button, Default y+30 xm w80 gSettingsEditSubmit, &Save
|
||||
; Cancel:
|
||||
Gui, SettingsEdit:Add, Button, x+10 w80 gSettingsEditGuiClose, &Cancel
|
||||
|
||||
; Show GUI:
|
||||
Gui, SettingsEdit:Show, w%SettingsW% h%SettingsH% x%SettingsX% y%SettingsY%, %SettingsTitle%
|
||||
; hang out here until user saves or closes:
|
||||
return
|
||||
|
||||
LevelUpSoundBrowse:
|
||||
Gui +OwnDialogs
|
||||
FileSelectFile, NewLocationLevelUpSound, , , Select a sound file , Audio (*.wav; *.mp3)
|
||||
GuiControl, SettingsEdit:, SettingsEditLevelUpEdit, % NewLocationLevelUpSound
|
||||
return
|
||||
|
||||
SoundTestLevelUp:
|
||||
GuiControlGet, LUSFile, SettingsEdit:, SettingsEditLevelUpEdit
|
||||
SoundPlay % LUSFile
|
||||
return
|
||||
|
||||
SoundTestLevelUpStop:
|
||||
SoundPlay 341589134759384759348.wav
|
||||
return
|
||||
|
||||
; What do to when user submits:
|
||||
SettingsEditSubmit:
|
||||
Gui, SettingsEdit:Submit, NoHide
|
||||
SettingSet("Sound","LevelUp", SettingsEditLevelUpEdit)
|
||||
LevelUpSound := SettingsEditLevelUpEdit
|
||||
|
||||
|
||||
; What to do when user closes or escapes window:
|
||||
SettingsEditGuiClose:
|
||||
SettingsEditGuiEscape:
|
||||
GuiChildClose("SettingsEdit") ; Close up GUI child window.
|
||||
return
|
||||
85
SkillsView.ahk
Normal file
85
SkillsView.ahk
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
; View the user's current levels in all the skills he has completed projects in:
|
||||
|
||||
SkillsView:
|
||||
GuiChildInit("SkillsView")
|
||||
;Notification(FilterSkillSelected,"")
|
||||
ColSkillName = 1
|
||||
ColSkillLevel = 2
|
||||
Gui, SkillsView:Add, ListView, w300 r20 -Multi gSkillsListEvent vSkillsListView, Skill|Level ; Set up skills list LV
|
||||
Gui, SkillsView:Add, Button, Hidden Default w0 h0 gSkillsListEvent, OK
|
||||
SVw = 300
|
||||
SVh = 400
|
||||
SVx := CenterX(SVw)
|
||||
SVy := CenterY(SVh)
|
||||
; Populate the Skill Stats ListView with skills and stats:
|
||||
; 1. Get the skills count for all done items from the projects table
|
||||
; First we need to add all skills to the LV
|
||||
; SELECT DISTINCT skill FROM projects WHERE difficulty <> 'Done' ORDER BY skill
|
||||
; 2. Add to ListView
|
||||
SkillsList := db.OpenRecordSet("SELECT DISTINCT skill FROM projects WHERE skill IS NOT NULL AND skill <> '' ORDER BY skill")
|
||||
while (!SkillsList.EOF)
|
||||
{
|
||||
SkillListName := SkillsList["skill"]
|
||||
LV_Add("", SkillListName)
|
||||
RowNum := A_Index
|
||||
Table := db.Query("SELECT COUNT(skill) FROM projects WHERE skill = '" . SkillListName . "' AND difficulty = 'Done'")
|
||||
columnCount := table.Columns.Count()
|
||||
for each, row in table.Rows
|
||||
{
|
||||
Loop, % columnCount
|
||||
;msgbox % row[A_index]
|
||||
LV_Modify(RowNum,"Col2", row[A_Index])
|
||||
}
|
||||
SkillsList.MoveNext()
|
||||
}
|
||||
SkillsList.Close()
|
||||
;LV_ModifyCol()
|
||||
LV_ModifyCol(ColSkillLevel, "AutoHDR integer sortdesc")
|
||||
Loop % LV_GetCount("Col")
|
||||
{
|
||||
LV_ModifyCol(A_Index, "AutoHDR")
|
||||
}
|
||||
Gui, SkillsView:Show, x%SVx% y%SVy%, Skill Stats ; Show skills list window
|
||||
SkillCount := LV_GetCount()
|
||||
if (FilterSkillSelected = "All" || FilterSkillSelected = "None" || !FilterSkillSelected)
|
||||
return
|
||||
else
|
||||
{
|
||||
Loop % SkillCount
|
||||
{
|
||||
HighlightLine := A_Index
|
||||
LV_GetText(SkillToHighlight, HighlightLine, ColSkillName)
|
||||
if (SkillToHighlight = FilterSkillSelected)
|
||||
{
|
||||
LV_Modify(HighlightLine, "Focus Select Vis")
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
|
||||
SkillsListEvent: ; Jump to double-clicked skill
|
||||
GuiControlGet, FocusedControl, FocusV
|
||||
if (FocusedControl = "SkillsListView")
|
||||
{
|
||||
if (LV_GetNext(0, "Focused") = 0)
|
||||
return
|
||||
else
|
||||
LV_GetText(SDC, LV_GetNext(0, "Focused"))
|
||||
}
|
||||
else if (A_GuiEvent = "DoubleClick" )
|
||||
LV_GetText(SDC, A_EventInfo)
|
||||
GuiChildClose("SkillsView")
|
||||
RefreshSkillsList(SDC)
|
||||
UpdateList(,,FilterSkillSelected)
|
||||
return
|
||||
|
||||
SkillsViewGuiEscape:
|
||||
SkillsViewGuiClose:
|
||||
GuiChildClose("SkillsView")
|
||||
return
|
||||
|
||||
ExploreObj(Obj, NewRow="`n", Equal=" = ", Indent="`t", Depth=12, CurIndent="") {
|
||||
for k,v in Obj
|
||||
ToReturn .= CurIndent . k . (IsObject(v) && depth>1 ? NewRow . ExploreObj(v, NewRow, Equal, Indent, Depth-1, CurIndent . Indent) : Equal . v) . NewRow
|
||||
return RTrim(ToReturn, NewRow)
|
||||
}
|
||||
75
SubprojectAdd.ahk
Normal file
75
SubprojectAdd.ahk
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
;~ ===============================================================================
|
||||
;~ Add subproject for a selected project:
|
||||
|
||||
AddSubproject:
|
||||
Selection := LV_GetNext("","F")
|
||||
LV_GetText(SelectedProjectID, Selection, 1)
|
||||
If (SelectedProjectID == "ID")
|
||||
{
|
||||
return
|
||||
}
|
||||
else
|
||||
{
|
||||
ProjectInfo := db.OpenRecordSet("SELECT * FROM projects WHERE id = " SelectedProjectID )
|
||||
while(!ProjectInfo.EOF)
|
||||
{
|
||||
ParentProjectName := ProjectInfo["project"]
|
||||
ProjectInfo.MoveNext()
|
||||
}
|
||||
ProjectInfo.Close()
|
||||
;UpdateList(Selection)
|
||||
}
|
||||
GuiChildInit("AddSubproject")
|
||||
Gui, AddSubproject:Add, Text, w270, Parent Project:`n%ParentProjectName%
|
||||
;Gui, AddSubproject:Add, Text, vParentName W270, %ParentProjectName%
|
||||
|
||||
Gui, AddSubproject:Add, Text, , Subproject Name:
|
||||
Gui, AddSubproject:Add, Edit, vProjectName W270,
|
||||
|
||||
Gui, AddSubproject:Add, Text, section, &Difficulty:
|
||||
Gui, AddSubproject:Add, DropDownList, vProjectDifficulty, % ListDifficulties("Really Easy")
|
||||
|
||||
Gui, AddSubproject:Add, Text, ys, Set S&kill:
|
||||
SPSkills := ListSkills()
|
||||
Gui, AddSubproject:Add, ComboBox, vProjectSkill gSPSkillAutoComplete w130 r7, % SPSkills
|
||||
|
||||
Gui, AddSubproject:Add, Text, xm, Impo&rtance:
|
||||
Gui, AddSubproject:Add, DropDownList, vProjectImportance, % ListPriorities("Must")
|
||||
|
||||
Gui, AddSubproject:Add, Button, Default gAddSubprojectSubmit w80 xm y+20, &Submit
|
||||
|
||||
WinGetPos,xd,yd,wd,hd,%WindowFind%
|
||||
xc := CenterX(300)
|
||||
yc := CenterY(200)
|
||||
Gui, AddSubproject:Show, w300 h240 x%xc% y%yc%, Add Subproject
|
||||
return
|
||||
|
||||
SPSkillAutoComplete:
|
||||
Critical
|
||||
Gui, AddSubproject:Submit, NoHide
|
||||
If (!GetKeyState("BackSpace","P") && ProjectSkill && Pos := InStr(SPSkills, "|" . ProjectSkill))
|
||||
{
|
||||
Found := SubStr(SPSkills, pos+1, InStr(SPSkills, "|", 1, Pos + 1) - Pos - 1)
|
||||
GuiControl, AddSubproject:Text, ProjectSkill, %Found%
|
||||
SendInput % "{End}" . "+{Left " . StrLen(Found) - StrLen(ProjectSkill) . "}"
|
||||
}
|
||||
return
|
||||
|
||||
AddSubprojectSubmit:
|
||||
Gui, AddSubproject:Submit, NoHide
|
||||
Record := {}
|
||||
Record.Project := ProjectName
|
||||
Record.Difficulty := ProjectDifficulty
|
||||
Record.Importance := ProjectImportance
|
||||
Record.Parent := SelectedProjectID
|
||||
Record.skill := ProjectSkill
|
||||
Record.dateEntered := A_Now
|
||||
S := db.Insert(Record, "projects")
|
||||
gosub FilterUpdate
|
||||
RefreshSkillsList(FilterSkillSelected)
|
||||
|
||||
AddSubprojectGuiEscape:
|
||||
AddSubprojectGuiClose:
|
||||
GuiChildClose("AddSubproject")
|
||||
;UpdateList(Selection)
|
||||
return
|
||||
15
license.txt
Normal file
15
license.txt
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
LifeRPG - Confidence and Motivation Building System
|
||||
Copyright (C) 2012 Jayvant Javier Pujara and other contributors
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
27
readme.txt
Normal file
27
readme.txt
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
LifeRPG Release 2 - Confidence and Motivation Building System
|
||||
by Jayvant Javier Pujara
|
||||
JJPujara@gmail.com
|
||||
|
||||
About:
|
||||
Organize your life; build confidence, momentum, motivation, and have fun.
|
||||
|
||||
Discussion:
|
||||
http://www.reddit.com/r/LifeRPG/
|
||||
|
||||
|
||||
|
||||
|
||||
Copyright (C) 2012 Jayvant Javier Pujara and other contributors
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
Loading…
Reference in New Issue
Block a user