views:

287

answers:

2

Greetings,

for one of my applications I'm trying to implement an "Edit" menu. This menu usually has the standard-entries Undo, Cut, Copy and Paste.

This menu is not there by default, and users seem to expect it especially on Mac OS X.

Is there a an easier way of implementing this, without doing so in every widget manually? Since most widgets have the copy/paste/undo mechanism already implemented via shortcuts, I'd like to provide a few simple menu actions that call them as well.

The actions should call whatever widget has the focus first, then they should pass the events upwards the object chain, I guess.

I'm using Qt 4.6 on Windows, Linux and Mac OS X.

Thanks!

A: 

My impression is that the Edit menu applies to the central document widget, not loads of small ones. I have not tested, but if you have a form with QLineEdits, does the Edit menu (in the menu bar) really apply to that widget. Don't you simple bring up the context menu or press the short-cuts to access these options...

e8johan
That might be true for Windows/Linux like window managers. On OS X, however, you have a application-wide menu bar at the top of the screen, not at the top of each window. And Mac users expect the selected menu action to have an effect on the topmost window and the widget that currently has the focus. (Selecting paste would paste whatever is in the clipboard into the QLineEdit which currently has the focus, etc.)
BastiBense
+1  A: 

It's easy enough to accomplish half of the necessary functionality. Just create the Edit menu, along with the necessary QActions (copy/paste/undo/etc.) in your main window class and connect them to slots. In the slots, emulate the correct key press and release events (e.g. Ctrl+C for Copy) and send them to the currently focused widget. In code, something like this:

MainWindow::MainWindow(...)
{
    ...
    connect( actionCopy, SIGNAL( triggered()), SLOT( copy()));
    ...
}
...
void MainWindow::copy()
{
    QWidget* focused = QApplication::focusWidget();
    if( focused != 0 )
    {
        QApplication::postEvent( focused,
                                 new QKeyEvent( QEvent::KeyPress,
                                                Qt::Key_C,
                                                Qt::ControlModifier ));
        QApplication::postEvent( focused,
                                 new QKeyEvent( QEvent::KeyRelease,
                                                Qt::Key_C,
                                                Qt::ControlModifier ));
}

Of course, this is quite a hack. You need to modify the code for each target platform, changing the keyboard shortcuts to the correct ones, and it might happen that a widget that receives focus does something quiet unexpected with Ctrl+C. The worst downside in this method, in my opinion, is that you cannot properly control the enabled state of the Edit menu items. It is not possible to query from a generic widget whether a copy or paste operation would be possible or not.

I am unable to find a real solution to this problem - and would be surprised to find out that one exists - as the copy/paste functionality is generally hidden inside the class' code and not exposed through any standard set of signals/slots. After tonight's experiments with the functionality, I have decided to just forget having an Edit menu from my application and expect the users to know the keyboard shortcuts, or use the context sensitive menus.

jlahd
Terrible news. Thanks though
Wahnfrieden