Fix crash if key bindings specified in profile cannot be found. Improve
[personal-kdebase.git] / apps / konqueror / src / konqguiclients.cpp
blobd29c47b75aba4dcedff37cba6f3a3f3bc7701516
1 /* This file is part of the KDE project
2 Copyright (C) 1998, 1999 Simon Hausmann <hausmann@kde.org>
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; see the file COPYING. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 Boston, MA 02110-1301, USA.
20 // Own
21 #include "konqguiclients.h"
23 // KDE
24 #include <ktoggleaction.h>
25 #include <kdebug.h>
26 #include <kicon.h>
27 #include <kiconloader.h>
28 #include <klocale.h>
29 #include <kmenubar.h>
30 #include <kactioncollection.h>
31 #include <kservicetypetrader.h>
33 // Local
34 #include "konqview.h"
35 #include "konqsettingsxt.h"
36 #include "konqframe.h"
37 #include "konqframevisitor.h"
38 #include "konqframestatusbar.h"
39 #include "konqviewmanager.h"
41 PopupMenuGUIClient::PopupMenuGUIClient( const KService::List &embeddingServices,
42 KParts::BrowserExtension::ActionGroupMap& actionGroups,
43 QAction* showMenuBar, QAction* stopFullScreen )
44 : m_actionCollection(this),
45 m_embeddingServices(embeddingServices)
47 QList<QAction *> topActions;
48 if (showMenuBar) {
49 topActions.append(showMenuBar);
50 QAction* separator = new QAction(&m_actionCollection);
51 separator->setSeparator(true);
52 topActions.append(separator);
55 if (stopFullScreen) {
56 topActions.append(stopFullScreen);
57 QAction* separator = new QAction(&m_actionCollection);
58 separator->setSeparator(true);
59 topActions.append(separator);
62 if (!embeddingServices.isEmpty()) {
63 QList<QAction *> previewActions;
64 if (embeddingServices.count() == 1) {
65 KService::Ptr service = embeddingServices.first();
66 QAction* act = addEmbeddingService( 0, i18n( "Preview &in %1", service->name() ), service );
67 previewActions.append(act);
68 } else if (embeddingServices.count() > 1) {
69 KService::List::ConstIterator it = embeddingServices.begin();
70 const KService::List::ConstIterator end = embeddingServices.end();
71 int idx = 0;
72 for (; it != end; ++it, ++idx ) {
73 QAction* act = addEmbeddingService( idx, (*it)->name(), *it );
74 previewActions.append(act);
77 actionGroups.insert("preview", previewActions);
79 actionGroups.insert("topactions", topActions);
82 PopupMenuGUIClient::~PopupMenuGUIClient()
86 QAction* PopupMenuGUIClient::addEmbeddingService( int idx, const QString &name, const KService::Ptr &service )
88 QAction *act = m_actionCollection.addAction( QByteArray::number( idx ) );
89 act->setText( name );
90 act->setIcon( KIcon(service->icon()) );
91 QObject::connect(act, SIGNAL(triggered(bool)), this, SLOT( slotOpenEmbedded() ));
92 return act;
95 void PopupMenuGUIClient::slotOpenEmbedded()
97 int idx = sender()->objectName().toInt();
98 // This calls KonqMainWindow::slotOpenEmbedded(service) (delayed so that the menu is closed first)
99 emit openEmbedded(m_embeddingServices.at(idx));
102 ////
104 ToggleViewGUIClient::ToggleViewGUIClient( KonqMainWindow *mainWindow )
105 : QObject( mainWindow )
107 m_mainWindow = mainWindow;
109 KService::List offers = KServiceTypeTrader::self()->query( "Browser/View" );
110 KService::List::Iterator it = offers.begin();
111 while ( it != offers.end() )
113 QVariant prop = (*it)->property( "X-KDE-BrowserView-Toggable" );
114 QVariant orientation = (*it)->property( "X-KDE-BrowserView-ToggableView-Orientation" );
116 if ( !prop.isValid() || !prop.toBool() ||
117 !orientation.isValid() || orientation.toString().isEmpty() )
119 offers.erase( it );
120 it = offers.begin();
122 else
123 ++it;
126 m_empty = ( offers.count() == 0 );
128 if ( m_empty )
129 return;
131 KService::List::ConstIterator cIt = offers.constBegin();
132 KService::List::ConstIterator cEnd = offers.constEnd();
133 for (; cIt != cEnd; ++cIt )
135 QString description = i18n( "Show %1" , (*cIt)->name() );
136 QString name = (*cIt)->desktopEntryName();
137 //kDebug(1202) << "ToggleViewGUIClient: name=" << name;
138 KToggleAction *action = new KToggleAction( description, this );
139 mainWindow->actionCollection()->addAction( name.toLatin1(), action );
140 action->setCheckedState( KGuiItem(i18n( "Hide %1" , (*cIt)->name() )) );
142 // HACK
143 if ( (*cIt)->icon() != "unknown" )
144 action->setIcon( KIcon((*cIt)->icon()) );
146 connect( action, SIGNAL( toggled( bool ) ),
147 this, SLOT( slotToggleView( bool ) ) );
149 m_actions.insert( name, action );
151 QVariant orientation = (*cIt)->property( "X-KDE-BrowserView-ToggableView-Orientation" );
152 bool horizontal = orientation.toString().toLower() == "horizontal";
153 m_mapOrientation.insert( name, horizontal );
156 connect( m_mainWindow, SIGNAL( viewAdded( KonqView * ) ),
157 this, SLOT( slotViewAdded( KonqView * ) ) );
158 connect( m_mainWindow, SIGNAL( viewRemoved( KonqView * ) ),
159 this, SLOT( slotViewRemoved( KonqView * ) ) );
162 ToggleViewGUIClient::~ToggleViewGUIClient()
166 QList<QAction*> ToggleViewGUIClient::actions() const
168 return m_actions.values();
171 void ToggleViewGUIClient::slotToggleView( bool toggle )
173 QString serviceName = sender()->objectName();
175 bool horizontal = m_mapOrientation[ serviceName ];
177 KonqViewManager *viewManager = m_mainWindow->viewManager();
179 if ( toggle )
181 // Don't crash when doing things too quickly.
182 if ( !m_mainWindow->currentView() )
183 return;
184 KonqView *childView = viewManager->splitMainContainer( m_mainWindow->currentView(),
185 horizontal ? Qt::Vertical : Qt::Horizontal,
186 QLatin1String( "Browser/View" ),
187 serviceName,
188 !horizontal /* vertical = make it first */);
190 QList<int> newSplitterSizes;
192 if ( horizontal )
193 newSplitterSizes << 100 << 30;
194 else
195 newSplitterSizes << 30 << 100;
197 if (!childView || !childView->frame())
198 return;
200 // Toggleviews don't need their statusbar
201 childView->frame()->statusbar()->hide();
203 KonqFrameContainerBase *newContainer = childView->frame()->parentContainer();
205 if (newContainer->frameType() == KonqFrameBase::Container)
206 static_cast<KonqFrameContainer*>(newContainer)->setSizes( newSplitterSizes );
208 #if 0 // already done by splitWindow
209 if ( m_mainWindow->currentView() )
211 QString locBarURL = m_mainWindow->currentView()->url().prettyUrl(); // default one in case it doesn't set it
212 childView->openUrl( m_mainWindow->currentView()->url(), locBarURL );
214 #endif
216 // If not passive, set as active :)
217 if (!childView->isPassiveMode())
218 viewManager->setActivePart( childView->part() );
220 kDebug() << "ToggleViewGUIClient::slotToggleView setToggleView(true) on " << childView;
221 childView->setToggleView( true );
223 m_mainWindow->viewCountChanged();
226 else
228 const QList<KonqView*> viewList = KonqViewCollector::collect(m_mainWindow);
229 foreach ( KonqView* view, viewList ) {
230 if ( view->service() && view->service()->desktopEntryName() == serviceName )
231 // takes care of choosing the new active view, and also calls slotViewRemoved
232 viewManager->removeView( view );
239 void ToggleViewGUIClient::saveConfig( bool add, const QString &serviceName )
241 // This is used on konqueror's startup....... so it's never used, since
242 // the K menu only contains calls to kfmclient......
243 // Well, it could be useful again in the future.
244 // Currently, the profiles save this info.
245 QStringList toggableViewsShown = KonqSettings::toggableViewsShown();
246 if (add)
248 if ( !toggableViewsShown.contains( serviceName ) )
249 toggableViewsShown.append(serviceName);
251 else
252 toggableViewsShown.removeAll(serviceName);
253 KonqSettings::setToggableViewsShown( toggableViewsShown );
256 void ToggleViewGUIClient::slotViewAdded( KonqView *view )
258 QString name = view->service()->desktopEntryName();
260 QAction *action = m_actions.value( name );
262 if ( action )
264 disconnect( action, SIGNAL( toggled( bool ) ),
265 this, SLOT( slotToggleView( bool ) ) );
266 static_cast<KToggleAction *>( action )->setChecked( true );
267 connect( action, SIGNAL( toggled( bool ) ),
268 this, SLOT( slotToggleView( bool ) ) );
270 saveConfig( true, name );
272 // KonqView::isToggleView() is not set yet.. so just check for the orientation
274 #if 0
275 QVariant vert = view->service()->property( "X-KDE-BrowserView-ToggableView-Orientation");
276 bool vertical = vert.toString().toLower() == "vertical";
277 QVariant nohead = view->service()->property( "X-KDE-BrowserView-ToggableView-NoHeader");
278 bool noheader = nohead.isValid() ? nohead.toBool() : false;
279 // if it is a vertical toggle part, turn on the header.
280 // this works even when konq loads the view from a profile.
281 if ( vertical && (!noheader))
283 view->frame()->header()->setText(view->service()->name());
284 view->frame()->header()->setAction(action);
286 #endif
290 void ToggleViewGUIClient::slotViewRemoved( KonqView *view )
292 QString name = view->service()->desktopEntryName();
294 QAction *action = m_actions.value( name );
296 if ( action )
298 disconnect( action, SIGNAL( toggled( bool ) ),
299 this, SLOT( slotToggleView( bool ) ) );
300 static_cast<KToggleAction *>( action )->setChecked( false );
301 connect( action, SIGNAL( toggled( bool ) ),
302 this, SLOT( slotToggleView( bool ) ) );
303 saveConfig( false, name );
307 #include "konqguiclients.moc"