How to transform a bootstrap modal into a non-blocking mdi window - bootstrap-modal

I want the page to stay accessible with modal being opened. I have tried with possible values of backdrop
this.modalService.open(firstWindow,
{
backdrop : 'static',/*true, false*/
keyboard : false
});
How do I implement a non blocking modal ?

Related

Close OleCreatePropertyFrame externally

I am using OleCreatePropertyFrame to display property pages of the webcam. But, I wasn't able to make the dialog modal or close the frame externally when closing the camera.
OleCreatePropertyFrame(
NULL, // Parent window
0, 0, // Reserved
lpcostr, // Caption for the dialog box
1, // Number of objects (just the filter)
&pFilterUnk, // Array of object pointers.
caGUID.cElems, // Number of property pages
caGUID.pElems, // Array of property page CLSIDs
0, // Locale identifier
0, NULL // Reserved
);
Any help is appreciated.
OleCreatePropertyFrame is standard API for modal dialog box meaning that it is supposed that the mesasge box is displayed until closed interactively. That is, you are not supposed to be able to close it from code.
This function always creates a modal dialog box and does not return until the dialog box is closed.
One of the ways to make the dialog modal is to re-implement property page host (IPropertyPage and friends) and put it into your customized UI as a modeless window or otherwise. It is quite doable overall, and mostly expects basic knowledge of COM.
Another [traditional?] trick to close standard modal UI externally is to PostQuitMessage into the inner message loop of OleCreatePropertyFrame API so that it closes the dialog box in response to non-interactive signal, and then remove pending WM_QUIT message from the outer message loop, added by the API after closing the dialog in attempt to forward quit command further.

open a dialog behind a modal dialog or after it is closed

I have an application which has several background tasks running in non-GUI threads which may time to time require some user interaction so they send signal to the main thread and the corresponding slot creates a dialog and shows it to the user. Meanwhile the task thread is waiting in a blocking event loop. Once the user answers the dialog and closes it, the task event loop is signaled to quit and the task resumes.
There is however a problem. In the GUI thread I can still use the application which time to time shows some modal dialogs. When there is a modal dialog already shown and then the background tasks requests another dialog to be opened, this task-related dialog is displayed in front of the modal dialog. But this new dialog is not modal and the modal dialog is hidden behind it. The non-modal one therefore is not responsive, the application feels like it got stuck.
My idea was to display the new dialog always behind the modal dialog, which I believe I can get with QApplication::activeModalWidget(). But I do not know how to do this. How can I show a dialog behind another dialog but still in front of the main window (which is a parent of both dialogs)? I tried to call QApplication::activeModalWidget()->activateWindow() after I show the non-modal one but his causes blinking of windows and moreover I can still click into the new non-modal dialog hiding the modal one. So this is not a perfect solution.
Or do you see any other solution?
Maybe I could implement a queue of dialogs, and once there is any modal dialog visible, then the new background task-related dialog would not be shown, only enqueued and shown once the modal dialog is closed. However this feels more fragile solution to me.
Any ideas?
UPDATE: I redefined the question by adding "or after it is closed" becasue this works for me too.
I found a solution which seems to work well and which shows the non-modal dialog only after the modal dialog is closed.
QWidget *nonModalDialog = ... // creates the non-modal dialog
nonModalDialog->setAttribute(Qt::WA_DeleteOnClose);
QWidget *modalDialog = qApp->activeModalWidget();
if (modalDialog == nullptr)
{
// no modal dialog, we can show the non-modal one now
dialog->show();
}
else
{
// we must wait until the modal one is closed
QObject::connect(modalDialog, &QWidget::destroyed, nonModalDialog, &QWidget::show);
}
This seems simple and robust.
I think you are looking for QWidget::raise(). You should be able to use QApplication::activeModalWidget()->raise() after calling dialog->show() on your non-modal dialog.
If you're getting into situations where you have multiple modal and non-modal dialogs, all launched in different order, this might not be enough to solve the problem. You might raise one modal dialog only to have others behind other non-modal dialogs and end up stuck again. You should consider keeping a reference to the collection of modal dialogs that are currently active so that you can make sure they are always on top of the non-modal dialogs.

In MFC Close only the Child Dialog, not the Parent

I'm a newcomer to MFC world. I need to have some dialog based operaion for an old application. There I'm having a trouble for an appraently obvious thing and that is I can't seem to find a way to close the child dialog (Modal) that I'm invoking from my parent (also a Modal). In all the ways I tried always both child and parent is getting closed at once.
Here is what I tried:
I've created a default MFC application in VS 2012 Professional
ParentDlg.cpp
void ParentDlg::OnBnClickedOk()
{
ChildDlg childDlg;
dialogOutput.DoModal();
CDialogEx::OnOK();
}
In my Child.cpp for a Close button (ID: IDCLOSE)
ChildDlg.cpp
void ChildDlg::OnBnClickedClose()
{
// TODO: Add your control notification handler code here
EndDialog(IDCLOSE);
}
But this is closing both the parent and child, but I need only the child dialog to be closed (Parent Dialog should remain open) as I'm clicking the 'Close' buton on the child dialog.
In short, I like to have the same behaviour of the default IDOK button of 'IDD_ABOUTBOX' dialog, which is also a Modal dialog and closes only the About Box when I click on the 'OK' button in it.
You should only place IDOK in the ID property of your close button. And only the child dialog will close. You should no longer create an event handler, and if you did, delete the event handler.

