Skip to content

Commit

Permalink
Implemented keyboard live properties keyboard.ctrl, keyboard.alt
Browse files Browse the repository at this point in the history
…and `keyboard.shift` and updated documentation accordingly. #138
  • Loading branch information
end2endzone committed Jan 20, 2024
1 parent cfdb368 commit 81cb438
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 11 deletions.
16 changes: 11 additions & 5 deletions UserManual.md
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,9 @@ For example, the following set a menu visible only when the keyboard _shift_ mod
<visibility keyboard="shift" />
```

**Note:**
You can also filter menus based on keyboard modifier states using `keyboard.ctrl`, `keyboard.alt` or `keyboard.shift` properties. See [live properties](#live-properties) for details.



### inverse attribute: ###
Expand All @@ -560,7 +563,7 @@ The meaning of each inversed attribute in explained in the following table:
| istrue | Validates a menu if the given value **does not** evaluates to logical _true_.<br>If multiple values are specified, **no value** must evaluate to logical _true_ for the validation to be successful. | |
| isfalse | Validates a menu if the given value **does not** evaluates to logical _false_.<br>If multiple values are specified, **no value** must evaluate to logical _false_ for the validation to be successful. | |
| isempty | Validates a menu if the given text **is not** empty. If the attribute is not specified, then the validation is successful. Otherwise, if text is specified, the expanded value **must not** be empty. | |
| keyboard | Validates a menu if the specified keyboard modifier **is not** pressed.<br>If multiple modifiers are specified, **all modifiers** must not match the keyboard state for the validation to be successful. | |
| keyboard | Validates a menu if the specified keyboard modifier **is not** pressed.<br>If multiple modifiers are specified, **all modifiers** must not match the keyboard state for the validation to be successful. | |

Typical use case of the `inverse` attribute is about filtering out known file extensions.

Expand Down Expand Up @@ -1221,7 +1224,7 @@ For example :
</default>
```

**Note:**
**Notes:**
* By default, the attribute is set to `true` for compatibility with legacy Configuration Files.
* Without this attribute, the &lt;property&gt; actions must be ordered from the least expected to fail to the most expected to fail.
* If the property value cannot be resolved and `fail` attribute is set to `false`, the target property is not modified.
Expand Down Expand Up @@ -1409,9 +1412,12 @@ The application provides _live_ properties which are defined automatically by th

The following table defines the list of live properties and their utility:

