kdeui Library API Documentation

kxmlguibuilder.cpp

00001 /* This file is part of the KDE project
00002    Copyright (C) 2000 Simon Hausmann <hausmann@kde.org>
00003                       David Faure <faure@kde.org>
00004 
00005    This library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public
00007    License as published by the Free Software Foundation; either
00008    version 2 of the License, or (at your option) any later version.
00009 
00010    This library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Library General Public License for more details.
00014 
00015    You should have received a copy of the GNU Library General Public License
00016    along with this library; see the file COPYING.LIB.  If not, write to
00017    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00018    Boston, MA 02111-1307, USA.
00019 */
00020 
00021 #include "kapplication.h"
00022 #include "kxmlguibuilder.h"
00023 #include "kmenubar.h"
00024 #include "kpopupmenu.h"
00025 #include "ktoolbar.h"
00026 #include "kstatusbar.h"
00027 #include "kmainwindow.h"
00028 #include "kaction.h"
00029 #include "kglobalsettings.h"
00030 #include <klocale.h>
00031 #include <kiconloader.h>
00032 #include <kdebug.h>
00033 #include <qobjectlist.h>
00034 
00035 class KXMLGUIBuilderPrivate
00036 {
00037 public:
00038     KXMLGUIBuilderPrivate() {
00039     }
00040   ~KXMLGUIBuilderPrivate() {
00041   }
00042 
00043     QWidget *m_widget;
00044 
00045     QString tagMainWindow;
00046     QString tagMenuBar;
00047     QString tagMenu;
00048     QString tagToolBar;
00049     QString tagStatusBar;
00050 
00051     QString tagSeparator;
00052     QString tagTearOffHandle;
00053     QString tagMenuTitle;
00054 
00055     QString attrName;
00056     QString attrLineSeparator;
00057 
00058     QString attrText1;
00059     QString attrText2;
00060 
00061     QString attrIcon;
00062 
00063     KInstance *m_instance;
00064     KXMLGUIClient *m_client;
00065 };
00066 
00067 KXMLGUIBuilder::KXMLGUIBuilder( QWidget *widget )
00068 {
00069   d = new KXMLGUIBuilderPrivate;
00070   d->m_widget = widget;
00071 
00072   d->tagMainWindow = QString::fromLatin1( "mainwindow" );
00073   d->tagMenuBar = QString::fromLatin1( "menubar" );
00074   d->tagMenu = QString::fromLatin1( "menu" );
00075   d->tagToolBar = QString::fromLatin1( "toolbar" );
00076   d->tagStatusBar = QString::fromLatin1( "statusbar" );
00077 
00078   d->tagSeparator = QString::fromLatin1( "separator" );
00079   d->tagTearOffHandle = QString::fromLatin1( "tearoffhandle" );
00080   d->tagMenuTitle = QString::fromLatin1( "title" );
00081 
00082   d->attrName = QString::fromLatin1( "name" );
00083   d->attrLineSeparator = QString::fromLatin1( "lineseparator" );
00084 
00085   d->attrText1 = QString::fromLatin1( "text" );
00086   d->attrText2 = QString::fromLatin1( "Text" );
00087 
00088   d->attrIcon = QString::fromLatin1( "icon" );
00089 
00090   d->m_instance = 0;
00091   d->m_client = 0;
00092 }
00093 
00094 KXMLGUIBuilder::~KXMLGUIBuilder()
00095 {
00096   delete d;
00097 }
00098 
00099 QWidget *KXMLGUIBuilder::widget()
00100 {
00101   return d->m_widget;
00102 }
00103 
00104 QStringList KXMLGUIBuilder::containerTags() const
00105 {
00106   QStringList res;
00107   res << d->tagMenu << d->tagToolBar << d->tagMainWindow << d->tagMenuBar << d->tagStatusBar;
00108 
00109   return res;
00110 }
00111 
00112 QWidget *KXMLGUIBuilder::createContainer( QWidget *parent, int index, const QDomElement &element, int &id )
00113 {
00114   id = -1;
00115   if ( element.tagName().lower() == d->tagMainWindow )
00116   {
00117     KMainWindow *mainwindow = 0;
00118     if ( d->m_widget->inherits( "KMainWindow" ) )
00119       mainwindow = static_cast<KMainWindow *>(d->m_widget);
00120 
00121     return mainwindow;
00122   }
00123 
00124   if ( element.tagName().lower() == d->tagMenuBar )
00125   {
00126     KMenuBar *bar;
00127 
00128     if ( d->m_widget->inherits( "KMainWindow" ) )
00129       bar = static_cast<KMainWindow *>(d->m_widget)->menuBar();
00130     else
00131       bar = new KMenuBar( d->m_widget );
00132 
00133     bar->show();
00134     return bar;
00135   }
00136 
00137   if ( element.tagName().lower() == d->tagMenu )
00138   {
00139     // Look up to see if we are inside a mainwindow. If yes, then
00140     // use it as parent widget (to get kaction to plug itself into the
00141     // mainwindow). Don't use a popupmenu as parent widget, otherwise
00142     // the popup won't be hidden if it is used as a standalone menu as well.
00143     // And we don't want to set the parent for a standalone popupmenu,
00144     // otherwise its shortcuts appear.
00145     QWidget* p = parent;
00146     while ( p && !p->inherits("KMainWindow") )
00147         p = p->parentWidget();
00148 
00149     QCString name = element.attribute( d->attrName ).utf8();
00150 
00151     if (!kapp->authorizeKAction(name))
00152        return 0;
00153 
00154     KPopupMenu *popup = new KPopupMenu( p, name);
00155 
00156     QString i18nText;
00157     QCString text = element.namedItem( d->attrText1 ).toElement().text().utf8();
00158     if ( text.isEmpty() ) // try with capital T
00159       text = element.namedItem( d->attrText2 ).toElement().text().utf8();
00160 
00161     if ( text.isEmpty() ) // still no luck
00162       i18nText = i18n( "No text!" );
00163     else
00164       i18nText = i18n( text );
00165 
00166     QString icon = element.attribute( d->attrIcon );
00167     QIconSet pix;
00168 
00169     if ( !icon.isEmpty() )
00170     {
00171       KInstance *instance = d->m_instance;
00172       if ( !instance )
00173         instance = KGlobal::instance();
00174 
00175       pix = SmallIconSet( icon, 16, instance );
00176     }
00177 
00178     if ( parent && parent->inherits( "KMenuBar" ) )
00179     {
00180       if ( !icon.isEmpty() )
00181         id = static_cast<KMenuBar *>(parent)->insertItem( pix, i18nText, popup, -1, index );
00182       else
00183         id = static_cast<KMenuBar *>(parent)->insertItem( i18nText, popup, -1, index );
00184     }
00185     else if ( parent && parent->inherits( "QPopupMenu" ) )
00186     {
00187       if ( !icon.isEmpty() )
00188         id = static_cast<QPopupMenu *>(parent)->insertItem( pix, i18nText, popup, -1, index );
00189       else
00190         id = static_cast<QPopupMenu *>(parent)->insertItem( i18nText, popup, -1, index );
00191     }
00192 
00193     return popup;
00194   }
00195 
00196   if ( element.tagName().lower() == d->tagToolBar )
00197   {
00198     bool honor = (element.attribute( d->attrName ) == "mainToolBar");
00199 
00200     QCString name = element.attribute( d->attrName ).utf8();
00201 
00202     KToolBar *bar = static_cast<KToolBar*>(d->m_widget->child( name, "KToolBar" ));
00203     if( !bar )
00204     {
00205        bar = new KToolBar( d->m_widget, name, honor, false );
00206     }
00207 
00208     if ( d->m_widget->inherits( "KMainWindow" ) )
00209     {
00210         if ( d->m_client && !d->m_client->xmlFile().isEmpty() )
00211             bar->setXMLGUIClient( d->m_client );
00212     }
00213 
00214     bar->loadState( element );
00215 
00216     return bar;
00217   }
00218 
00219   if ( element.tagName().lower() == d->tagStatusBar )
00220   {
00221     if ( d->m_widget->inherits( "KMainWindow" ) )
00222     {
00223       KMainWindow *mainWin = static_cast<KMainWindow *>(d->m_widget);
00224       mainWin->statusBar()->show();
00225       return mainWin->statusBar();
00226     }
00227     KStatusBar *bar = new KStatusBar( d->m_widget );
00228     return bar;
00229   }
00230 
00231   return 0L;
00232 }
00233 
00234 void KXMLGUIBuilder::removeContainer( QWidget *container, QWidget *parent, QDomElement &element, int id )
00235 {
00236   // Warning parent can be 0L
00237 
00238   if ( container->inherits( "QPopupMenu" ) )
00239   {
00240     if ( parent )
00241     {
00242         if ( parent->inherits( "KMenuBar" ) )
00243             static_cast<KMenuBar *>(parent)->removeItem( id );
00244         else if ( parent->inherits( "QPopupMenu" ) )
00245             static_cast<QPopupMenu *>(parent)->removeItem( id );
00246     }
00247 
00248     delete container;
00249   }
00250   else if ( container->inherits( "KToolBar" ) )
00251   {
00252     KToolBar *tb = static_cast<KToolBar *>( container );
00253 
00254     tb->saveState( element );
00255     delete tb;
00256   }
00257   else if ( container->inherits( "KMenuBar" ) )
00258   {
00259     KMenuBar *mb = static_cast<KMenuBar *>( container );
00260     mb->hide();
00261     // Don't delete menubar - it can be reused by createContainer.
00262     // If you decide that you do need to delete the menubar, make
00263     // sure that QMainWindow::d->mb does not point to a deleted
00264     // menubar object.
00265   }
00266   else if ( container->inherits( "KStatusBar" ) )
00267   {
00268     if ( d->m_widget->inherits( "KMainWindow" ) )
00269         container->hide();
00270     else
00271       delete static_cast<KStatusBar *>(container);
00272   }
00273   else
00274      kdWarning() << "Unhandled container to remove : " << container->className() << endl;
00275 }
00276 
00277 QStringList KXMLGUIBuilder::customTags() const
00278 {
00279   QStringList res;
00280   res << d->tagSeparator << d->tagTearOffHandle << d->tagMenuTitle;
00281   return res;
00282 }
00283 
00284 int KXMLGUIBuilder::createCustomElement( QWidget *parent, int index, const QDomElement &element )
00285 {
00286   if ( element.tagName().lower() == d->tagSeparator )
00287   {
00288     if ( parent->inherits( "QPopupMenu" ) )
00289     {
00290       // Don't insert multiple separators in a row
00291       QPopupMenu *menu = static_cast<QPopupMenu *>(parent);
00292       int count = menu->count();
00293       if (count)
00294       {
00295          int previousId = -1;
00296          if ((index == -1) || (index > count))
00297             previousId = menu->idAt(count-1);
00298          else if (index > 0)
00299             previousId = menu->idAt(index-1);
00300          if (previousId != -1)
00301          {
00302             if (menu->text(previousId).isEmpty() &&
00303                 !menu->iconSet(previousId) &&
00304                 !menu->pixmap(previousId))
00305                return 0;
00306          }
00307       }
00308       // Don't insert a separator at the top of the menu
00309       if(count == 0)
00310         return 0;
00311       else
00312         return menu->insertSeparator( index );
00313     }
00314     else if ( parent->inherits( "QMenuBar" ) )
00315        return static_cast<QMenuBar *>(parent)->insertSeparator( index );
00316     else if ( parent->inherits( "KToolBar" ) )
00317     {
00318       KToolBar *bar = static_cast<KToolBar *>( parent );
00319 
00320       bool isLineSep = false;
00321 
00322       QDomNamedNodeMap attributes = element.attributes();
00323       unsigned int i = 0;
00324       for (; i < attributes.length(); i++ )
00325       {
00326         QDomAttr attr = attributes.item( i ).toAttr();
00327 
00328         if ( attr.name().lower() == d->attrLineSeparator &&
00329              attr.value().lower() == QString::fromLatin1("true") )
00330         {
00331           isLineSep = true;
00332           break;
00333         }
00334       }
00335 
00336       int id = KAction::getToolButtonID();
00337 
00338       if ( isLineSep )
00339           bar->insertLineSeparator( index, id );
00340       else
00341           bar->insertSeparator( index, id );
00342 
00343       return id;
00344     }
00345   }
00346   else if ( element.tagName().lower() == d->tagTearOffHandle )
00347   {
00348     if ( parent->inherits( "QPopupMenu" )  && KGlobalSettings::insertTearOffHandle())
00349       return static_cast<QPopupMenu *>(parent)->insertTearOffHandle( -1, index );
00350   }
00351   else if ( element.tagName().lower() == d->tagMenuTitle )
00352   {
00353     if ( parent->inherits( "KPopupMenu" ) )
00354     {
00355       QString i18nText;
00356       QCString text = element.text().utf8();
00357 
00358       if ( text.isEmpty() )
00359         i18nText = i18n( "No text!" );
00360       else
00361         i18nText = i18n( text );
00362 
00363       QString icon = element.attribute( d->attrIcon );
00364       QPixmap pix;
00365 
00366       if ( !icon.isEmpty() )
00367       {
00368         KInstance *instance = d->m_instance;
00369         if ( !instance )
00370           instance = KGlobal::instance();
00371 
00372         pix = SmallIcon( icon, instance );
00373       }
00374 
00375       if ( !icon.isEmpty() )
00376         return static_cast<KPopupMenu *>(parent)->insertTitle( pix, i18nText, -1, index );
00377       else
00378         return static_cast<KPopupMenu *>(parent)->insertTitle( i18nText, -1, index );
00379     }
00380   }
00381   return 0;
00382 }
00383 
00384 void KXMLGUIBuilder::removeCustomElement( QWidget *parent, int id )
00385 {
00386   if ( parent->inherits( "QPopupMenu" ) )
00387     static_cast<QPopupMenu *>(parent)->removeItem( id );
00388   else if ( parent->inherits( "QMenuBar" ) )
00389     static_cast<QMenuBar *>(parent)->removeItem( id );
00390   else if ( parent->inherits( "KToolBar" ) )
00391     static_cast<KToolBar *>(parent)->removeItem( id );
00392 }
00393 
00394 KXMLGUIClient *KXMLGUIBuilder::builderClient() const
00395 {
00396   return d->m_client;
00397 }
00398 
00399 void KXMLGUIBuilder::setBuilderClient( KXMLGUIClient *client )
00400 {
00401   d->m_client = client;
00402   if ( client )
00403       setBuilderInstance( client->instance() );
00404 }
00405 
00406 KInstance *KXMLGUIBuilder::builderInstance() const
00407 {
00408   return d->m_instance;
00409 }
00410 
00411 void KXMLGUIBuilder::setBuilderInstance( KInstance *instance )
00412 {
00413   d->m_instance = instance;
00414 }
00415 
00416 void KXMLGUIBuilder::finalizeGUI( KXMLGUIClient * )
00417 {
00418     if ( !d->m_widget || !d->m_widget->inherits( "KMainWindow" ) )
00419         return;
00420 #if 0
00421     KToolBar *toolbar = 0;
00422     QListIterator<KToolBar> it( ( (KMainWindow*)d->m_widget )->toolBarIterator() );
00423     while ( ( toolbar = it.current() ) ) {
00424         kdDebug() << "KXMLGUIBuilder::finalizeGUI toolbar=" << (void*)toolbar << endl;
00425         ++it;
00426         toolbar->positionYourself();
00427     }
00428 #else
00429     static_cast<KMainWindow *>(d->m_widget)->finalizeGUI( false );
00430 #endif
00431 }
00432 
00433 void KXMLGUIBuilder::virtual_hook( int, void* )
00434 { /*BASE::virtual_hook( id, data );*/ }
00435 
KDE Logo
This file is part of the documentation for kdeui Library Version 3.2.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Thu Mar 3 19:23:13 2005 by doxygen 1.3.6 written by Dimitri van Heesch, © 1997-2003