MFC EndDialog crashes when modal dialog does not have focus

I am closing a modal dialog after I end a task, inside a separate thread from where I created a modal dialog:
void CmodguiApp::_notify_task_end() {
processingDialog->EndDialog(0);
}
This works fine if my application has focus (therefore the modal dialog has focus). But this causes the application to crash if I change window while the modal dialog is on (for instance, if I leave the application processing and switch to Firefox or so).
What could be wrong?
Do not end the dialog with EndDialog. Instead PostMessage with WM_CLOSE or WM_QUIT to the dialog window.

QT Modal Window and Disabling parents toolbar

I am developing a project using Qt4 and I have run into a slight issue.
I am creating a modal window from the main window. I want this to disable the toolbar at the top.
I have a menu item that spawns the modal from the menu. What I want is that when the modal is spawned that menus is disabled. I have tried using the setEnabled(false) function but that doesn't reset it.
Here is the code:
void Main_Screen::Create_ViPro()
{
std::auto_ptr<ViPro_Dialog> modal(new ViPro_Dialog(this));
modal->show();
modal->exec();
}
So It is just a simple class that is triggered when a menu item is selected. I feel that the problem stems from the fact that i'm setting the parent to the main screen, however I don't know how to create a modal without a parent(it doesn't make sense to do that). Is there a way to disable the parents toolbar from the child? The only thing I have seen so far is _fileMenu->setEnabled(false);
That works as long as I don't create the modal, but as soon as that is spawned, the menu works again. I'm totally lost.
Thanks in advance
Edit as Patrice
Here is the constructor
Main_Screen::Main_Screen(QWidget* parent /*= NULL*/)
: QMainWindow(parent),
_newProj(new QAction(tr("New &ViPro"), this)),
_fileMenu(menuBar()->addMenu(tr("&File")))
{
//create slot for creating a new project
connect(_newProj.get(), SIGNAL(triggered()), this, SLOT(Create_ViPro()));
_fileMenu->addAction(_newProj.get());
//if i do this then setEnabled(false) works perfectly and i can't access the menu
Create_ViPro()
}
So the function is signaled by triggering the newproject action. If i call the function directly from within the constructor it disables it as you stated patrice, however, if I have the function called via the trigger, it doesn't disable it. Am I handling the signal / slot mechanism wrong? Thanks again.
Another example, if I make the function create_vipro() as below
void Main_Screen::Create_ViPro()
{
_fileMenu->setEnabled(false);
}
The file menu isn't disabled when I trigger the event, so it must have nothing to do with the modal itself, but instead how signals are handled.
Since child is a modal dialog main screen can't react to event. But you can disable the toolbar (or menubar) before creating the modal dialog and enable it as soon as you leave the exec function:
void Main_Screen::Create_ViPro()
{
_fileMenu->setEnabled(false);
std::auto_ptr<ViPro_Dialog> modal(new ViPro_Dialog(this));
modal->show();
modal->exec(); // Will stay here until you close the modal dialog
_fileMenu->setEnabled(true);
}
if ViPro_Dialog is really a modal dialog it will works.
Another thing, since ViPro_Dialog is modal you can declare it locally without using auto_ptr:
void Main_Screen::Create_ViPro()
{
_fileMenu->setEnabled(false);
ViPro_Dialog modal(this);
modal.show();
modal.exec(); // Will stay here until you close the modal dialog
_fileMenu->setEnabled(true);
}
EDIT:
I guess (I can't test at work) that you can't enable/disable menu when it is executing a QAction. Signal is calling slots sequentially so QAction is busy when you try to disable the menu.
Try this:
In Main Screen, create a slot with one boolean parameter that enable/disable menubar. Just call the setEnabled function
In ViPro_Dialog, emit a signal with a boolean parameter (false at startup, true at validation)
In Create_ViPro, once dialog created, connect the new signal with the slot, exec dialog and don't forget to disconnect slot from signal:
void Main_Screen::Create_ViPro()
{
ViPro_Dialog modal(this);
// Connect signal/slot
modal.show();
modal.exec(); // Will stay here until you close the modal dialog
// Disconnect signal/slot
}
This can achieve what you want
EDIT2
You are doing a mistake when using modal dialog. There's a conflict between show() and exec(). When you are displaying modal dialog you don't need to disable other windows: it's automatically done by modal status of the dialog. There are many modal depth: http://qt-project.org/doc/qt-4.8/qt.html#WindowModality-enum. So your code should be:
void Main_Screen::Create_ViPro()
{
ViPro_Dialog modal(this);
// modal.setWindowModality(Qt::WindowModal); // Uncomment this line if you want to only disable parent
modal.exec();
}
Read this for more detail: http://qt-project.org/doc/qt-4.8/QDialog.html#details.
Using exec() doesn't just create a modal dialog, it also suspends most of the regular event handling, and only handles events in the dialog that is in exec(). This may include some UI updates (like the transitions from enabled to disabled), but I'm not positive. A better way to handle this might be to explicitly set the dialog modal, but allow the regular event loop to continue, something like this:
void Main_Screen::Create_ViPro()
{
ViPro_Dialog* modal = new ViPro_Dialog(this);
modal->setModal(true);
modal->show();
}
That code will still not visually disable the toolbar or menubar, but they should be unresponsive. To disable them, you could try combining this with Patrice Bernassola's answer.