- Hymnal Browser Lite Documentation
This file contains both developer and user documentation for the application. This documentation is last updated on May 4, 2023.
Changes may or may not be made without prior notice.
While Autohotkey may not be the most optimal programming language for the development of this application, it has been chosen for the purpose of an experimental project to provide a temporary solution for the slow runtime issue present in the Python-based Hymnal Browser.
The language is primarily designed for task automation and may not be an ideal fit for our application. However, due to its superior speed and open-source nature, we have decided to utilize it for this project to achieve faster performance. The application has been programmed in C++ for optimal efficiency.
- AHK2ExtLib - a personalized extended library for AutoHotkey v2
- KConfig - customized configuration serializer/deserializer
- SevenZip - AHK wrapper for 7zip
- Hymnal Database (.sda) file
- Microsoft Office PowerPoint or any .pptx-compatible software.
- Since this application is written in AHKv2, interface design is limited to what's available resources.
- Although efforts have been made to maximize user interface, the primary goal is focused on better functionality and reliability.
Regrettably, at present, Hymnal Browser Lite only supports English and Tagalog presentations, and we do not have any immediate plans to include other languages. This is because the addition of other languages would require the recreation of the hymn files, which is currently not feasible.
To ensure the codebase remains organized and maintainable, the classes in the program have been separated into distinct files. The code structure adheres to the principles of object-oriented programming, wherein each class serves a specific purpose. A list of these classes is provided below.
As the program requires an external library to function correctly, a significant portion of the functions are customized and may lack in-depth explanations. Many of the custom codes implemented in the program draw inspiration from Python's syntax and terminology.
(No content yet.)
- System - This handles system-related info of the application such as checking if the required folders are present, executing the main program, and getting the monitor number where the application is visible.
- UI - Handles user-interface behavior, threads, and connections between every control (or widgets) such as Search bar, Launch button, Suggestion box, and Hymn detail text. It also handles every control.
- Config - Handles and processes the user-specified configuration. This also covers application-related configurations like
TME_QUERY
(Time before the search considers the count). - Hymnal - Works with the hymnal package's content such as parsing and generating a map of the parsed data.
- Session - Works similarly to the Config class but this handles only the data in the current session.
- Background - Acts like the background thread/listener for the application. It covers events like detecting if the app is currently active or the window is moved.
- Events - Handle events forwarded by signals from controls or the system. This contains methods like
Events.System.Exit()
where the system will request a proper close event for the application. - Errors - Handle errors properly for the system.
- Launcher - Handles extraction and presentation launch for the application.
- File Management - Manages the external files that are within the scope of the program such as removing temp files.
- SW/Software - Contains metadata about the software such as
SW.TITLE
to retrieve the title of the application.
- Buttons - Interface for buttons like Clear and Launch button.
- Search Bar - The LineEdit/TextEdit where the user inputs the hymn.
- Completer - A customized completer/suggestion box for the search bar.
- Context Menu - Handles context menu items and their behaviors.
- Main Menu - Interface for texts like the Hymnal Browser Lite title, the app version, and the hymn details.
- Settings - [Not implemented yet] a GUI version of configuration where user can change settings via this window.
Several classes are not implemented as a file in the program. For example, the
_LOG
object fromKLogger
class handles the logging for the app. This helps the developer to identify bugs easily. This also acts as a replacement for the default exception message box from AHK
The main program will start with the Hymnal Browser Lite.ah2 file where AHK settings will be set and System.Exec()
is called.
Inside System.Exec()
, there are several instructions on setting up the interface, handlers, and threads.
The following statements are under the System.Exec()
method.
_STARTUP
- This variable starts the startup counter to measure how long the initialization will take time.
System.CheckDevMode()
will check if the application is being run in script mode or the compiled mode. The differences are minimal but noticeable. These include (1) additional menu items in the context menu as well as (2) the indicator beside the version text. But more importantly, the FileInstall
command will be only executed if the system detects a compiled mode.
Global variables like _LOG
(KLogger) and CF
(Config) are also initiated at this point. These are now the instance of their class, where _LOG
handles logging and CF
handles the configuration data of the application.
The system will now set the settings for _LOG
object:
- Verbose logging will be set according to
CF.MAIN.VERBOSE_LOG
.In script mode, the verbose log will be always set to 1 (Enabled)
- Max lines will be set according to
SW.LOG_MAX_LINES
.Default value is set to 1,000 lines before the log is truncated
Since the KLogger is instantiated, several logs will be dumped:
- Application start message
- System information report
- Dev mode notice (Only shows in compiled mode)
- Process ID report
- Verbose logging status
- Core initialization message
Config is always placed ahead of Logger to load the
CF.MAIN.VERBOSE_LOG
before instantiating the logger. Both instances are global.
Menu tray items are deleted and replaced with an Exit item. You can see this item by right-clicking the tray icon of Hymnal Browser Lite.
Error.Setup()
will rebind the error messages to Error.BaseError()
method if the SW.ERROR_HANDLING
is set to True
The system will now verify each required directory. Directories are retrieved from SW.DIRS
. Every absent directory will be created. After this, the system logs the report, including MISSING
and RESOLVED
directories if available.
After directory verification, the system will now verify the presentation software that will be used later for launching.
There are two (2) situations that the program may encounter:
- If the computer does not have an Office PowerPoint installed, the file will be executed by
Run()
command, in which in some cases, Windows will ask the user for the presentation software the '.pptx' file should be opened with. - If Microsoft Office PowerPoint is detected (via registry path search), the retrieved value will be stored in
SW.FILE_POWERPOINT
System environments are loaded and stored in an ENV
object. This contains the sensitive keys for the program.
This part will now scan the hymnal package and retrieves its parsed content. The hymn package is specified in CF.__FILE_HYMNALDB
. If the user changes the [HYMNAL] PACKAGE = <name>
in settings.cfg (SW.FILE_CONFIG
), the specified package will be used.
HymnalDB._VerifyDatabase()
There are several directories for the package search. This includes:
A_ScriptDir
or the directory where the .exe is located.SW.DIR_PROGRAM
or the program's directory inA_CommonAppdata
(ProgramData)SW.DIR_DOCS_PROGRAM
or the program's directory inDocuments\MSDAC Systems
Failure to find the package in these directories will result in AbsentPackage
error in Errors.HymnsDB
.
The package path is stored in CF.__FILE_HYMNALDB
which will be used
later in Launcher class.
HymnalDB.ScanHymnal()
The method will return a map of all hymnal data such as the number of hymns in English, Tagalog, User, or both, the hymn titles, and hymn numbers.
The method uses SevenZip
to read the contents inside the package.
The map object is stored in HYMNAL
as a global variable.
The Session data will start. The object is stored in global SES
and all properties in session data will be referenced as SES.PROPERTY_NAME
.
The user interface or UI will execute several instructions for its UI.Setup()
method, in which the individual controls are initialized.
It calls every UI element specified in UI.UIs
array and holds its object to bind all objects together in a UI's property.
Class names are different from provided class names in static variable
_NAME
. (e.g: ContextMenu class is referenced as UI.RCTX, not UI.ContextMenu)
For example, the UI.CPLTR
is referencing the Completer object that is instantiated in the setup method.
UI.ConnectEvents()
After instantiating all UI elements, their events will now connect to Events
class where Events will handle their function
UI.StartThreads()
The setup will now invoke the UI.StartThreads()
to start the background listeners of some UI elements like the search bar.
UI.Keybinds
The UI will now bind certain keys to its function. One of examples is the Ctrl + Backspace which is connected to UI.SEARCH.Keypress
to emulate a regular key combination in search bar (because it's apparently not working in AHK).
After setting up the UI, the BackgroundThread
class will now be initialized. This class contains methods that are in a timer with a specific period defined by SW.BG_REF_RATE
One of the methods it contains is the BackgroundThread.WindowListener()
that detects and listens to the activity of the main window if it's active or not, or whether the main window was moved.
The hymn stats can be also found here which listens at different periods (custom listener) and logs a query and launch for a particular hymn.
Before the initialization is complete, the _LOG
will dump all postponed logs to the log file.
After that, the main window will now show the saved coordinates (if available) provided by CF.WINDOW.XPOS
and CF.WINDOW.YPOS
A completion log will be sent to the logger along with the startup time that was declared here.
_RUNTIME
will now start to mark the runtime of the program.
At this point, the program is now ready for usage, assuming that there was no error encountered by the system as discussed in Error handling.
This section contains all the details about the controls of the UI.
The application utilizes 3 GUI interfaces:
- Main Window
- Completer Window
- Settings Window
Two context menus are found in the main window and the tray menu icon.
There are seven (7) elements that can be found in the main window (from left to right, top to bottom):
- Title Text (Hymnal Browser Lite)
- Version Text
- Detail Text
- Last launched [Not implemented yet]
- Search Bar
- Clear Button
- Launch Button
In the completer window or the suggestion box, the only element is the ListBox where the hymns are shown. The secondary window is transparent.
Name | Control Type | Description |
---|---|---|
Title Text | Text | Displays "Hymnal Browser Lite" with a primary color |
Version Text | Text | Displays the current version of the running app |
Detail Text | Text | Displays the details of the hymn: Base hymn and Equivalent hymn |
Last Launched | Text | Dynamic text that displays the last launched time of the current hymn relatively |
Search Bar | Edit | A single-line edit that acts as an input for search query |
Clear Button | Button | Clears the current search text |
Launch Button | Button | Launches the hymn. Also displays how many hymns are matching during the search |
Not implemented yet.
Name | Control Type | Description |
---|---|---|
Confirm Button | Button |
These are the known exit codes covered by the program.
Code | Name | Scope | Description |
---|---|---|---|
0 | ExitApp |
System | Normal application exit |
1 | AbsentPackage |
HymnalDB | Hymnal package cannot be found |
2 | ExitApp |
System | Normal application exit |
10 | ReloadApp |
System | System reload request |
13 | BaseError |
Base | A standard error if not specified |
AbsentPackage
- Hymnal package cannot be foundAbsentBinary
- Binary 7z.exe cannot be found inA_Temp
This event class consists of nested classes.
This event handles the proper exit of the application. Critical errors are also forwarded to this method to safely terminate the program.
The exit code defines the severity of the application exit. (See list of exit codes) An exit code of 0 or 2 is normal.
Reloads the program. Also invokes Events.System.Exit()
with an error code of 10
which requests for a program restart. This doesn't save the session data and does not take parameters to execute in the next launch.
The configuration and software components of the system serve a similar purpose in that they both store variable values. However, there is a fundamental difference between the two that sets them apart.
The Config class allows users to modify variables by specifying custom values, while the Software class variables are immutable and cannot be changed by the user.
Special thanks to the AutoHotkey team and Lexikos for making this possible with AHK.
Copyright © 2022 MSDAC Systems