| Property | Description |
|-----------|---------------------------------------------------------------------------------------------------------------------|
| clipboard | Matches the content of [Windows Clipboard](https://lifehacker.com/how-to-copy-cut-and-paste-for-beginners-5801525). |
| Property | Description |
|----------------|---------------------------------------------------------------------------------------------------------------------|
| clipboard | Matches the content of [Windows Clipboard](https://lifehacker.com/how-to-copy-cut-and-paste-for-beginners-5801525). |
| keyboard.ctrl | Matches the down state of keyboard CTRL modififer. The value is set to `system.true` or `system.false` properties. |
| keyboard.alt | Matches the down state of keyboard ALT modififer. The value is set to `system.true` or `system.false` properties. |
| keyboard.shift | Matches the down state of keyboard SHIFT modififer. The value is set to `system.true` or `system.false` properties. |

These properties are encoded in utf-8.

Expand Down
62 changes: 57 additions & 5 deletions src/core/PropertyManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ namespace shellanything
const std::string PropertyManager::SYSTEM_FALSE_PROPERTY_NAME = "system.false";
const std::string PropertyManager::SYSTEM_FALSE_DEFAULT_VALUE = "false";
const std::string PropertyManager::SYSTEM_CLIPBOARD_PROPERTY_NAME = "clipboard";
const std::string PropertyManager::SYSTEM_KEYBOARD_CTRL_PROPERTY_NAME = "keyboard.ctrl";
const std::string PropertyManager::SYSTEM_KEYBOARD_ALT_PROPERTY_NAME = "keyboard.alt";
const std::string PropertyManager::SYSTEM_KEYBOARD_SHIFT_PROPERTY_NAME = "keyboard.shift";

PropertyManager::PropertyManager()
{
Expand Down Expand Up @@ -274,11 +277,11 @@ namespace shellanything
virtual std::string GetProperty() const
{
// Try to read the clipboard's value.
IClipboardService* clipboard = App::GetInstance().GetClipboardService();
if (clipboard)
IClipboardService* service = App::GetInstance().GetClipboardService();
if (service)
{
std::string clipboard_value;
bool clipboard_read = clipboard->GetClipboardText(clipboard_value);
bool clipboard_read = service->GetClipboardText(clipboard_value);
if (clipboard_read)
{
return clipboard_value;
Expand All @@ -290,13 +293,62 @@ namespace shellanything
}
};


class KeyboardModifierLiveProperty : public virtual ILiveProperty
{
private:
std::string property_name;
KEYB_MODIFIER_ID keyb_modifier_id;

public:
KeyboardModifierLiveProperty(const std::string& name, KEYB_MODIFIER_ID id) :
property_name(name),
keyb_modifier_id(id)
{
}

~KeyboardModifierLiveProperty()
{
}

virtual const std::string& GetName() const
{
return property_name;
}

virtual std::string GetProperty() const
{
// Try to read the keyboard's modifier state.
IKeyboardService* service = App::GetInstance().GetKeyboardService();
if (service)
{
PropertyManager& pmgr = PropertyManager::GetInstance();
if (service->IsModifierKeyDown(keyb_modifier_id))
{
return pmgr.GetProperty(PropertyManager::SYSTEM_TRUE_PROPERTY_NAME);
}
else
{
return pmgr.GetProperty(PropertyManager::SYSTEM_FALSE_PROPERTY_NAME);
}
}

static std::string EMPTY_VALUE;
return EMPTY_VALUE;
}
};

void PropertyManager::RegisterLiveProperties()
{
// Check if a live property instance already exists
if (GetLiveProperty(SYSTEM_CLIPBOARD_PROPERTY_NAME) == NULL)
{
AddLiveProperty(new ClipboardLiveProperty());
}
if (GetLiveProperty(SYSTEM_KEYBOARD_CTRL_PROPERTY_NAME) == NULL)
AddLiveProperty(new KeyboardModifierLiveProperty(SYSTEM_KEYBOARD_CTRL_PROPERTY_NAME, KMID_CTRL));
if (GetLiveProperty(SYSTEM_KEYBOARD_ALT_PROPERTY_NAME) == NULL)
AddLiveProperty(new KeyboardModifierLiveProperty(SYSTEM_KEYBOARD_ALT_PROPERTY_NAME, KMID_ALT));
if (GetLiveProperty(SYSTEM_KEYBOARD_SHIFT_PROPERTY_NAME) == NULL)
AddLiveProperty(new KeyboardModifierLiveProperty(SYSTEM_KEYBOARD_SHIFT_PROPERTY_NAME, KMID_SHIFT));
}

void PropertyManager::ClearLiveProperty(const std::string& name)
Expand Down
15 changes: 15 additions & 0 deletions src/core/PropertyManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,21 @@ namespace shellanything
/// </summary>
static const std::string SYSTEM_CLIPBOARD_PROPERTY_NAME;

/// <summary>
/// Name of the property that defines the keyboard's CTRL modifier state.
/// </summary>
static const std::string SYSTEM_KEYBOARD_CTRL_PROPERTY_NAME;

/// <summary>
/// Name of the property that defines the keyboard's ALT modifier state.
/// </summary>
static const std::string SYSTEM_KEYBOARD_ALT_PROPERTY_NAME;

/// <summary>
/// Name of the property that defines the keyboard's SHIFT modifier state.
/// </summary>
static const std::string SYSTEM_KEYBOARD_SHIFT_PROPERTY_NAME;

public:

/// <summary>
Expand Down
42 changes: 42 additions & 0 deletions src/tests/TestPropertyManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,14 @@
#include "TestPropertyManager.h"
#include "PropertyManager.h"
#include "IClipboardService.h"
#include "TestKeyboardService.h"
#include "App.h"

#include "rapidassist/testing.h"
#include "rapidassist/random.h"

extern shellanything::TestKeyboardService* keyboard_service;

namespace shellanything
{
namespace test
Expand Down Expand Up @@ -395,6 +398,45 @@ namespace shellanything
ASSERT_EQ(str2, "str2");
ASSERT_EQ(str3, "str3");
}
//--------------------------------------------------------------------------------------------------
TEST_F(TestPropertyManager, testLivePropertyKeyboardAutoUpdate)
{
//assert the service is available
ASSERT_TRUE(keyboard_service != NULL);

// Update PropertyManager with default live properties
PropertyManager& pmgr = PropertyManager::GetInstance();
pmgr.ClearLiveProperties();
pmgr.RegisterLiveProperties();

// Act
keyboard_service->Clear();
keyboard_service->SetModifierKeyDown(KMID_CTRL , false);
keyboard_service->SetModifierKeyDown(KMID_ALT , false);
keyboard_service->SetModifierKeyDown(KMID_SHIFT, false);
std::string str1 = pmgr.Expand("${" + PropertyManager::SYSTEM_KEYBOARD_CTRL_PROPERTY_NAME + "}");
std::string str2 = pmgr.Expand("${" + PropertyManager::SYSTEM_KEYBOARD_ALT_PROPERTY_NAME + "}");
std::string str3 = pmgr.Expand("${" + PropertyManager::SYSTEM_KEYBOARD_SHIFT_PROPERTY_NAME + "}");

// Assert.
ASSERT_EQ(str1, "false");
ASSERT_EQ(str2, "false");
ASSERT_EQ(str3, "false");

// Act
keyboard_service->Clear();
keyboard_service->SetModifierKeyDown(KMID_CTRL , true);
keyboard_service->SetModifierKeyDown(KMID_ALT , true);
keyboard_service->SetModifierKeyDown(KMID_SHIFT, true);
str1 = pmgr.Expand("${" + PropertyManager::SYSTEM_KEYBOARD_CTRL_PROPERTY_NAME + "}");
str2 = pmgr.Expand("${" + PropertyManager::SYSTEM_KEYBOARD_ALT_PROPERTY_NAME + "}");
str3 = pmgr.Expand("${" + PropertyManager::SYSTEM_KEYBOARD_SHIFT_PROPERTY_NAME + "}");

// Assert.
ASSERT_EQ(str1, "true");
ASSERT_EQ(str2, "true");
ASSERT_EQ(str3, "true");
}

} //namespace test
} //namespace shellanything
2 changes: 1 addition & 1 deletion src/tests/TestValidator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1271,7 +1271,7 @@ namespace shellanything
//--------------------------------------------------------------------------------------------------
TEST_F(TestValidator, testKeyboard)
{
//assert success if the service is not available
//assert the service is available
ASSERT_TRUE(keyboard_service != NULL);

SelectionContext c;
Expand Down

0 comments on commit 81cb438

Please sign in to comment.