2014-11-13 01:04:59 +02:00
/* This file is part of the KDE libraries
Copyright ( C ) 2000 Kurt Granroth < granroth @ kde . org >
Copyright ( C ) 2006 Hamish Rodda < rodda @ kde . org >
Copyright 2007 David Faure < faure @ 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 <kedittoolbar.h>
# include <kedittoolbar_p.h>
2015-08-11 05:56:07 +03:00
# include <QtGui/qevent.h>
2014-11-13 01:04:59 +02:00
2015-08-11 05:56:07 +03:00
# include <QtXml/qdom.h>
2014-11-13 01:04:59 +02:00
# include <QtCore/QDir>
# include <QtCore/QFile>
2016-04-30 06:09:02 +00:00
# include <QtCore/QProcess>
# include <QtCore/QMimeData>
# include <QtGui/QHeaderView>
2014-11-13 01:04:59 +02:00
# include <QtGui/QToolButton>
# include <QtGui/QLabel>
# include <QtGui/QApplication>
# include <QtGui/QGridLayout>
# include <QtGui/QCheckBox>
2016-04-30 06:09:02 +00:00
# include <QtGui/QLayout>
2014-11-13 01:04:59 +02:00
# include <kstandarddirs.h>
# include <klistwidgetsearchline.h>
# include <klocale.h>
# include <kicon.h>
# include <kiconloader.h>
# include <kcomponentdata.h>
# include <kmessagebox.h>
# include <kxmlguifactory.h>
# include <kseparator.h>
# include <kconfig.h>
# include <kdebug.h>
# include <kpushbutton.h>
# include <ktoolbar.h>
# include <kdeversion.h>
# include <kcombobox.h>
# include <klineedit.h>
# include "kaction.h"
# include "kactioncollection.h"
static const char * const separatorstring = I18N_NOOP ( " --- separator --- " ) ;
# define SEPARATORSTRING i18n(separatorstring)
static const char * const s_XmlTypeToString [ ] = { " Shell " , " Part " , " Local " , " Merged " } ;
typedef QList < QDomElement > ToolBarList ;
namespace KDEPrivate {
/**
* Return a list of toolbar elements given a toplevel element
*/
static ToolBarList findToolBars ( const QDomElement & start )
{
2022-02-18 19:48:53 +02:00
static const QString tagToolBar = QString : : fromLatin1 ( " ToolBar " ) ;
static const QString tagMenuBar = QString : : fromLatin1 ( " MenuBar " ) ;
static const QString attrNoEdit = QString : : fromLatin1 ( " noEdit " ) ;
2014-11-13 01:04:59 +02:00
ToolBarList list ;
for ( QDomElement elem = start ; ! elem . isNull ( ) ; elem = elem . nextSiblingElement ( ) ) {
if ( elem . tagName ( ) = = tagToolBar ) {
if ( elem . attribute ( attrNoEdit ) ! = " true " )
list . append ( elem ) ;
} else {
if ( elem . tagName ( ) ! = tagMenuBar ) // there are no toolbars inside the menubar :)
list + = findToolBars ( elem . firstChildElement ( ) ) ; // recursive
}
}
return list ;
}
class XmlData
{
public :
enum XmlType { Shell = 0 , Part , Local , Merged } ;
explicit XmlData ( XmlType xmlType , const QString & xmlFile , KActionCollection * collection )
: m_isModified ( false ) ,
m_xmlFile ( xmlFile ) ,
m_type ( xmlType ) ,
m_actionCollection ( collection )
{
}
void dump ( ) const
{
2023-06-09 23:43:20 +03:00
kDebug ( ) < < " XmlData " < < this < < " type " < < s_XmlTypeToString [ m_type ] < < " xmlFile: " < < m_xmlFile ;
2014-11-13 01:04:59 +02:00
foreach ( const QDomElement & element , m_barList ) {
2023-06-09 23:43:20 +03:00
kDebug ( ) < < " ToolBar: " < < toolBarText ( element ) ;
2014-11-13 01:04:59 +02:00
}
if ( m_actionCollection )
2023-06-09 23:43:20 +03:00
kDebug ( ) < < " " < < m_actionCollection - > actions ( ) . count ( ) < < " actions in the collection. " ;
2014-11-13 01:04:59 +02:00
else
2023-06-09 23:43:20 +03:00
kDebug ( ) < < " no action collection. " ;
2014-11-13 01:04:59 +02:00
}
QString xmlFile ( ) const { return m_xmlFile ; }
XmlType type ( ) const { return m_type ; }
KActionCollection * actionCollection ( ) const { return m_actionCollection ; }
void setDomDocument ( const QDomDocument & domDoc )
{
m_document = domDoc . cloneNode ( ) . toDocument ( ) ;
m_barList = findToolBars ( m_document . documentElement ( ) ) ;
}
// Return reference, for e.g. actionPropertiesElement() to modify the document
QDomDocument & domDocument ( ) { return m_document ; }
const QDomDocument & domDocument ( ) const { return m_document ; }
/**
* Return the text ( user - visible name ) of a given toolbar
*/
QString toolBarText ( const QDomElement & it ) const ;
bool m_isModified ;
ToolBarList & barList ( ) { return m_barList ; }
const ToolBarList & barList ( ) const { return m_barList ; }
private :
ToolBarList m_barList ;
QString m_xmlFile ;
QDomDocument m_document ;
XmlType m_type ;
KActionCollection * m_actionCollection ;
} ;
QString XmlData : : toolBarText ( const QDomElement & it ) const
{
2022-02-18 19:48:53 +02:00
static const QString tagText = QString : : fromLatin1 ( " text " ) ;
static const QString tagText2 = QString : : fromLatin1 ( " Text " ) ;
static const QString attrName = QString : : fromLatin1 ( " name " ) ;
2014-11-13 01:04:59 +02:00
QString name ;
QByteArray txt ( it . namedItem ( tagText ) . toElement ( ) . text ( ) . toUtf8 ( ) ) ;
if ( txt . isEmpty ( ) )
txt = it . namedItem ( tagText2 ) . toElement ( ) . text ( ) . toUtf8 ( ) ;
if ( txt . isEmpty ( ) )
name = it . attribute ( attrName ) ;
else
name = i18n ( txt ) ;
// the name of the toolbar might depend on whether or not
// it is in kparts
if ( ( m_type = = XmlData : : Shell ) | |
( m_type = = XmlData : : Part ) ) {
QString doc_name ( m_document . documentElement ( ) . attribute ( attrName ) ) ;
name + = " < " + doc_name + ' > ' ;
}
return name ;
}
typedef QList < XmlData > XmlDataList ;
class ToolBarItem : public QListWidgetItem
{
public :
ToolBarItem ( QListWidget * parent , const QString & tag = QString ( ) , const QString & name = QString ( ) , const QString & statusText = QString ( ) )
: QListWidgetItem ( parent ) ,
m_internalTag ( tag ) ,
m_internalName ( name ) ,
m_statusText ( statusText ) ,
m_isSeparator ( false ) ,
m_isTextAlongsideIconHidden ( false )
{
// Drop between items, not onto items
setFlags ( ( flags ( ) | Qt : : ItemIsDragEnabled ) & ~ Qt : : ItemIsDropEnabled ) ;
}
void setInternalTag ( const QString & tag ) { m_internalTag = tag ; }
void setInternalName ( const QString & name ) { m_internalName = name ; }
void setStatusText ( const QString & text ) { m_statusText = text ; }
void setSeparator ( bool sep ) { m_isSeparator = sep ; }
void setTextAlongsideIconHidden ( bool hidden ) { m_isTextAlongsideIconHidden = hidden ; }
QString internalTag ( ) const { return m_internalTag ; }
QString internalName ( ) const { return m_internalName ; }
QString statusText ( ) const { return m_statusText ; }
bool isSeparator ( ) const { return m_isSeparator ; }
bool isTextAlongsideIconHidden ( ) const { return m_isTextAlongsideIconHidden ; }
int index ( ) const { return listWidget ( ) - > row ( const_cast < ToolBarItem * > ( this ) ) ; }
private :
QString m_internalTag ;
QString m_internalName ;
QString m_statusText ;
bool m_isSeparator ;
bool m_isTextAlongsideIconHidden ;
} ;
static QDataStream & operator < < ( QDataStream & s , const ToolBarItem & item ) {
s < < item . internalTag ( ) ;
s < < item . internalName ( ) ;
s < < item . statusText ( ) ;
s < < item . isSeparator ( ) ;
s < < item . isTextAlongsideIconHidden ( ) ;
return s ;
}
static QDataStream & operator > > ( QDataStream & s , ToolBarItem & item ) {
QString internalTag ;
s > > internalTag ;
item . setInternalTag ( internalTag ) ;
QString internalName ;
s > > internalName ;
item . setInternalName ( internalName ) ;
QString statusText ;
s > > statusText ;
item . setStatusText ( statusText ) ;
bool sep ;
s > > sep ;
item . setSeparator ( sep ) ;
bool hidden ;
s > > hidden ;
item . setTextAlongsideIconHidden ( hidden ) ;
return s ;
}
////
ToolBarListWidget : : ToolBarListWidget ( QWidget * parent )
: QListWidget ( parent ) ,
m_activeList ( true )
{
setDragDropMode ( QAbstractItemView : : DragDrop ) ; // no internal moves
}
QMimeData * ToolBarListWidget : : mimeData ( const QList < QListWidgetItem * > items ) const
{
if ( items . isEmpty ( ) )
return 0 ;
QMimeData * mimedata = new QMimeData ( ) ;
QByteArray data ;
{
QDataStream stream ( & data , QIODevice : : WriteOnly ) ;
// we only support single selection
ToolBarItem * item = static_cast < ToolBarItem * > ( items . first ( ) ) ;
stream < < * item ;
}
mimedata - > setData ( " application/x-kde-action-list " , data ) ;
mimedata - > setData ( " application/x-kde-source-treewidget " , m_activeList ? " active " : " inactive " ) ;
return mimedata ;
}
bool ToolBarListWidget : : dropMimeData ( int index , const QMimeData * mimeData , Qt : : DropAction action )
{
Q_UNUSED ( action )
const QByteArray data = mimeData - > data ( " application/x-kde-action-list " ) ;
if ( data . isEmpty ( ) )
return false ;
QDataStream stream ( data ) ;
const bool sourceIsActiveList = mimeData - > data ( " application/x-kde-source-treewidget " ) = = " active " ;
ToolBarItem * item = new ToolBarItem ( this ) ; // needs parent, use this temporarily
stream > > * item ;
emit dropped ( this , index , item , sourceIsActiveList ) ;
return true ;
}
ToolBarItem * ToolBarListWidget : : currentItem ( ) const
{
return static_cast < ToolBarItem * > ( QListWidget : : currentItem ( ) ) ;
}
IconTextEditDialog : : IconTextEditDialog ( QWidget * parent )
: KDialog ( parent )
{
setCaption ( i18n ( " Change Text " ) ) ;
setButtons ( Ok | Cancel ) ;
setDefaultButton ( Ok ) ;
setModal ( true ) ;
QWidget * mainWidget = new QWidget ( this ) ;
QGridLayout * layout = new QGridLayout ( mainWidget ) ;
layout - > setMargin ( 0 ) ;
m_lineEdit = new KLineEdit ( mainWidget ) ;
m_lineEdit - > setClearButtonShown ( true ) ;
QLabel * label = new QLabel ( i18n ( " Icon te&xt: " ) , this ) ;
label - > setBuddy ( m_lineEdit ) ;
layout - > addWidget ( label , 0 , 0 ) ;
layout - > addWidget ( m_lineEdit , 0 , 1 ) ;
m_cbHidden = new QCheckBox ( i18n ( " &Hide text when toolbar shows text alongside icons " ) , mainWidget ) ;
layout - > addWidget ( m_cbHidden , 1 , 1 ) ;
connect ( m_lineEdit , SIGNAL ( textChanged ( QString ) ) , SLOT ( slotTextChanged ( QString ) ) ) ;
m_lineEdit - > setFocus ( ) ;
setMainWidget ( mainWidget ) ;
setFixedHeight ( sizeHint ( ) . height ( ) ) ;
}
void IconTextEditDialog : : setIconText ( const QString & text )
{
m_lineEdit - > setText ( text ) ;
}
QString IconTextEditDialog : : iconText ( ) const
{
return m_lineEdit - > text ( ) . trimmed ( ) ;
}
void IconTextEditDialog : : setTextAlongsideIconHidden ( bool hidden )
{
m_cbHidden - > setChecked ( hidden ) ;
}
bool IconTextEditDialog : : textAlongsideIconHidden ( ) const
{
return m_cbHidden - > isChecked ( ) ;
}
void IconTextEditDialog : : slotTextChanged ( const QString & text )
{
// Do not allow empty icon text
enableButton ( Ok , ! text . trimmed ( ) . isEmpty ( ) ) ;
}
class KEditToolBarWidgetPrivate
{
public :
/**
*
* @ param collection In the old - style constructor , this is the collection passed
* to the KEditToolBar constructor .
* In the xmlguifactory - based constructor , we let KXMLGUIClient create a dummy one ,
* but it probably isn ' t used .
*/
KEditToolBarWidgetPrivate ( KEditToolBarWidget * widget ,
const KComponentData & cData , KActionCollection * collection )
: m_collection ( collection ) ,
m_widget ( widget ) ,
m_factory ( NULL ) ,
m_loadedOnce ( false )
{
m_componentData = cData ;
m_isPart = false ;
m_helpArea = 0L ;
m_kdialogProcess = 0 ;
// We want items with an icon to align with items without icon
// So we use an empty QPixmap for that
const int iconSize = widget - > style ( ) - > pixelMetric ( QStyle : : PM_SmallIconSize ) ;
m_emptyIcon = QPixmap ( iconSize , iconSize ) ;
m_emptyIcon . fill ( Qt : : transparent ) ;
}
~ KEditToolBarWidgetPrivate ( )
{
}
// private slots
void slotToolBarSelected ( int index ) ;
void slotInactiveSelectionChanged ( ) ;
void slotActiveSelectionChanged ( ) ;
void slotInsertButton ( ) ;
void slotRemoveButton ( ) ;
void slotUpButton ( ) ;
void slotDownButton ( ) ;
void selectActiveItem ( const QString & ) ;
void slotChangeIcon ( ) ;
void slotChangeIconText ( ) ;
void slotProcessExited ( ) ;
void slotDropped ( ToolBarListWidget * list , int index , ToolBarItem * item , bool sourceIsActiveList ) ;
void setupLayout ( ) ;
void initOldStyle ( const QString & file , bool global , const QString & defaultToolbar ) ;
void initFromFactory ( KXMLGUIFactory * factory , const QString & defaultToolbar ) ;
void loadToolBarCombo ( const QString & defaultToolbar ) ;
void loadActions ( const QDomElement & elem ) ;
QString xmlFile ( const QString & xml_file ) const
{
return xml_file . isEmpty ( ) ? QString ( m_componentData . componentName ( ) ) + " ui.rc " :
xml_file ;
}
/**
* Load in the specified XML file and dump the raw xml
*/
QString loadXMLFile ( const QString & _xml_file )
{
QString raw_xml ;
QString xml_file = xmlFile ( _xml_file ) ;
//kDebug() << "loadXMLFile xml_file=" << xml_file;
if ( ! QDir : : isRelativePath ( xml_file ) )
raw_xml = KXMLGUIFactory : : readConfigFile ( xml_file ) ;
else
raw_xml = KXMLGUIFactory : : readConfigFile ( xml_file , m_componentData ) ;
return raw_xml ;
}
/**
* Look for a given item in the current toolbar
*/
QDomElement findElementForToolBarItem ( const ToolBarItem * item ) const
{
2022-02-18 19:48:53 +02:00
static const QString attrName = QString : : fromLatin1 ( " name " ) ;
2023-06-09 23:43:20 +03:00
// kDebug() << "looking for name=" << item->internalName() << "and tag=" << item->internalTag();
2014-11-13 01:04:59 +02:00
for ( QDomNode n = m_currentToolBarElem . firstChild ( ) ; ! n . isNull ( ) ; n = n . nextSibling ( ) )
{
QDomElement elem = n . toElement ( ) ;
if ( ( elem . attribute ( attrName ) = = item - > internalName ( ) ) & &
( elem . tagName ( ) = = item - > internalTag ( ) ) )
return elem ;
}
2023-06-09 23:43:20 +03:00
// kDebug() << "no item found in the DOM with name=" << item->internalName() << "and tag=" << item->internalTag();
2014-11-13 01:04:59 +02:00
return QDomElement ( ) ;
}
void insertActive ( ToolBarItem * item , ToolBarItem * before , bool prepend = false ) ;
void removeActive ( ToolBarItem * item ) ;
void moveActive ( ToolBarItem * item , ToolBarItem * before ) ;
void updateLocal ( QDomElement & elem ) ;
# ifndef NDEBUG
void dump ( ) const
{
XmlDataList : : const_iterator xit = m_xmlFiles . begin ( ) ;
for ( ; xit ! = m_xmlFiles . end ( ) ; + + xit ) {
( * xit ) . dump ( ) ;
}
}
# endif
KComboBox * m_toolbarCombo ;
QToolButton * m_upAction ;
QToolButton * m_removeAction ;
QToolButton * m_insertAction ;
QToolButton * m_downAction ;
//QValueList<KAction*> m_actionList;
KActionCollection * m_collection ;
KEditToolBarWidget * m_widget ;
KXMLGUIFactory * m_factory ;
KComponentData m_componentData ;
QPixmap m_emptyIcon ;
XmlData * m_currentXmlData ;
QDomElement m_currentToolBarElem ;
QString m_xmlFile ;
QString m_globalFile ;
QString m_rcFile ;
QDomDocument m_localDoc ;
ToolBarList m_barList ;
ToolBarListWidget * m_inactiveList ;
ToolBarListWidget * m_activeList ;
XmlDataList m_xmlFiles ;
QLabel * m_comboLabel ;
KSeparator * m_comboSeparator ;
QLabel * m_helpArea ;
KPushButton * m_changeIcon ;
KPushButton * m_changeIconText ;
2016-04-30 06:09:02 +00:00
QProcess * m_kdialogProcess ;
2014-11-13 01:04:59 +02:00
bool m_isPart : 1 ;
bool m_hasKDialog : 1 ;
bool m_loadedOnce : 1 ;
} ;
}
using namespace KDEPrivate ;
class KEditToolBarPrivate {
public :
KEditToolBarPrivate ( KEditToolBar * q ) : q ( q ) ,
m_accept ( false ) , m_global ( false ) ,
m_collection ( 0 ) , m_factory ( 0 ) , m_widget ( 0 ) { }
void init ( ) ;
void _k_slotOk ( ) ;
void _k_slotApply ( ) ;
void _k_acceptOK ( bool ) ;
void _k_slotDefault ( ) ;
KEditToolBar * q ;
bool m_accept ;
// Save parameters for recreating widget after resetting toolbar
bool m_global ;
KActionCollection * m_collection ;
QString m_file ;
QString m_defaultToolBar ;
KXMLGUIFactory * m_factory ;
KEditToolBarWidget * m_widget ;
} ;
K_GLOBAL_STATIC ( QString , s_defaultToolBarName )
KEditToolBar : : KEditToolBar ( KActionCollection * collection ,
QWidget * parent )
: KDialog ( parent ) ,
d ( new KEditToolBarPrivate ( this ) )
{
d - > m_widget = new KEditToolBarWidget ( collection , this ) ;
d - > init ( ) ;
d - > m_collection = collection ;
}
KEditToolBar : : KEditToolBar ( KXMLGUIFactory * factory ,
QWidget * parent )
: KDialog ( parent ) ,
d ( new KEditToolBarPrivate ( this ) )
{
d - > m_widget = new KEditToolBarWidget ( this ) ;
d - > init ( ) ;
d - > m_factory = factory ;
}
void KEditToolBarPrivate : : init ( )
{
m_accept = false ;
m_factory = 0 ;
q - > setDefaultToolBar ( QString ( ) ) ;
q - > setCaption ( i18n ( " Configure Toolbars " ) ) ;
q - > setButtons ( KDialog : : Default | KDialog : : Ok | KDialog : : Apply | KDialog : : Cancel ) ;
q - > setDefaultButton ( KDialog : : Ok ) ;
q - > setModal ( false ) ;
q - > setMainWidget ( m_widget ) ;
q - > connect ( m_widget , SIGNAL ( enableOk ( bool ) ) , SLOT ( _k_acceptOK ( bool ) ) ) ;
q - > connect ( m_widget , SIGNAL ( enableOk ( bool ) ) , SLOT ( enableButtonApply ( bool ) ) ) ;
q - > enableButtonApply ( false ) ;
q - > connect ( q , SIGNAL ( okClicked ( ) ) , SLOT ( _k_slotOk ( ) ) ) ;
q - > connect ( q , SIGNAL ( applyClicked ( ) ) , SLOT ( _k_slotApply ( ) ) ) ;
q - > connect ( q , SIGNAL ( defaultClicked ( ) ) , SLOT ( _k_slotDefault ( ) ) ) ;
q - > setMinimumSize ( q - > sizeHint ( ) ) ;
}
void KEditToolBar : : setResourceFile ( const QString & file , bool global )
{
d - > m_file = file ;
d - > m_global = global ;
d - > m_widget - > load ( d - > m_file , d - > m_global , d - > m_defaultToolBar ) ;
}
KEditToolBar : : ~ KEditToolBar ( )
{
delete d ;
s_defaultToolBarName - > clear ( ) ;
}
void KEditToolBar : : setDefaultToolBar ( const QString & toolBarName )
{
if ( toolBarName . isEmpty ( ) ) {
d - > m_defaultToolBar = * s_defaultToolBarName ;
} else {
d - > m_defaultToolBar = toolBarName ;
}
}
void KEditToolBarPrivate : : _k_acceptOK ( bool b )
{
q - > enableButtonOk ( b ) ;
m_accept = b ;
}
void KEditToolBarPrivate : : _k_slotDefault ( )
{
if ( KMessageBox : : warningContinueCancel ( q , i18n ( " Do you really want to reset all toolbars of this application to their default? The changes will be applied immediately. " ) , i18n ( " Reset Toolbars " ) , KGuiItem ( i18n ( " Reset " ) ) ) ! = KMessageBox : : Continue )
return ;
KEditToolBarWidget * oldWidget = m_widget ;
m_widget = 0 ;
m_accept = false ;
if ( m_factory )
{
foreach ( KXMLGUIClient * client , m_factory - > clients ( ) )
{
const QString file = client - > localXMLFile ( ) ;
if ( file . isEmpty ( ) )
continue ;
2023-06-09 23:43:20 +03:00
kDebug ( ) < < " Deleting local xml file " < < file ;
2014-11-13 01:04:59 +02:00
// << "for client" << client << typeid(*client).name();
if ( QFile : : exists ( file ) )
if ( ! QFile : : remove ( file ) )
kWarning ( ) < < " Could not delete " < < file ;
}
// Reload the xml files in all clients, now that the local files are gone
oldWidget - > rebuildKXMLGUIClients ( ) ;
m_widget = new KEditToolBarWidget ( q ) ;
m_widget - > load ( m_factory , m_defaultToolBar ) ;
}
else
{
int slash = m_file . lastIndexOf ( ' / ' ) + 1 ;
if ( slash )
m_file = m_file . mid ( slash ) ;
QString xml_file = KStandardDirs : : locateLocal ( " data " , KGlobal : : mainComponent ( ) . componentName ( ) + ' / ' + m_file ) ;
if ( QFile : : exists ( xml_file ) )
if ( ! QFile : : remove ( xml_file ) )
kWarning ( ) < < " Could not delete " < < xml_file ;
m_widget = new KEditToolBarWidget ( m_collection , q ) ;
q - > setResourceFile ( m_file , m_global ) ;
}
// Copy the geometry to minimize UI flicker
m_widget - > setGeometry ( oldWidget - > geometry ( ) ) ;
q - > setMainWidget ( m_widget ) ;
delete oldWidget ;
q - > connect ( m_widget , SIGNAL ( enableOk ( bool ) ) , SLOT ( _k_acceptOK ( bool ) ) ) ;
q - > connect ( m_widget , SIGNAL ( enableOk ( bool ) ) , SLOT ( enableButtonApply ( bool ) ) ) ;
q - > enableButtonApply ( false ) ;
emit q - > newToolBarConfig ( ) ;
}
void KEditToolBarPrivate : : _k_slotOk ( )
{
if ( ! m_accept ) {
q - > reject ( ) ;
return ;
}
if ( ! m_widget - > save ( ) )
{
// some error box here is needed
}
else
{
// Do not emit the "newToolBarConfig" signal again here if the "Apply"
// button was already pressed and no further changes were made.
if ( q - > isButtonEnabled ( KDialog : : Apply ) ) {
emit q - > newToolBarConfig ( ) ;
}
q - > accept ( ) ;
}
}
void KEditToolBarPrivate : : _k_slotApply ( )
{
( void ) m_widget - > save ( ) ;
q - > enableButtonApply ( false ) ;
emit q - > newToolBarConfig ( ) ;
}
void KEditToolBar : : setGlobalDefaultToolBar ( const char * toolbarName )
{
* s_defaultToolBarName = QString : : fromLatin1 ( toolbarName ) ;
}
KEditToolBarWidget : : KEditToolBarWidget ( KActionCollection * collection ,
QWidget * parent )
: QWidget ( parent ) ,
d ( new KEditToolBarWidgetPrivate ( this , componentData ( ) , collection ) )
{
d - > setupLayout ( ) ;
}
KEditToolBarWidget : : KEditToolBarWidget ( QWidget * parent )
: QWidget ( parent ) ,
d ( new KEditToolBarWidgetPrivate ( this , componentData ( ) , KXMLGUIClient : : actionCollection ( ) /*create new one*/ ) )
{
d - > setupLayout ( ) ;
}
KEditToolBarWidget : : ~ KEditToolBarWidget ( )
{
delete d ;
}
void KEditToolBarWidget : : load ( const QString & file , bool global , const QString & defaultToolBar )
{
d - > initOldStyle ( file , global , defaultToolBar ) ;
}
void KEditToolBarWidget : : load ( KXMLGUIFactory * factory , const QString & defaultToolBar )
{
d - > initFromFactory ( factory , defaultToolBar ) ;
}
void KEditToolBarWidgetPrivate : : initOldStyle ( const QString & resourceFile ,
bool global ,
const QString & defaultToolBar )
{
//TODO: make sure we can call this multiple times?
if ( m_loadedOnce ) {
return ;
}
m_loadedOnce = true ;
//d->m_actionList = collection->actions();
// handle the merging
if ( global )
m_widget - > loadStandardsXmlFile ( ) ; // ui_standards.rc
const QString localXML = loadXMLFile ( resourceFile ) ;
m_widget - > setXML ( localXML , global ? true /*merge*/ : false ) ;
// first, get all of the necessary info for our local xml
XmlData local ( XmlData : : Local , xmlFile ( resourceFile ) , m_collection ) ;
QDomDocument domDoc ;
domDoc . setContent ( localXML ) ;
local . setDomDocument ( domDoc ) ;
m_xmlFiles . append ( local ) ;
// then, the merged one (ui_standards + local xml)
XmlData merge ( XmlData : : Merged , QString ( ) , m_collection ) ;
merge . setDomDocument ( m_widget - > domDocument ( ) ) ;
m_xmlFiles . append ( merge ) ;
# ifndef NDEBUG
dump ( ) ;
# endif
// now load in our toolbar combo box
loadToolBarCombo ( defaultToolBar ) ;
m_widget - > adjustSize ( ) ;
m_widget - > setMinimumSize ( m_widget - > sizeHint ( ) ) ;
}
void KEditToolBarWidgetPrivate : : initFromFactory ( KXMLGUIFactory * factory ,
const QString & defaultToolBar )
{
//TODO: make sure we can call this multiple times?
if ( m_loadedOnce ) {
return ;
}
m_loadedOnce = true ;
m_factory = factory ;
// add all of the client data
bool first = true ;
foreach ( KXMLGUIClient * client , factory - > clients ( ) )
{
if ( client - > xmlFile ( ) . isEmpty ( ) )
continue ;
XmlData : : XmlType type = XmlData : : Part ;
if ( first ) {
type = XmlData : : Shell ;
first = false ;
Q_ASSERT ( ! client - > localXMLFile ( ) . isEmpty ( ) ) ; // where would we save changes??
}
XmlData data ( type , client - > localXMLFile ( ) , client - > actionCollection ( ) ) ;
QDomDocument domDoc = client - > domDocument ( ) ;
data . setDomDocument ( domDoc ) ;
m_xmlFiles . append ( data ) ;
//d->m_actionList += client->actionCollection()->actions();
}
# ifndef NDEBUG
//d->dump();
# endif
// now load in our toolbar combo box
loadToolBarCombo ( defaultToolBar ) ;
m_widget - > adjustSize ( ) ;
m_widget - > setMinimumSize ( m_widget - > sizeHint ( ) ) ;
m_widget - > actionCollection ( ) - > addAssociatedWidget ( m_widget ) ;
foreach ( QAction * action , m_widget - > actionCollection ( ) - > actions ( ) )
action - > setShortcutContext ( Qt : : WidgetWithChildrenShortcut ) ;
}
bool KEditToolBarWidget : : save ( )
{
2023-06-09 23:43:20 +03:00
//kDebug() << "KEditToolBarWidget::save";
2014-11-13 01:04:59 +02:00
XmlDataList : : Iterator it = d - > m_xmlFiles . begin ( ) ;
for ( ; it ! = d - > m_xmlFiles . end ( ) ; + + it )
{
// let's not save non-modified files
if ( ! ( ( * it ) . m_isModified ) )
continue ;
// let's also skip (non-existent) merged files
if ( ( * it ) . type ( ) = = XmlData : : Merged )
continue ;
// Add noMerge="1" to all the menus since we are saving the merged data
QDomNodeList menuNodes = ( * it ) . domDocument ( ) . elementsByTagName ( " Menu " ) ;
2016-05-26 14:57:49 +00:00
for ( int i = 0 ; i < menuNodes . length ( ) ; + + i )
2014-11-13 01:04:59 +02:00
{
QDomNode menuNode = menuNodes . item ( i ) ;
QDomElement menuElement = menuNode . toElement ( ) ;
if ( menuElement . isNull ( ) ) continue ;
menuElement . setAttribute ( " noMerge " , " 1 " ) ;
}
kDebug ( ) < < ( * it ) . domDocument ( ) . toString ( ) ;
2023-06-09 23:43:20 +03:00
kDebug ( ) < < " Saving " < < ( * it ) . xmlFile ( ) ;
2014-11-13 01:04:59 +02:00
// if we got this far, we might as well just save it
KXMLGUIFactory : : saveConfigFile ( ( * it ) . domDocument ( ) , ( * it ) . xmlFile ( ) ) ;
}
if ( ! d - > m_factory )
return true ;
rebuildKXMLGUIClients ( ) ;
return true ;
}
void KEditToolBarWidget : : rebuildKXMLGUIClients ( )
{
if ( ! d - > m_factory )
return ;
const QList < KXMLGUIClient * > clients = d - > m_factory - > clients ( ) ;
2023-06-09 23:43:20 +03:00
// kDebug() << "factory: " << clients.count() << " clients";
2014-11-13 01:04:59 +02:00
// remove the elements starting from the last going to the first
if ( ! clients . count ( ) )
return ;
QListIterator < KXMLGUIClient * > clientIterator = clients ;
clientIterator . toBack ( ) ;
while ( clientIterator . hasPrevious ( ) ) {
KXMLGUIClient * client = clientIterator . previous ( ) ;
2023-06-09 23:43:20 +03:00
// kDebug() << "factory->removeClient " << client;
2014-11-13 01:04:59 +02:00
d - > m_factory - > removeClient ( client ) ;
}
KXMLGUIClient * firstClient = clients . first ( ) ;
// now, rebuild the gui from the first to the last
2023-06-09 23:43:20 +03:00
// kDebug() << "rebuilding the gui";
2014-11-13 01:04:59 +02:00
foreach ( KXMLGUIClient * client , clients )
{
2023-06-09 23:43:20 +03:00
//kDebug() << "updating client " << client << " " << client->componentData().componentName() << " xmlFile=" << client->xmlFile();
2014-11-13 01:04:59 +02:00
QString file ( client - > xmlFile ( ) ) ; // before setting ui_standards!
if ( ! file . isEmpty ( ) )
{
// passing an empty stream forces the clients to reread the XML
client - > setXMLGUIBuildDocument ( QDomDocument ( ) ) ;
// for the shell, merge in ui_standards.rc
if ( client = = firstClient ) // same assumption as in the ctor: first==shell
client - > loadStandardsXmlFile ( ) ;
// and this forces it to use the *new* XML file
client - > setXMLFile ( file , client = = firstClient /* merge if shell */ ) ;
// [we can't use reloadXML, it doesn't load ui_standards.rc]
}
}
// Now we can add the clients to the factory
// We don't do it in the loop above because adding a part automatically
// adds its plugins, so we must make sure the plugins were updated first.
foreach ( KXMLGUIClient * client , clients ) {
d - > m_factory - > addClient ( client ) ;
}
}
void KEditToolBarWidgetPrivate : : setupLayout ( )
{
// the toolbar name combo
m_comboLabel = new QLabel ( i18n ( " &Toolbar: " ) , m_widget ) ;
m_toolbarCombo = new KComboBox ( m_widget ) ;
m_comboLabel - > setBuddy ( m_toolbarCombo ) ;
m_comboSeparator = new KSeparator ( m_widget ) ;
QObject : : connect ( m_toolbarCombo , SIGNAL ( activated ( int ) ) ,
m_widget , SLOT ( slotToolBarSelected ( int ) ) ) ;
// QPushButton *new_toolbar = new QPushButton(i18n("&New"), this);
// new_toolbar->setPixmap(BarIcon("document-new", KIconLoader::SizeSmall));
// new_toolbar->setEnabled(false); // disabled until implemented
// QPushButton *del_toolbar = new QPushButton(i18n("&Delete"), this);
// del_toolbar->setPixmap(BarIcon("edit-delete", KIconLoader::SizeSmall));
// del_toolbar->setEnabled(false); // disabled until implemented
// our list of inactive actions
QLabel * inactive_label = new QLabel ( i18n ( " A&vailable actions: " ) , m_widget ) ;
m_inactiveList = new ToolBarListWidget ( m_widget ) ;
m_inactiveList - > setDragEnabled ( true ) ;
m_inactiveList - > setActiveList ( false ) ;
m_inactiveList - > setMinimumSize ( 180 , 250 ) ;
m_inactiveList - > setDropIndicatorShown ( false ) ; // #165663
inactive_label - > setBuddy ( m_inactiveList ) ;
QObject : : connect ( m_inactiveList , SIGNAL ( itemSelectionChanged ( ) ) ,
m_widget , SLOT ( slotInactiveSelectionChanged ( ) ) ) ;
QObject : : connect ( m_inactiveList , SIGNAL ( itemDoubleClicked ( QListWidgetItem * ) ) ,
m_widget , SLOT ( slotInsertButton ( ) ) ) ;
QObject : : connect ( m_inactiveList , SIGNAL ( dropped ( ToolBarListWidget * , int , ToolBarItem * , bool ) ) ,
m_widget , SLOT ( slotDropped ( ToolBarListWidget * , int , ToolBarItem * , bool ) ) ) ;
KListWidgetSearchLine * inactiveListSearchLine = new KListWidgetSearchLine ( m_widget , m_inactiveList ) ;
inactiveListSearchLine - > setClickMessage ( i18n ( " Filter " ) ) ;
// our list of active actions
QLabel * active_label = new QLabel ( i18n ( " Curr&ent actions: " ) , m_widget ) ;
m_activeList = new ToolBarListWidget ( m_widget ) ;
m_activeList - > setDragEnabled ( true ) ;
m_activeList - > setActiveList ( true ) ;
// With Qt-4.1 only setting MiniumWidth results in a 0-width icon column ...
m_activeList - > setMinimumSize ( m_inactiveList - > minimumWidth ( ) , 100 ) ;
active_label - > setBuddy ( m_activeList ) ;
QObject : : connect ( m_activeList , SIGNAL ( itemSelectionChanged ( ) ) ,
m_widget , SLOT ( slotActiveSelectionChanged ( ) ) ) ;
QObject : : connect ( m_activeList , SIGNAL ( itemDoubleClicked ( QListWidgetItem * ) ) ,
m_widget , SLOT ( slotRemoveButton ( ) ) ) ;
QObject : : connect ( m_activeList , SIGNAL ( dropped ( ToolBarListWidget * , int , ToolBarItem * , bool ) ) ,
m_widget , SLOT ( slotDropped ( ToolBarListWidget * , int , ToolBarItem * , bool ) ) ) ;
KListWidgetSearchLine * activeListSearchLine = new KListWidgetSearchLine ( m_widget , m_activeList ) ;
activeListSearchLine - > setClickMessage ( i18n ( " Filter " ) ) ;
// "change icon" button
m_changeIcon = new KPushButton ( i18n ( " Change &Icon... " ) , m_widget ) ;
m_changeIcon - > setIcon ( KIcon ( " preferences-desktop-icons " ) ) ;
QString kdialogExe = KStandardDirs : : findExe ( QLatin1String ( " kdialog " ) ) ;
m_hasKDialog = ! kdialogExe . isEmpty ( ) ;
m_changeIcon - > setEnabled ( m_hasKDialog & & m_activeList - > currentItem ( ) ) ;
QObject : : connect ( m_changeIcon , SIGNAL ( clicked ( ) ) ,
m_widget , SLOT ( slotChangeIcon ( ) ) ) ;
// "change icon text" button
m_changeIconText = new KPushButton ( i18n ( " Change Te&xt... " ) , m_widget ) ;
m_changeIconText - > setIcon ( KIcon ( " edit-rename " ) ) ;
m_changeIconText - > setEnabled ( m_activeList - > currentItem ( ) ! = 0 ) ;
QObject : : connect ( m_changeIconText , SIGNAL ( clicked ( ) ) ,
m_widget , SLOT ( slotChangeIconText ( ) ) ) ;
// The buttons in the middle
m_upAction = new QToolButton ( m_widget ) ;
m_upAction - > setIcon ( KIcon ( " go-up " ) ) ;
m_upAction - > setEnabled ( false ) ;
m_upAction - > setAutoRepeat ( true ) ;
QObject : : connect ( m_upAction , SIGNAL ( clicked ( ) ) , m_widget , SLOT ( slotUpButton ( ) ) ) ;
m_insertAction = new QToolButton ( m_widget ) ;
m_insertAction - > setIcon ( KIcon ( QApplication : : isRightToLeft ( ) ? " go-previous " : " go-next " ) ) ;
m_insertAction - > setEnabled ( false ) ;
QObject : : connect ( m_insertAction , SIGNAL ( clicked ( ) ) , m_widget , SLOT ( slotInsertButton ( ) ) ) ;
m_removeAction = new QToolButton ( m_widget ) ;
m_removeAction - > setIcon ( KIcon ( QApplication : : isRightToLeft ( ) ? " go-next " : " go-previous " ) ) ;
m_removeAction - > setEnabled ( false ) ;
QObject : : connect ( m_removeAction , SIGNAL ( clicked ( ) ) , m_widget , SLOT ( slotRemoveButton ( ) ) ) ;
m_downAction = new QToolButton ( m_widget ) ;
m_downAction - > setIcon ( KIcon ( " go-down " ) ) ;
m_downAction - > setEnabled ( false ) ;
m_downAction - > setAutoRepeat ( true ) ;
QObject : : connect ( m_downAction , SIGNAL ( clicked ( ) ) , m_widget , SLOT ( slotDownButton ( ) ) ) ;
m_helpArea = new QLabel ( m_widget ) ;
m_helpArea - > setWordWrap ( true ) ;
// now start with our layouts
QVBoxLayout * top_layout = new QVBoxLayout ( m_widget ) ;
top_layout - > setMargin ( 0 ) ;
QVBoxLayout * name_layout = new QVBoxLayout ( ) ;
QHBoxLayout * list_layout = new QHBoxLayout ( ) ;
QVBoxLayout * inactive_layout = new QVBoxLayout ( ) ;
QVBoxLayout * active_layout = new QVBoxLayout ( ) ;
QHBoxLayout * changeIcon_layout = new QHBoxLayout ( ) ;
QGridLayout * button_layout = new QGridLayout ( ) ;
name_layout - > addWidget ( m_comboLabel ) ;
name_layout - > addWidget ( m_toolbarCombo ) ;
// name_layout->addWidget(new_toolbar);
// name_layout->addWidget(del_toolbar);
button_layout - > setSpacing ( 0 ) ;
button_layout - > setRowStretch ( 0 , 10 ) ;
button_layout - > addWidget ( m_upAction , 1 , 1 ) ;
button_layout - > addWidget ( m_removeAction , 2 , 0 ) ;
button_layout - > addWidget ( m_insertAction , 2 , 2 ) ;
button_layout - > addWidget ( m_downAction , 3 , 1 ) ;
button_layout - > setRowStretch ( 4 , 10 ) ;
inactive_layout - > addWidget ( inactive_label ) ;
inactive_layout - > addWidget ( inactiveListSearchLine ) ;
inactive_layout - > addWidget ( m_inactiveList , 1 ) ;
active_layout - > addWidget ( active_label ) ;
active_layout - > addWidget ( activeListSearchLine ) ;
active_layout - > addWidget ( m_activeList , 1 ) ;
active_layout - > addLayout ( changeIcon_layout ) ;
changeIcon_layout - > addWidget ( m_changeIcon ) ;
changeIcon_layout - > addStretch ( 1 ) ;
changeIcon_layout - > addWidget ( m_changeIconText ) ;
list_layout - > addLayout ( inactive_layout ) ;
list_layout - > addLayout ( button_layout ) ;
list_layout - > addLayout ( active_layout ) ;
top_layout - > addLayout ( name_layout ) ;
top_layout - > addWidget ( m_comboSeparator ) ;
top_layout - > addLayout ( list_layout , 10 ) ;
top_layout - > addWidget ( m_helpArea ) ;
top_layout - > addWidget ( new KSeparator ( m_widget ) ) ;
}
void KEditToolBarWidgetPrivate : : loadToolBarCombo ( const QString & defaultToolBar )
{
const QLatin1String attrName ( " name " ) ;
// just in case, we clear our combo
m_toolbarCombo - > clear ( ) ;
int defaultToolBarId = - 1 ;
int count = 0 ;
// load in all of the toolbar names into this combo box
XmlDataList : : const_iterator xit = m_xmlFiles . constBegin ( ) ;
for ( ; xit ! = m_xmlFiles . constEnd ( ) ; + + xit )
{
// skip the merged one in favor of the local one,
// so that we can change icons
// This also makes the app-defined named for "mainToolBar" appear rather than the ui_standards-defined name.
if ( ( * xit ) . type ( ) = = XmlData : : Merged )
continue ;
// each xml file may have any number of toolbars
ToolBarList : : const_iterator it = ( * xit ) . barList ( ) . begin ( ) ;
for ( ; it ! = ( * xit ) . barList ( ) . constEnd ( ) ; + + it )
{
const QString text = ( * xit ) . toolBarText ( * it ) ;
m_toolbarCombo - > addItem ( text ) ;
const QString name = ( * it ) . attribute ( attrName ) ;
if ( defaultToolBarId = = - 1 & & name = = defaultToolBar )
defaultToolBarId = count ;
count + + ;
}
}
const bool showCombo = ( count > 1 ) ;
m_comboLabel - > setVisible ( showCombo ) ;
m_comboSeparator - > setVisible ( showCombo ) ;
m_toolbarCombo - > setVisible ( showCombo ) ;
if ( defaultToolBarId = = - 1 )
defaultToolBarId = 0 ;
// we want to the specified item selected and its actions loaded
m_toolbarCombo - > setCurrentIndex ( defaultToolBarId ) ;
slotToolBarSelected ( m_toolbarCombo - > currentIndex ( ) ) ;
}
void KEditToolBarWidgetPrivate : : loadActions ( const QDomElement & elem )
{
const QLatin1String tagSeparator ( " Separator " ) ;
const QLatin1String tagMerge ( " Merge " ) ;
const QLatin1String tagActionList ( " ActionList " ) ;
const QLatin1String tagAction ( " Action " ) ;
const QLatin1String attrName ( " name " ) ;
int sep_num = 0 ;
QString sep_name ( " separator_%1 " ) ;
// clear our lists
m_inactiveList - > clear ( ) ;
m_activeList - > clear ( ) ;
m_insertAction - > setEnabled ( false ) ;
m_removeAction - > setEnabled ( false ) ;
m_upAction - > setEnabled ( false ) ;
m_downAction - > setEnabled ( false ) ;
// We'll use this action collection
KActionCollection * actionCollection = m_currentXmlData - > actionCollection ( ) ;
// store the names of our active actions
QSet < QString > active_list ;
// Filtering message requested by translators (scripting).
KLocalizedString nameFilter = ki18nc ( " @item:intable Action name in toolbar editor " , " %1 " ) ;
// see if our current action is in this toolbar
QDomNode n = elem . firstChild ( ) ;
for ( ; ! n . isNull ( ) ; n = n . nextSibling ( ) )
{
QDomElement it = n . toElement ( ) ;
if ( it . isNull ( ) ) continue ;
if ( it . tagName ( ) = = tagSeparator )
{
ToolBarItem * act = new ToolBarItem ( m_activeList , tagSeparator , sep_name . arg ( sep_num + + ) , QString ( ) ) ;
act - > setSeparator ( true ) ;
act - > setText ( SEPARATORSTRING ) ;
it . setAttribute ( attrName , act - > internalName ( ) ) ;
continue ;
}
if ( it . tagName ( ) = = tagMerge )
{
// Merge can be named or not - use the name if there is one
QString name = it . attribute ( attrName ) ;
ToolBarItem * act = new ToolBarItem ( m_activeList , tagMerge , name , i18n ( " This element will be replaced with all the elements of an embedded component. " ) ) ;
if ( name . isEmpty ( ) )
act - > setText ( i18n ( " <Merge> " ) ) ;
else
act - > setText ( i18n ( " <Merge %1> " , name ) ) ;
continue ;
}
if ( it . tagName ( ) = = tagActionList )
{
ToolBarItem * act = new ToolBarItem ( m_activeList , tagActionList , it . attribute ( attrName ) , i18n ( " This is a dynamic list of actions. You can move it, but if you remove it you will not be able to re-add it. " ) ) ;
act - > setText ( i18n ( " ActionList: %1 " , it . attribute ( attrName ) ) ) ;
continue ;
}
// iterate through this client's actions
// This used to iterate through _all_ actions, but we don't support
// putting any action into any client...
foreach ( QAction * action , actionCollection - > actions ( ) )
{
// do we have a match?
if ( it . attribute ( attrName ) = = action - > objectName ( ) )
{
// we have a match!
ToolBarItem * act = new ToolBarItem ( m_activeList , it . tagName ( ) , action - > objectName ( ) , action - > toolTip ( ) ) ;
act - > setText ( nameFilter . subs ( KGlobal : : locale ( ) - > removeAcceleratorMarker ( action - > iconText ( ) ) ) . toString ( ) ) ;
act - > setIcon ( ! action - > icon ( ) . isNull ( ) ? action - > icon ( ) : m_emptyIcon ) ;
act - > setTextAlongsideIconHidden ( action - > priority ( ) < QAction : : NormalPriority ) ;
active_list . insert ( action - > objectName ( ) ) ;
break ;
}
}
}
// go through the rest of the collection
foreach ( QAction * action , actionCollection - > actions ( ) )
{
// skip our active ones
if ( active_list . contains ( action - > objectName ( ) ) )
continue ;
ToolBarItem * act = new ToolBarItem ( m_inactiveList , tagAction , action - > objectName ( ) , action - > toolTip ( ) ) ;
act - > setText ( nameFilter . subs ( KGlobal : : locale ( ) - > removeAcceleratorMarker ( action - > text ( ) ) ) . toString ( ) ) ;
act - > setIcon ( ! action - > icon ( ) . isNull ( ) ? action - > icon ( ) : m_emptyIcon ) ;
}
m_inactiveList - > sortItems ( Qt : : AscendingOrder ) ;
// finally, add default separators to the inactive list
ToolBarItem * act = new ToolBarItem ( 0L , tagSeparator , sep_name . arg ( sep_num + + ) , QString ( ) ) ;
act - > setSeparator ( true ) ;
act - > setText ( SEPARATORSTRING ) ;
m_inactiveList - > insertItem ( 0 , act ) ;
}
KActionCollection * KEditToolBarWidget : : actionCollection ( ) const
{
return d - > m_collection ;
}
void KEditToolBarWidgetPrivate : : slotToolBarSelected ( int index )
{
const QLatin1String attrName ( " name " ) ;
// We need to find the XmlData and toolbar element for this index
// To do that, we do the same iteration as the one which filled in the combobox.
int toolbarNumber = 0 ;
XmlDataList : : iterator xit = m_xmlFiles . begin ( ) ;
for ( ; xit ! = m_xmlFiles . end ( ) ; + + xit ) {
// skip the merged one in favor of the local one,
// so that we can change icons
if ( ( * xit ) . type ( ) = = XmlData : : Merged )
continue ;
// each xml file may have any number of toolbars
ToolBarList : : Iterator it = ( * xit ) . barList ( ) . begin ( ) ;
for ( ; it ! = ( * xit ) . barList ( ) . end ( ) ; + + it ) {
// is this our toolbar?
if ( toolbarNumber = = index ) {
// save our current settings
m_currentXmlData = & ( * xit ) ;
m_currentToolBarElem = * it ;
kDebug ( ) < < " found toolbar " < < m_currentXmlData - > toolBarText ( * it ) < < " m_currentXmlData set to " ;
m_currentXmlData - > dump ( ) ;
// If this is a Merged xmldata, clicking the "change icon" button would assert...
Q_ASSERT ( m_currentXmlData - > type ( ) ! = XmlData : : Merged ) ;
// load in our values
loadActions ( m_currentToolBarElem ) ;
if ( ( * xit ) . type ( ) = = XmlData : : Part | | ( * xit ) . type ( ) = = XmlData : : Shell )
m_widget - > setDOMDocument ( ( * xit ) . domDocument ( ) ) ;
return ;
}
+ + toolbarNumber ;
}
}
}
void KEditToolBarWidgetPrivate : : slotInactiveSelectionChanged ( )
{
if ( m_inactiveList - > selectedItems ( ) . count ( ) )
{
m_insertAction - > setEnabled ( true ) ;
QString statusText = static_cast < ToolBarItem * > ( m_inactiveList - > selectedItems ( ) . first ( ) ) - > statusText ( ) ;
m_helpArea - > setText ( i18nc ( " @label Action tooltip in toolbar editor, below the action list " , " %1 " , statusText ) ) ;
}
else
{
m_insertAction - > setEnabled ( false ) ;
m_helpArea - > setText ( QString ( ) ) ;
}
}
void KEditToolBarWidgetPrivate : : slotActiveSelectionChanged ( )
{
ToolBarItem * toolitem = 0 ;
if ( ! m_activeList - > selectedItems ( ) . isEmpty ( ) )
toolitem = static_cast < ToolBarItem * > ( m_activeList - > selectedItems ( ) . first ( ) ) ;
m_removeAction - > setEnabled ( toolitem ) ;
m_changeIcon - > setEnabled ( toolitem & &
m_hasKDialog & &
toolitem - > internalTag ( ) = = " Action " ) ;
m_changeIconText - > setEnabled ( toolitem & &
toolitem - > internalTag ( ) = = " Action " ) ;
if ( toolitem )
{
m_upAction - > setEnabled ( toolitem - > index ( ) ! = 0 ) ;
m_downAction - > setEnabled ( toolitem - > index ( ) ! = toolitem - > listWidget ( ) - > count ( ) - 1 ) ;
QString statusText = toolitem - > statusText ( ) ;
m_helpArea - > setText ( i18nc ( " @label Action tooltip in toolbar editor, below the action list " , " %1 " , statusText ) ) ;
}
else
{
m_upAction - > setEnabled ( false ) ;
m_downAction - > setEnabled ( false ) ;
m_helpArea - > setText ( QString ( ) ) ;
}
}
void KEditToolBarWidgetPrivate : : slotInsertButton ( )
{
QString internalName = static_cast < ToolBarItem * > ( m_inactiveList - > currentItem ( ) ) - > internalName ( ) ;
insertActive ( m_inactiveList - > currentItem ( ) , m_activeList - > currentItem ( ) , false ) ;
// we're modified, so let this change
emit m_widget - > enableOk ( true ) ;
slotToolBarSelected ( m_toolbarCombo - > currentIndex ( ) ) ;
selectActiveItem ( internalName ) ;
}
void KEditToolBarWidgetPrivate : : selectActiveItem ( const QString & internalName )
{
int activeItemCount = m_activeList - > count ( ) ;
for ( int i = 0 ; i < activeItemCount ; i + + )
{
ToolBarItem * item = static_cast < ToolBarItem * > ( m_activeList - > item ( i ) ) ;
if ( item - > internalName ( ) = = internalName )
{
m_activeList - > setCurrentItem ( item ) ;
break ;
}
}
}
void KEditToolBarWidgetPrivate : : slotRemoveButton ( )
{
removeActive ( m_activeList - > currentItem ( ) ) ;
slotToolBarSelected ( m_toolbarCombo - > currentIndex ( ) ) ;
}
void KEditToolBarWidgetPrivate : : insertActive ( ToolBarItem * item , ToolBarItem * before , bool prepend )
{
if ( ! item )
return ;
2022-02-18 19:48:53 +02:00
static const QString tagAction = QString : : fromLatin1 ( " Action " ) ;
static const QString tagSeparator = QString : : fromLatin1 ( " Separator " ) ;
static const QString attrName = QString : : fromLatin1 ( " name " ) ;
static const QString attrNoMerge = QString : : fromLatin1 ( " noMerge " ) ;
2014-11-13 01:04:59 +02:00
QDomElement new_item ;
// let's handle the separator specially
if ( item - > isSeparator ( ) )
new_item = m_widget - > domDocument ( ) . createElement ( tagSeparator ) ;
else
new_item = m_widget - > domDocument ( ) . createElement ( tagAction ) ;
new_item . setAttribute ( attrName , item - > internalName ( ) ) ;
Q_ASSERT ( ! m_currentToolBarElem . isNull ( ) ) ;
if ( before )
{
// we have the item in the active list which is before the new
// item.. so let's try our best to add our new item right after it
QDomElement elem = findElementForToolBarItem ( before ) ;
Q_ASSERT ( ! elem . isNull ( ) ) ;
m_currentToolBarElem . insertAfter ( new_item , elem ) ;
}
else
{
// simply put it at the beginning or the end of the list.
if ( prepend )
m_currentToolBarElem . insertBefore ( new_item , m_currentToolBarElem . firstChild ( ) ) ;
else
m_currentToolBarElem . appendChild ( new_item ) ;
}
// and set this container as a noMerge
m_currentToolBarElem . setAttribute ( attrNoMerge , " 1 " ) ;
// update the local doc
updateLocal ( m_currentToolBarElem ) ;
}
void KEditToolBarWidgetPrivate : : removeActive ( ToolBarItem * item )
{
if ( ! item )
return ;
2022-02-18 19:48:53 +02:00
static const QString attrNoMerge = QString : : fromLatin1 ( " noMerge " ) ;
2014-11-13 01:04:59 +02:00
// we're modified, so let this change
emit m_widget - > enableOk ( true ) ;
// now iterate through to find the child to nuke
QDomElement elem = findElementForToolBarItem ( item ) ;
if ( ! elem . isNull ( ) )
{
// nuke myself!
m_currentToolBarElem . removeChild ( elem ) ;
// and set this container as a noMerge
m_currentToolBarElem . setAttribute ( attrNoMerge , " 1 " ) ;
// update the local doc
updateLocal ( m_currentToolBarElem ) ;
}
}
void KEditToolBarWidgetPrivate : : slotUpButton ( )
{
ToolBarItem * item = m_activeList - > currentItem ( ) ;
if ( ! item ) {
Q_ASSERT ( false ) ;
return ;
}
int row = item - > listWidget ( ) - > row ( item ) - 1 ;
// make sure we're not the top item already
if ( row < 0 ) {
Q_ASSERT ( false ) ;
return ;
}
// we're modified, so let this change
emit m_widget - > enableOk ( true ) ;
moveActive ( item , static_cast < ToolBarItem * > ( item - > listWidget ( ) - > item ( row - 1 ) ) ) ;
}
void KEditToolBarWidgetPrivate : : moveActive ( ToolBarItem * item , ToolBarItem * before )
{
QDomElement e = findElementForToolBarItem ( item ) ;
if ( e . isNull ( ) )
return ;
// remove item
m_activeList - > takeItem ( m_activeList - > row ( item ) ) ;
// put it where it's supposed to go
m_activeList - > insertItem ( m_activeList - > row ( before ) + 1 , item ) ;
// make it selected again
m_activeList - > setCurrentItem ( item ) ;
// and do the real move in the DOM
if ( ! before )
m_currentToolBarElem . insertBefore ( e , m_currentToolBarElem . firstChild ( ) ) ;
else
m_currentToolBarElem . insertAfter ( e , findElementForToolBarItem ( ( ToolBarItem * ) before ) ) ;
// and set this container as a noMerge
2022-02-18 19:48:53 +02:00
static const QString attrNoMerge = QString : : fromLatin1 ( " noMerge " ) ;
2014-11-13 01:04:59 +02:00
m_currentToolBarElem . setAttribute ( attrNoMerge , " 1 " ) ;
// update the local doc
updateLocal ( m_currentToolBarElem ) ;
}
void KEditToolBarWidgetPrivate : : slotDownButton ( )
{
ToolBarItem * item = m_activeList - > currentItem ( ) ;
if ( ! item ) {
Q_ASSERT ( false ) ;
return ;
}
// make sure we're not the bottom item already
int newRow = item - > listWidget ( ) - > row ( item ) + 1 ;
if ( newRow > = item - > listWidget ( ) - > count ( ) ) {
Q_ASSERT ( false ) ;
return ;
}
// we're modified, so let this change
emit m_widget - > enableOk ( true ) ;
moveActive ( item , static_cast < ToolBarItem * > ( item - > listWidget ( ) - > item ( newRow ) ) ) ;
}
void KEditToolBarWidgetPrivate : : updateLocal ( QDomElement & elem )
{
2022-02-18 19:48:53 +02:00
static const QString attrName = QString : : fromLatin1 ( " name " ) ;
2014-11-13 01:04:59 +02:00
XmlDataList : : Iterator xit = m_xmlFiles . begin ( ) ;
for ( ; xit ! = m_xmlFiles . end ( ) ; + + xit )
{
if ( ( * xit ) . type ( ) = = XmlData : : Merged )
continue ;
if ( ( * xit ) . type ( ) = = XmlData : : Shell | |
( * xit ) . type ( ) = = XmlData : : Part )
{
if ( m_currentXmlData - > xmlFile ( ) = = ( * xit ) . xmlFile ( ) )
{
( * xit ) . m_isModified = true ;
return ;
}
continue ;
}
( * xit ) . m_isModified = true ;
ToolBarList : : Iterator it = ( * xit ) . barList ( ) . begin ( ) ;
for ( ; it ! = ( * xit ) . barList ( ) . end ( ) ; + + it )
{
QString name ( ( * it ) . attribute ( attrName ) ) ;
QString tag ( ( * it ) . tagName ( ) ) ;
if ( ( tag ! = elem . tagName ( ) ) | | ( name ! = elem . attribute ( attrName ) ) )
continue ;
QDomElement toolbar = ( * xit ) . domDocument ( ) . documentElement ( ) . toElement ( ) ;
toolbar . replaceChild ( elem , ( * it ) ) ;
return ;
}
// just append it
QDomElement toolbar = ( * xit ) . domDocument ( ) . documentElement ( ) . toElement ( ) ;
Q_ASSERT ( ! toolbar . isNull ( ) ) ;
toolbar . appendChild ( elem ) ;
}
}
void KEditToolBarWidgetPrivate : : slotChangeIcon ( )
{
2022-10-03 18:52:34 +03:00
// We can't use KIconDialog here, since it's in libkio
// ##### KDE4: reconsider this, e.g. move KEditToolBar to libkio
2014-11-13 01:04:59 +02:00
//if the process is already running (e.g. when somebody clicked the change button twice (see #127149)) - do nothing...
//otherwise m_kdialogProcess will be overwritten and set to zero in slotProcessExited()...crash!
if ( m_kdialogProcess & & m_kdialogProcess - > state ( ) = = QProcess : : Running )
return ;
m_currentXmlData - > dump ( ) ;
Q_ASSERT ( m_currentXmlData - > type ( ) ! = XmlData : : Merged ) ;
2016-04-30 06:09:02 +00:00
m_kdialogProcess = new QProcess ( ) ;
2014-11-13 01:04:59 +02:00
QString kdialogExe = KStandardDirs : : findExe ( QLatin1String ( " kdialog " ) ) ;
2016-04-30 06:09:02 +00:00
QStringList kdialogArgs ;
kdialogArgs < < " --caption " ;
kdialogArgs < < i18n ( " Change Icon " ) ;
kdialogArgs < < " --embed " ;
kdialogArgs < < QString : : number ( ( quintptr ) m_widget - > window ( ) - > winId ( ) ) ;
kdialogArgs < < " --geticon " ;
kdialogArgs < < " Toolbar " ;
kdialogArgs < < " Actions " ;
m_kdialogProcess - > setReadChannel ( QProcess : : StandardOutput ) ;
2016-04-30 16:23:25 +00:00
m_kdialogProcess - > start ( kdialogExe , kdialogArgs , QIODevice : : ReadOnly | QIODevice : : Text ) ;
2014-11-13 01:04:59 +02:00
if ( ! m_kdialogProcess - > waitForStarted ( ) ) {
2023-06-09 23:43:20 +03:00
kError ( ) < < " Can't run " < < kdialogExe ;
2014-11-13 01:04:59 +02:00
delete m_kdialogProcess ;
m_kdialogProcess = 0 ;
return ;
}
m_activeList - > setEnabled ( false ) ; // don't change the current item
m_toolbarCombo - > setEnabled ( false ) ; // don't change the current toolbar
QObject : : connect ( m_kdialogProcess , SIGNAL ( finished ( int , QProcess : : ExitStatus ) ) ,
m_widget , SLOT ( slotProcessExited ( ) ) ) ;
}
void KEditToolBarWidgetPrivate : : slotChangeIconText ( )
{
m_currentXmlData - > dump ( ) ;
ToolBarItem * item = m_activeList - > currentItem ( ) ;
if ( item ) {
QString iconText = item - > text ( ) ;
bool hidden = item - > isTextAlongsideIconHidden ( ) ;
IconTextEditDialog dialog ( m_widget ) ;
dialog . setIconText ( iconText ) ;
dialog . setTextAlongsideIconHidden ( hidden ) ;
bool ok = dialog . exec ( ) = = KDialog : : Accepted ;
iconText = dialog . iconText ( ) ;
hidden = dialog . textAlongsideIconHidden ( ) ;
bool hiddenChanged = hidden ! = item - > isTextAlongsideIconHidden ( ) ;
bool iconTextChanged = iconText ! = item - > text ( ) ;
if ( ! ok | | ( ! hiddenChanged & & ! iconTextChanged ) )
return ;
item - > setText ( iconText ) ;
item - > setTextAlongsideIconHidden ( hidden ) ;
Q_ASSERT ( m_currentXmlData - > type ( ) ! = XmlData : : Merged ) ;
m_currentXmlData - > m_isModified = true ;
// Get hold of ActionProperties tag
QDomElement elem = KXMLGUIFactory : : actionPropertiesElement ( m_currentXmlData - > domDocument ( ) ) ;
// Find or create an element for this action
QDomElement act_elem = KXMLGUIFactory : : findActionByName ( elem , item - > internalName ( ) , true /*create*/ ) ;
Q_ASSERT ( ! act_elem . isNull ( ) ) ;
if ( iconTextChanged )
act_elem . setAttribute ( " iconText " , iconText ) ;
if ( hiddenChanged )
act_elem . setAttribute ( " priority " , hidden ? QAction : : LowPriority : QAction : : NormalPriority ) ;
// we're modified, so let this change
emit m_widget - > enableOk ( true ) ;
}
}
void KEditToolBarWidgetPrivate : : slotProcessExited ( )
{
m_activeList - > setEnabled ( true ) ;
m_toolbarCombo - > setEnabled ( true ) ;
QString icon ;
if ( ! m_kdialogProcess ) {
2023-06-09 23:43:20 +03:00
kError ( ) < < " Something is wrong here! m_kdialogProcess is zero! " ;
return ;
2014-11-13 01:04:59 +02:00
}
icon = QString : : fromLocal8Bit ( m_kdialogProcess - > readLine ( ) ) ;
icon = icon . left ( icon . indexOf ( ' \n ' ) ) ;
2023-06-09 23:43:20 +03:00
kDebug ( ) < < " icon= " < < icon ;
2014-11-13 01:04:59 +02:00
if ( m_kdialogProcess - > exitStatus ( ) ! = QProcess : : NormalExit | |
icon . isEmpty ( ) ) {
delete m_kdialogProcess ;
m_kdialogProcess = 0 ;
return ;
}
ToolBarItem * item = m_activeList - > currentItem ( ) ;
kDebug ( ) < < item ;
if ( item ) {
item - > setIcon ( KIcon ( icon ) ) ;
Q_ASSERT ( m_currentXmlData - > type ( ) ! = XmlData : : Merged ) ;
m_currentXmlData - > m_isModified = true ;
// Get hold of ActionProperties tag
QDomElement elem = KXMLGUIFactory : : actionPropertiesElement ( m_currentXmlData - > domDocument ( ) ) ;
// Find or create an element for this action
QDomElement act_elem = KXMLGUIFactory : : findActionByName ( elem , item - > internalName ( ) , true /*create*/ ) ;
Q_ASSERT ( ! act_elem . isNull ( ) ) ;
act_elem . setAttribute ( " icon " , icon ) ;
// we're modified, so let this change
emit m_widget - > enableOk ( true ) ;
}
delete m_kdialogProcess ;
m_kdialogProcess = 0 ;
}
void KEditToolBarWidgetPrivate : : slotDropped ( ToolBarListWidget * list , int index , ToolBarItem * item , bool sourceIsActiveList )
{
//kDebug() << "slotDropped list=" << (list==m_activeList?"activeList":"inactiveList")
// << "index=" << index << "sourceIsActiveList=" << sourceIsActiveList;
if ( list = = m_activeList ) {
ToolBarItem * after = index > 0 ? static_cast < ToolBarItem * > ( list - > item ( index - 1 ) ) : 0 ;
//kDebug() << "after" << after->text() << after->internalTag();
if ( sourceIsActiveList ) {
// has been dragged within the active list (moved).
moveActive ( item , after ) ;
} else {
// dragged from the inactive list to the active list
insertActive ( item , after , true ) ;
}
} else if ( list = = m_inactiveList ) {
// has been dragged to the inactive list -> remove from the active list.
removeActive ( item ) ;
}
delete item ; // not needed anymore. must be deleted before slotToolBarSelected clears the lists
// we're modified, so let this change
emit m_widget - > enableOk ( true ) ;
slotToolBarSelected ( m_toolbarCombo - > currentIndex ( ) ) ;
}
void KEditToolBar : : showEvent ( QShowEvent * event )
{
if ( ! event - > spontaneous ( ) ) {
// The dialog has been shown, enable toolbar editing
if ( d - > m_factory ) {
// call the xmlgui-factory version
d - > m_widget - > load ( d - > m_factory , d - > m_defaultToolBar ) ;
} else {
// call the action collection version
d - > m_widget - > load ( d - > m_file , d - > m_global , d - > m_defaultToolBar ) ;
}
KToolBar : : setToolBarsEditable ( true ) ;
}
KDialog : : showEvent ( event ) ;
}
void KEditToolBar : : hideEvent ( QHideEvent * event )
{
// The dialog has been hidden, disable toolbar editing
KToolBar : : setToolBarsEditable ( false ) ;
KDialog : : hideEvent ( event ) ;
}
2015-02-27 07:40:26 +00:00
# include "moc_kedittoolbar.cpp"
# include "moc_kedittoolbar_p.cpp"