Programmatically populated contextual "ok glass" menu - google-glass

Is there any way to populate the custom "ok glass" menu in my glassware programmatically?
I have an application where the user will be in an immersion and interact with the system mainly by voice commands. The immersion consists of a CardScrollView displaying different sets of data. These sets are added and removed dynamically from a bluetooth service talking to a phone and the glass unit can't know in advance what new sets will appear.
What I want the user to be able to do is to list all current sets in the voice menu and from there choose which set to switch to. For example, if I at the moment have the sets A, B, C and D, I want the user to be able to say "ok glass, go to set", see a sub menu with A, B, C and D and then say for example "C" to switch to set C in the view.
Is this at all possible?
The glassware is going to run in a closed environment with no connection to MyGlass at all, so custom voice commands for the menu with the development permission is not a problem.

From what I understand you want you application to be already running when the user speaks. If this is correct then you can simply implement a custom menu with contextual voice commands. I believe you can always repopulate the menu just before it is being shown by overriding onPreparePanel.
I haven't tested it but guessing from the guide something like:
#Override
public boolean onPreparePanel(int featureId, View view, Menu menu) {
if (featureId == WindowUtils.FEATURE_VOICE_COMMANDS) {
menu.clear();
for (MyMenuItem item : mCurrentMenuItems) {
menu.add(Menu.NONE, item.getId(), Menu.NONE, item.getTitle());
}
}
return super.onPreparePanel(featureId, view, menu);
}
#Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
if (featureId == WindowUtils.FEATURE_VOICE_COMMANDS) {
switch (item.getItemId()) {
case MENU_ITEM_A:
// do something
break;
default:
return true;
}
return true;
}
return super.onMenuItemSelected(featureId, item);
}
MyMenuItem would be a simple class which holds a unique id of an item and its title. mCurrentMenuItems is a list of items to be shown at the moment. You can change its content using a background service, for example.

Related

How do I open a window depending on the user's choice in the previous window? in Qt

Okay so basically I am creating an interface that has a seller and a customer, and so the user chooses which option he wants and is taken to the the "registration window". After filling the questions he presses continue and it takes him to either the "seller" interface or "customer" interface.
I want to know how on Qt do I make the
void RegistrationWindow::on_continue_pushButton_clicked()
take the user to the interface of the chosen option in the previous window.
I know I will need to use an If statement, but I don't know what will the condition be or how i will make it work.
Here is the code for the registration window continue button:
void RegistrationWindow::on_continue_pushButton_clicked()
{
hide();
if ()
customer = new CustomerWindow(this);
customer->show();
if()
seller = new SellerWindow(this);
seller->show();
}
And here is the code for the main window buttons:
void MainWindow::on_customer_pushButton_clicked()
{
hide();
registration = new RegistrationWindow(this);
registration->show();
}
void MainWindow::on_seller_pushButton_clicked()
{
hide();
registration = new RegistrationWindow(this);
registration->show();
}
If any information else is needed I will provide it.
Thank you!
I have not tried anything yet because I dont understand

Disable some context menu items if no items are checked

I have a tree view (CTreeView) that will show me a pop-up menu after I right-click my mouse on it.
In my context menu there are only 3 items (i.e A, B, C) for selection and my tree view displays a long list of ordered foods designed with check-boxes. I would like to disable menu items A and B if no ordered foods are checked and enable them when any is.
I create CFoodView::OnUpdateItemA(CCmdUI* pCmdUI) //CFoodView inherits CTreeView
and CFoodView::OnUpdateItemB(CCmdUI* pCmdUI) to handle their states like so
CFoodView::OnUpdateItemB(CCmdUI* pCmdUI)
{
if TreeView has no items
{
pCmdUI->Enable(FALSE);
}
else
{
*Search* the tree to get selected items
if None is checked
{
pCmdUI->Enable(FALSE);
}
else there are checked items
pCmdUI->Enable(TRUE);
}
}
Method CFoodView::OnUpdateItemA(CCmdUI* pCmdUI) is the same.
I think this isn't a correct way to handle this GUI feature.
Well, you did not submit all important information. How did you create menu item handlers?
Assuming you insert handlers the proper way, still did not provide any information how you are invoking popup menu.
If all you did was properly done it is the proper way of handling update menu.
The most common mistake is designating view itself as the window that handles popup updates and commands. In order to use MFC menu update mechanism, you have to pass a pointer to the main window not to the tree view:
CWnd *pMainWnd = AfxGetMainWnd();
ASSERT(pMainWnd != nullptr);
pSubMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, pt.x, pt.y, pMainWnd);
If this will not work reexamine the way you create handler and/or the place you invoke the TrackPopupMenu function.

Adding and localizing menu items in the main menu of a Qt application menubar

