kdelibs/kdeui/xmlgui/ktoolbarhandler.cpp

253 lines
6.7 KiB
C++
Raw Normal View History

2014-11-13 01:04:59 +02:00
/* This file is part of the KDE libraries
Copyright (C) 2002 Simon Hausmann <hausmann@kde.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License version 2 as published by the Free Software Foundation.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "ktoolbarhandler_p.h"
#include <QtXml/qdom.h>
2014-11-13 01:04:59 +02:00
#include <kaction.h>
#include <kactioncollection.h>
#include <kactionmenu.h>
#include <kauthorized.h>
#include <kguiitem.h>
#include <klocale.h>
#include <kxmlguiwindow.h>
#include <kmenu.h>
#include <ktoggletoolbaraction.h>
#include <ktoolbar.h>
#include <kxmlguifactory.h>
#include <kdebug.h>
#include <kstandardaction_p.h>
namespace
{
const char *actionListName = "show_menu_and_toolbar_actionlist";
const char *guiDescription = ""
"<!DOCTYPE kpartgui><kpartgui name=\"StandardToolBarMenuHandler\">"
"<MenuBar>"
" <Menu name=\"settings\">"
" <ActionList name=\"%1\" />"
" </Menu>"
"</MenuBar>"
"</kpartgui>";
class BarActionBuilder
{
public:
BarActionBuilder( KActionCollection *actionCollection, KXmlGuiWindow *mainWindow,
QLinkedList<KToolBar*> &oldToolBarList )
: m_actionCollection( actionCollection ), m_mainWindow( mainWindow ), m_needsRebuild( false )
{
QList<KToolBar*> toolBars = m_mainWindow->findChildren<KToolBar*>();
2014-11-13 01:04:59 +02:00
foreach( KToolBar * toolBar, toolBars) {
if ( toolBar->mainWindow() != m_mainWindow )
continue;
if ( !oldToolBarList.contains( toolBar ) )
m_needsRebuild = true;
m_toolBars.append( toolBar );
}
if ( !m_needsRebuild )
m_needsRebuild = ( oldToolBarList.count() != m_toolBars.count() );
}
bool needsRebuild() const
{
return m_needsRebuild;
}
QList<QAction*> create()
{
QList<QAction*> actions;
if ( !m_needsRebuild )
return actions;
foreach ( KToolBar* bar, m_toolBars )
handleToolBar( bar );
if ( m_toolBarActions.count() == 0 )
return actions;
if ( m_toolBarActions.count() == 1 ) {
const KStandardAction::KStandardActionInfo* pInfo = KStandardAction::infoPtr(KStandardAction::ShowToolbar);
KToggleToolBarAction* action = static_cast<KToggleToolBarAction *>( m_toolBarActions.first() );
action->setText( i18n( pInfo->psLabel ) );
return m_toolBarActions;
}
KActionMenu *menuAction = new KActionMenu(i18n( "Toolbars Shown" ), m_actionCollection);
m_actionCollection->addAction("toolbars_submenu_action", menuAction);
foreach ( QAction* action, m_toolBarActions )
menuAction->menu()->addAction( action );
actions.append( menuAction );
return actions;
}
const QLinkedList<KToolBar*> &toolBars() const
{
return m_toolBars;
}
private:
void handleToolBar( KToolBar *toolBar )
{
KToggleToolBarAction *action = new KToggleToolBarAction(
toolBar,
toolBar->windowTitle(),
m_actionCollection);
m_actionCollection->addAction(toolBar->objectName(), action);
// ## tooltips, whatsthis?
m_toolBarActions.append( action );
}
KActionCollection *m_actionCollection;
KXmlGuiWindow *m_mainWindow;
QLinkedList<KToolBar*> m_toolBars;
QList<QAction*> m_toolBarActions;
bool m_needsRebuild : 1;
};
}
using namespace KDEPrivate;
class ToolBarHandler::Private
{
public:
Private( ToolBarHandler *_parent )
: parent( _parent )
{
}
void clientAdded( KXMLGUIClient *client )
{
Q_UNUSED(client)
parent->setupActions();
}
void init( KXmlGuiWindow *mainWindow );
void connectToActionContainers();
void connectToActionContainer( QAction *action );
void connectToActionContainer( QWidget *container );
ToolBarHandler *parent;
QPointer<KXmlGuiWindow> mainWindow;
QList<QAction*> actions;
QLinkedList<KToolBar*> toolBars;
};
void ToolBarHandler::Private::init( KXmlGuiWindow *mw )
{
mainWindow = mw;
QObject::connect( mainWindow->guiFactory(), SIGNAL(clientAdded(KXMLGUIClient*)),
parent, SLOT(clientAdded(KXMLGUIClient*)) );
if ( parent->domDocument().documentElement().isNull() ) {
QString completeDescription = QString::fromLatin1( guiDescription )
.arg( actionListName );
parent->setXML( completeDescription, false /*merge*/ );
}
}
void ToolBarHandler::Private::connectToActionContainers()
{
foreach ( QAction* action, actions )
connectToActionContainer( action );
}
void ToolBarHandler::Private::connectToActionContainer( QAction *action )
{
uint containerCount = action->associatedWidgets().count();
for ( uint i = 0; i < containerCount; ++i )
connectToActionContainer( action->associatedWidgets().value( i ) );
}
void ToolBarHandler::Private::connectToActionContainer( QWidget *container )
{
QMenu *popupMenu = qobject_cast<QMenu *>( container );
if ( !popupMenu )
return;
connect( popupMenu, SIGNAL(aboutToShow()),
parent, SLOT(setupActions()) );
}
ToolBarHandler::ToolBarHandler( KXmlGuiWindow *mainWindow, QObject *parent )
: QObject( parent ), KXMLGUIClient( mainWindow ),
d( new Private( this ) )
{
d->init( mainWindow );
}
ToolBarHandler::~ToolBarHandler()
{
qDeleteAll( d->actions );
d->actions.clear();
delete d;
}
QAction *ToolBarHandler::toolBarMenuAction()
{
Q_ASSERT( d->actions.count() == 1 );
return d->actions.first();
}
void ToolBarHandler::setupActions()
{
if ( !factory() || !d->mainWindow )
return;
BarActionBuilder builder( actionCollection(), d->mainWindow, d->toolBars );
if ( !builder.needsRebuild() )
return;
unplugActionList( actionListName );
qDeleteAll( d->actions );
d->actions.clear();
d->actions = builder.create();
d->toolBars = builder.toolBars();
// We have no XML file associated with our action collection, so load settings from KConfig
actionCollection()->readSettings(); // #233712
plugActionList( actionListName, d->actions );
2014-11-13 01:04:59 +02:00
d->connectToActionContainers();
}
#include "moc_ktoolbarhandler_p.cpp"