menuactionhelper.cpp 6.27 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
#include "menuactionhelper.h"

MenuActionHelper::MenuActionHelper(QObject *parent) : QObject(parent),
    m_isAdvancedMode(false),
    m_dockWidgetTitleBarsEnabled(true),
    m_addedCustomSeperator(false)
{
}

QAction *MenuActionHelper::createToolAction(const QString &title, const QString &name)
{
    QAction *action = m_menuToDockNameMap.key(name);  //For sanity, check that the action is not NULL
    if(action) {
            qWarning() << "createToolAction was called for action" << name << "which already exists in the menu";
            return action;
    }

    action = new QAction(title, NULL);
    action->setCheckable(true);
    connect(action,SIGNAL(triggered(bool)),this,SLOT(showTool(bool)));
    m_menuToDockNameMap[action] = name;
    m_menu->addAction(action);
    return action;
}

void MenuActionHelper::removeDockWidget()
{
    QObject *dockWidget = QObject::sender(); //Note that we can't cast to QDockWidget because we are in its destructor
    Q_ASSERT(dockWidget);

    qDebug() << "Dockwidget:"  << dockWidget->objectName() << "of type" << dockWidget->metaObject()->className();

    QAction *action = m_menuToDockNameMap.key(dockWidget->objectName());
    if(action) {
        m_menuToDockNameMap.remove(action);
        action->deleteLater();
    }
    QMap<MainWindow::VIEW_SECTIONS,QMap<QString,QDockWidget*> >::iterator it;
    for (it = m_centralWidgetToDockWidgetsMap.begin(); it != m_centralWidgetToDockWidgetsMap.end(); ++it) {
        QMap<QString,QDockWidget*>::iterator it2 = it.value().begin();
        while( it2 != it.value().end()) {
            if(it2.value() == dockWidget)
                it2 = it.value().erase(it2);
            else
                ++it2;
        }
    }
    //Don't delete the dockWidget because this could have been called from the dockWidget destructor
    m_dockWidgets.removeAll(static_cast<QDockWidget*>(dockWidget));
}

QAction *MenuActionHelper::createToolActionForCustomDockWidget(const QString &title, const QString& name, QDockWidget* dockWidget, MainWindow::VIEW_SECTIONS view) {
    bool found = false;
    QAction *action = NULL;
    foreach(QAction *act, m_menuToDockNameMap.keys()) {
        if(act->text() == title) {
            found = true;
            action = act;
        }
    }

    if(!found)
        action = createToolAction(title, name);
    else
        m_menuToDockNameMap[action] = name;

    m_centralWidgetToDockWidgetsMap[view][name] = dockWidget;
    connect(dockWidget, SIGNAL(destroyed()), SLOT(removeDockWidget()),Qt::UniqueConnection); //Use UniqueConnection since we might have already created this connection in createDockWidget
    connect(dockWidget, SIGNAL(visibilityChanged(bool)), action, SLOT(setChecked(bool)));
    action->setChecked(dockWidget->isVisible());
    return action;
}

QDockWidget* MenuActionHelper::createDockWidget(const QString& title,const QString& name)
{
    QDockWidget *dockWidget = new QDockWidget(title);
    m_dockWidgets.append(dockWidget);
    setDockWidgetTitleBar(dockWidget);
    dockWidget->setObjectName(name);
    connect(dockWidget, SIGNAL(destroyed()), SLOT(removeDockWidget()));

    return dockWidget;
}

bool MenuActionHelper::containsDockWidget(MainWindow::VIEW_SECTIONS view, const QString &name) const {

    return m_centralWidgetToDockWidgetsMap.contains(view) && m_centralWidgetToDockWidgetsMap[view].contains(name);
}

QDockWidget *MenuActionHelper::getDockWidget(MainWindow::VIEW_SECTIONS view, const QString &name) const {
    if(!m_centralWidgetToDockWidgetsMap.contains(view))
        return NULL;
    return m_centralWidgetToDockWidgetsMap[view].value(name);
}

void MenuActionHelper::showTool(bool show) {
    //Called when a menu item is clicked on, regardless of view.
    QAction* act = qobject_cast<QAction *>(sender());
    Q_ASSERT(act);
    if (m_menuToDockNameMap.contains(act)) {
        QString name = m_menuToDockNameMap[act];
        emit needToShowDockWidget(name, show);
    }
}

void MenuActionHelper::setDockWidgetTitleBarsEnabled(bool enabled)
{
    m_dockWidgetTitleBarsEnabled = enabled;
    for (int i = 0; i < m_dockWidgets.size(); i++)
        setDockWidgetTitleBar(m_dockWidgets[i]);
}


void MenuActionHelper::setAdvancedMode(bool advancedMode)
{
    m_isAdvancedMode = advancedMode;
    for (int i = 0; i < m_dockWidgets.size(); i++)
        setDockWidgetTitleBar(m_dockWidgets[i]);
}

void MenuActionHelper::setDockWidgetTitleBar(QDockWidget* widget)
{
    Q_ASSERT(widget);
    QWidget* oldTitleBar = widget->titleBarWidget();

    // In advanced mode, we use the default titlebar provided by Qt.
    if (m_isAdvancedMode)
    {
        widget->setTitleBarWidget(0);
    }
    // Otherwise, if just a textlabel should be shown, make that the titlebar.
    else if (m_dockWidgetTitleBarsEnabled)
    {
        QLabel* label = new QLabel(widget);
        label->setText(widget->windowTitle());
        label->installEventFilter(this); //Ignore mouse clicks
        widget->installEventFilter(this); //Update label if window title changes. See eventFilter below
        widget->setTitleBarWidget(label);
    }
    // And if nothing should be shown, use an empty widget.
    else
    {
        QWidget* newTitleBar = new QWidget(widget);
        widget->setTitleBarWidget(newTitleBar);
    }

    // Be sure to clean up the old titlebar. When using QDockWidget::setTitleBarWidget(),
    // it doesn't delete the old titlebar object.
    delete oldTitleBar;
}

bool MenuActionHelper::eventFilter(QObject *object,QEvent *event)
{
    if (event->type() == QEvent::WindowTitleChange)
    {
        QDockWidget *dock = qobject_cast<QDockWidget *>(object);
        if(dock) {
            // Update the dock title bar label
            QLabel *label = dynamic_cast<QLabel *>(dock->titleBarWidget());
            if(label)
                label->setText(dock->windowTitle());
            // Now update the action label
            QString oldObjectName = dock->objectName();
            QAction *action = m_menuToDockNameMap.key(oldObjectName);
            if(action)
                action->setText(dock->windowTitle());
            //Now modify the object name - it is a strange naming scheme..
        }
    } else if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonRelease)
    {
        if(qobject_cast<QLabel *>(object))
            return true;
    }
    return QObject::eventFilter(object,event);
}