So first of all here is a screenshot of the said menu of Evernote, localized in French:
[]
As you can see, all the menu items in the main menu (by main menu I mean the one whose name is the application name, like here it is Evernote) are localized in French. There are lots of menu items which the Evernote app itself brings, like Évaluez Evernote pour Mac (Rate Evernote for Mac), Information du compte... (Account Info...), etc. Plus there are the standard OS X provided menu items like Quit Evernote, Preferences, etc which are also localized.
My questions:
How do I add a new item in this main menu? How to access this menu to add items?
How do I localize these items based on my app localization, both OS X provided default ones and the ones I add?
In the Evernote menu, everything seems to be localized except the Services menu option (the submenu options are however localized!)? Can't this be localized as well?
What I have tried:
fMenuBar = fMainWindow->menuBar();
fMenuFile = fMenuBar->addMenu(QObject::tr(qPrintable(String_Class::FileMenu))); //"File" in English, translated into other languages
fAboutAppAct = new QAction(QObject::tr(qPrintable(String_Class::About_App)), fMainWindow); //prints "About App", localized in all languages
fMenuFile->addAction(fAboutAppAct);
fAboutAppAct->setMenuRole(QAction::AboutRole); //otherwise it sits with the other file menu options in the File menu
//reset UI language slot, called whenver UI language is reset. It retranslates all strings in all menus, except this
void AppMenu::reTranslateUISlot()
{
fAboutAppAct->setText(QObject::tr(qPrintable(String_Class::About_App)));
}
Maybe you could reimplement in MainWindow or in AppMenu the changeEvent.
void MainWindow::changeEvent(QEvent *event)
{
if (event->type() == QEvent::LanguageChange) {
this->retranslateUi(this);
quickStart->retranslateUi(quickStart);
//etc...
} else {
QMainWindow::changeEvent(event);
}
}
You could force Widgets to retranslate themselves. But you need to have registered some QTranslator first.
For example, in the constructor of MainWindow (or in some config dialog) if it's possible to change language at runtime (what I've done in my software):
CustomizeOptionsDialog::CustomizeOptionsDialog(QWidget *parent)
: QDialog(parent, Qt::Tool)
{
// Load the language of the application
customTranslator.load(languages.value( SettingsPrivate::instance()->language()) );
// Translate standard buttons (OK, Cancel, ...)
defaultQtTranslator.load("qt_" + SettingsPrivate::instance()->language(), QLibraryInfo::location(QLibraryInfo::TranslationsPath));
QApplication::installTranslator(&customTranslator);
QApplication::installTranslator(&defaultQtTranslator);
}
Where language() returns "fr", "gb" or "cs" (initialized from a signal emitted when one has chosen a new language in options).
/** Change language at runtime. */
void CustomizeOptionsDialog::changeLanguage(const QString &language)
{
QString lang = languages.value(language);
SettingsPrivate *settings = SettingsPrivate::instance();
// If the language is successfully loaded, tells every widget that they need to be redisplayed
if (!lang.isEmpty() && lang != settings->language() && customTranslator.load(lang)) {
settings->setLanguage(language);
defaultQtTranslator.load("qt_" + lang, QLibraryInfo::location(QLibraryInfo::TranslationsPath));
QApplication::installTranslator(&customTranslator);
/// TODO: reload plugin UI
QApplication::installTranslator(&defaultQtTranslator);
} else {
labelStatusLanguage->setText(tr("No translation is available for this language :("));
}
}
I hope it's helping.
I still haven't found the complete answer to my problems. But here some of the observations I have made over the last few days:
To be able to add menu items in the main menu, you have to set the menu role accordingly, i.e after adding it wherever you want to (it won't matter, because it will move out), you set the menu role like this:
fYourAction->setMenuRole(QAction::ApplicationSpecificRole);
This will add the menu item in the main menu. If you add more than item in this way, they will appear in the order in which you set their menu roles.
There are few specific roles Qt already provides - i.e for the About <app> item, Quit <app> item, Preferences... item, etc. They are mentioned here.
For example, if your action has a text "Foo", and you add it somewhere as a menu item, and set the role like
fFooAction->setMenuRole(QAction:: PreferencesRole);
then it will automatically move to the main menu and show as Preferences..., what text you actually put in the action will be immaterial. Whatever slot you have attached to it as a response to the triggered() signal will still fire correctly, though. Same goes for QAction::AboutRole as well, whatever text you add in that action, it will move to the main menu and show as About <your_app_name>.
The problem with QAction::AboutRole or QAction:: PreferencesRole is like I said, they won't localize even if you try. They will get localized only when the system locale changes, if you change it just within your app by installing a new translator, it won't change. The workaround? Avoid them and use QAction::ApplicationSpecificRole for all items you want to appear in the main menu. Then they will get properly localized as per your custom translator, and will respect whatever text you provide in the action, i.e if you give foo as text in the action, it will appear as foo in the main menu, and get localized accordingly. Again, mind you, when you are adding multiple items, set the role of the items in order of their appearance, i.e to simulate the Evernote menu above, first set the menu role for the about_app action, then the preferences action. Where you are adding them will be of no importance since they will be moved to a new menu, so the order in which you set the menu role for the items will determine the order in which they appear in the main menu.
The problem with the above approach is that I don't know how to insert separators between the items I am adding in the main menu. It is easy to do that in the menus we add, since we have access to the menu object, but here we don't have access (we add the items somewhere else, and make them move to the main menu by setting the menu role), so I don't know yet how to add multiple separators in the main menu.

Disabling (Greying out) multiple GUI Items in C++

Question:
I am looking for an effective way to disable(grey) mutiple items in a MFC C++ application. Depending on if the user is signed into a SQL Server or Oracle account, I wish to disable a section of GUI items.
What I have tried:
I have used the following code to disable one of my two "Create User" buttons.
if(checkIsSQLServer())
{
CWnd *oraCreateUser = GetDlgItem(BTN_ORA_CREATE);
oraCreateUser->EnableWindow(false); //Disable Oracle "Create User" button
}
else
{
CWnd *sqlCreateLogin = GetDlgItem(BTN_SQL_CREATE);
sqlCreateLogin->EnableWindow(false); //Disable SQL Server "Create User" button.
}
.
This code works perfectly, however it only disables the button. I wish to disable all items within either groupbox.
Do I need to create a CWnd* object for every item I wish to disable? Is there a more effective way, such as a way to disable all items that are contained within a group box?
I use this:
void EnableDlgItem (CWnd *dlg, int items[], BOOL bEnable)
{
int i = 0, item ;
while ((item = items[i++]) != 0)
{
CWnd *pControl = dlg->GetDlgItem(item) ;
if (pControl != NULL)
pControl->EnableWindow(bEnable) ;
}
}
...
And in some CYourDialog::OnSomethingFunction()
static int ids[] = {IDOK, IDC_EDIT1, IDC_EDIT2, 0};
EnableDlgItem(this, ids, FALSE);
As others have said, MFC does not expose a method that allows you to enable/disable a group of controls. You'll need to craft your own code to do that.
I was faced with the very same situation and decided to handle it by deriving my own groupbox class. In my situation, the groupbox enable/disable functioning was tied to the state of a checkbox as seen below.
(I've redacted some information from it).
Clicking on the checkbox will toggle the enable/disable of all controls within the groupbox. There's nothing stopping you from deriving your own class for the groupbox and exposing a method that can be called (rather than a checkbox) to enable/disable controls. The advantage to this approach is that if you create the class in a generic manner, you can re-use it in other situations where a groupbox is the "parent" of other controls.

Best way to Enable/Disable CMenu items in real time

I'm working on a project using Visual C++ 6.0, and I need to be able to enable or disable certain menu items depending on the permissions assigned to the currently logged in user. This is the code I'm using:
// If the currently logged in user doesn't have permission to edit invoices
if (!((CMyApp *)AfxGetApp())->UserHasPermission(PERMISSION_EditInvoice))
{
// Disable the Edit Menu
pMain->EnableMenuItem(1, MF_BYPOSITION | MF_DISABLED | MF_GRAYED);
}
else
{
// Enable the Edit Menu
pMain->EnableMenuItem(1, MF_BYPOSITION | MF_ENABLED);
}
It does exactly what I want it to do, however I'm trying to find the best place to put it. If I put it in OnInitialUpdate(), I get the results I want, but only for the first invoice opened. If you open a second invoice without closing and re-opening the dialog, the code is not executed again. OnUpdate() isn't called when opening a different invoice, and the only other place I've found that works is OnDraw(), the problem with OnDraw() is that the menu item doesn't visually change state from Grayed out to Enabled or vice versa until you try to click it.
I think you must include this code in a procedure
void check_user_permission();
than you must call it when this events occur:
- OnInitialUpdate()
- new user login (if your software permits user login/logout during the same session)
- new invoice opened
Can it help?
I ended up deciding to disable the Edit Invoice menu item, instead of the Edit menu itself. This proved much easier and cleaner, as it determines permission and enables or disables item every time the main 'Edit menu is opened.
void CViewInvoiceView::OnUpdateEditEditinvoice(CCmdUI* pCmdUI)
{
// If the currently logged in user doesn't have permission to edit invoices
if (!((CJ3App *)AfxGetApp())->UserHasPermission(PERMISSION_EditInvoice))
{
// Disable the Edit Menu
pCmdUI->Enable(false);
}
else
{
// Enable the edit menu
pCmdUI->Enable();
}
}