Fix crash if key bindings specified in profile cannot be found. Improve
[personal-kdebase.git] / apps / konqueror / src / konqviewmanager.cpp
blobe6414062d9730df4ec48a1318d12761b0143edc1
1 /* This file is part of the KDE project
2 Copyright (C) 1999 Simon Hausmann <hausmann@kde.org>
3 Copyright (C) 2007 Eduardo Robles Elvira <edulix@gmail.com>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 #include "konqviewmanager.h"
22 #include "konqcloseditem.h"
23 #include "konqundomanager.h"
25 #include <QtCore/QFileInfo>
26 #include <QtDBus/QDBusMessage>
27 #include <QtDBus/QDBusConnection>
29 #include <kaccelgen.h>
30 #include <kactionmenu.h>
31 #include <kstandarddirs.h>
32 #include <kstringhandler.h>
33 #include <kdebug.h>
34 #include <kapplication.h>
35 #include <kglobalsettings.h>
36 #include <ktemporaryfile.h>
37 #include <klocale.h>
38 #include <kmessagebox.h>
39 #include <ktoolbarpopupaction.h>
41 #include <kmenu.h>
43 #include <assert.h>
45 #include "konqmisc.h"
47 #include "konqview.h"
48 #include "konqframestatusbar.h"
49 #include "konqtabs.h"
50 #include "konqprofiledlg.h"
51 #include <konq_events.h>
52 #include "konqsettingsxt.h"
53 #include "konqframevisitor.h"
55 //#define DEBUG_VIEWMGR
57 KonqViewManager::KonqViewManager( KonqMainWindow *mainWindow )
58 : KParts::PartManager( mainWindow )
60 m_pMainWindow = mainWindow;
62 m_pamProfiles = 0L;
63 m_bProfileListDirty = true;
64 m_bLoadingProfile = false;
65 m_tabContainer = 0;
67 connect( this, SIGNAL( activePartChanged ( KParts::Part * ) ),
68 this, SLOT( slotActivePartChanged ( KParts::Part * ) ) );
71 KonqView* KonqViewManager::createFirstView( const QString &mimeType, const QString &serviceName )
73 //kDebug(1202) << serviceName;
74 KService::Ptr service;
75 KService::List partServiceOffers, appServiceOffers;
76 KonqViewFactory newViewFactory = createView( mimeType, serviceName, service, partServiceOffers, appServiceOffers, true /*forceAutoEmbed*/ );
77 if ( newViewFactory.isNull() )
79 kDebug(1202) << "No suitable factory found.";
80 return 0;
83 KonqView* childView = setupView( tabContainer(), newViewFactory, service, partServiceOffers, appServiceOffers, mimeType, false );
85 setActivePart( childView->part() );
87 m_tabContainer->asQWidget()->show();
88 return childView;
91 KonqViewManager::~KonqViewManager()
93 clear();
96 KonqView* KonqViewManager::splitView( KonqView* currentView,
97 Qt::Orientation orientation,
98 bool newOneFirst, bool forceAutoEmbed )
100 #ifdef DEBUG_VIEWMGR
101 kDebug(1202);
102 m_pMainWindow->dumpViewList();
103 printFullHierarchy();
104 #endif
106 KonqFrame* splitFrame = currentView->frame();
107 const QString serviceType = currentView->serviceType();
109 KService::Ptr service;
110 KService::List partServiceOffers, appServiceOffers;
112 KonqViewFactory newViewFactory = createView( serviceType, currentView->service()->desktopEntryName(), service, partServiceOffers, appServiceOffers, forceAutoEmbed );
114 if( newViewFactory.isNull() )
115 return 0; //do not split at all if we can't create the new view
117 assert( splitFrame );
119 KonqFrameContainerBase* parentContainer = splitFrame->parentContainer();
121 KonqFrameContainer* newContainer = parentContainer->splitChildFrame(splitFrame, orientation);
122 connect(newContainer, SIGNAL(ctrlTabPressed()), m_pMainWindow, SLOT(slotCtrlTabPressed()));
124 //kDebug(1202) << "Create new child";
125 KonqView *newView = setupView( newContainer, newViewFactory, service, partServiceOffers, appServiceOffers, serviceType, false );
127 #ifndef DEBUG
128 //printSizeInfo( splitFrame, parentContainer, "after child insert" );
129 #endif
131 newContainer->insertWidget(newOneFirst ? 0 : 1, newView->frame());
132 if ( newOneFirst ) {
133 newContainer->swapChildren();
136 Q_ASSERT(newContainer->count() == 2);
137 QList<int> newSplitterSizes;
138 newSplitterSizes << 50 << 50;
139 newContainer->setSizes( newSplitterSizes );
140 splitFrame->show();
141 newContainer->show();
143 assert( newView->frame() );
144 assert( newView->part() );
145 newContainer->setActiveChild( newView->frame() );
146 setActivePart( newView->part() );
148 #ifdef DEBUG_VIEWMGR
149 m_pMainWindow->dumpViewList();
150 printFullHierarchy();
151 kDebug(1202) << "done";
152 #endif
154 return newView;
157 KonqView* KonqViewManager::splitMainContainer( KonqView* currentView,
158 Qt::Orientation orientation,
159 const QString &serviceType, // This can be Browser/View, not necessarily a mimetype
160 const QString &serviceName,
161 bool newOneFirst )
163 //kDebug(1202);
165 KService::Ptr service;
166 KService::List partServiceOffers, appServiceOffers;
168 KonqViewFactory newViewFactory = createView( serviceType, serviceName, service, partServiceOffers, appServiceOffers );
170 if( newViewFactory.isNull() )
171 return 0; //do not split at all if we can't create the new view
173 // Get main frame. Note: this is NOT necessarily m_tabContainer!
174 // When having tabs plus a konsole, the main frame is a splitter (KonqFrameContainer).
175 KonqFrameBase* mainFrame = m_pMainWindow->childFrame();
177 KonqFrameContainer* newContainer = m_pMainWindow->splitChildFrame(mainFrame, orientation);
178 connect(newContainer, SIGNAL(ctrlTabPressed()), m_pMainWindow, SLOT(slotCtrlTabPressed()));
180 KonqView* childView = setupView( newContainer, newViewFactory, service, partServiceOffers, appServiceOffers, serviceType, true );
182 newContainer->insertWidget(newOneFirst ? 0 : 1, childView->frame());
183 if( newOneFirst ) {
184 newContainer->swapChildren();
187 newContainer->show();
188 newContainer->setActiveChild( mainFrame );
190 childView->openUrl( currentView->url(), currentView->locationBarURL() );
192 #ifdef DEBUG_VIEWMGR
193 m_pMainWindow->dumpViewList();
194 printFullHierarchy();
195 kDebug(1202) << "done";
196 #endif
198 return childView;
201 KonqView* KonqViewManager::addTab(const QString &serviceType, const QString &serviceName, bool passiveMode, bool openAfterCurrentPage, int pos )
203 #ifdef DEBUG_VIEWMGR
204 kDebug(1202) << "------------- KonqViewManager::addTab starting -------------";
205 m_pMainWindow->dumpViewList();
206 printFullHierarchy();
207 #endif
209 KService::Ptr service;
210 KService::List partServiceOffers, appServiceOffers;
212 Q_ASSERT( !serviceType.isEmpty() );
214 KonqViewFactory newViewFactory = createView( serviceType, serviceName, service, partServiceOffers, appServiceOffers, true /*forceAutoEmbed*/ );
216 if( newViewFactory.isNull() )
217 return 0L; //do not split at all if we can't create the new view
219 KonqView* childView = setupView( tabContainer(), newViewFactory, service, partServiceOffers, appServiceOffers, serviceType, passiveMode, openAfterCurrentPage, pos );
221 #ifdef DEBUG_VIEWMGR
222 m_pMainWindow->dumpViewList();
223 printFullHierarchy();
224 kDebug(1202) << "------------- KonqViewManager::addTab done -------------";
225 #endif
227 return childView;
230 KonqView* KonqViewManager::addTabFromHistory( KonqView* currentView, int steps, bool openAfterCurrentPage )
232 int oldPos = currentView->historyIndex();
233 int newPos = oldPos + steps;
235 const HistoryEntry * he = currentView->historyAt(newPos);
236 if(!he)
237 return 0L;
239 KonqView* newView = 0L;
240 newView = addTab( he->strServiceType, he->strServiceName, false, openAfterCurrentPage );
242 if(!newView)
243 return 0;
245 newView->copyHistory(currentView);
246 newView->setHistoryIndex(newPos);
247 newView->restoreHistory();
249 return newView;
253 void KonqViewManager::duplicateTab( KonqFrameBase* currentFrame, bool openAfterCurrentPage )
255 #ifdef DEBUG_VIEWMGR
256 kDebug(1202) << currentFrame;
257 m_pMainWindow->dumpViewList();
258 printFullHierarchy();
259 #endif
261 KTemporaryFile tempFile;
262 tempFile.open();
263 KConfig config( tempFile.fileName() );
264 KConfigGroup profileGroup( &config, "Profile" );
266 QString prefix = KonqFrameBase::frameTypeToString(currentFrame->frameType()) + QString::number(0);
267 profileGroup.writeEntry( "RootItem", prefix );
268 prefix.append( QLatin1Char( '_' ) );
269 KonqFrameBase::Options flags = KonqFrameBase::saveHistoryItems;
270 currentFrame->saveConfig( profileGroup, prefix, flags, 0L, 0, 1);
272 loadRootItem( profileGroup, tabContainer(), KUrl(), true, KUrl(), openAfterCurrentPage );
274 if (openAfterCurrentPage)
275 m_tabContainer->setCurrentIndex( m_tabContainer->currentIndex () + 1 );
276 else
277 m_tabContainer->setCurrentIndex( m_tabContainer->count() - 1 );
279 #ifdef DEBUG_VIEWMGR
280 m_pMainWindow->dumpViewList();
281 printFullHierarchy();
282 #endif
285 void KonqViewManager::breakOffTab( KonqFrameBase* currentFrame, const QSize& windowSize )
287 #ifdef DEBUG_VIEWMGR
288 kDebug(1202) << currentFrame;
289 m_pMainWindow->dumpViewList();
290 printFullHierarchy();
291 #endif
293 KTemporaryFile tempFile;
294 tempFile.open();
295 KSharedConfigPtr config = KSharedConfig::openConfig( tempFile.fileName() );
296 KConfigGroup profileGroup( config, "Profile" );
298 QString prefix = KonqFrameBase::frameTypeToString(currentFrame->frameType()) + QString::number(0);
299 profileGroup.writeEntry( "RootItem", prefix );
300 prefix.append( QLatin1Char( '_' ) );
301 KonqFrameBase::Options flags = KonqFrameBase::saveHistoryItems;
302 currentFrame->saveConfig( profileGroup, prefix, flags, 0L, 0, 1);
304 KonqMainWindow *mainWindow = new KonqMainWindow(KUrl(), m_pMainWindow->xmlFile());
306 mainWindow->viewManager()->loadViewProfileFromConfig( config, QString(), currentProfile() );
308 removeTab( currentFrame, false );
310 mainWindow->enableAllActions( true );
311 mainWindow->resize( windowSize );
312 mainWindow->activateChild();
313 mainWindow->show();
315 #ifdef DEBUG_VIEWMGR
316 m_pMainWindow->dumpViewList();
317 printFullHierarchy();
318 #endif
321 void KonqViewManager::openClosedWindow(const KonqClosedWindowItem& closedWindowItem)
323 openSavedWindow(closedWindowItem.configGroup())->show();
326 KonqMainWindow *KonqViewManager::openSavedWindow(const KConfigGroup& configGroup)
328 const QString xmluiFile =
329 configGroup.readEntry("XMLUIFile","konqueror.rc");
331 // TODO factorize to avoid code duplication with loadViewProfileFromGroup
332 KonqMainWindow *mainWindow = new KonqMainWindow(KUrl(), xmluiFile);
334 if (configGroup.readEntry( "FullScreen", false ))
336 // Full screen on
337 mainWindow->showFullScreen();
338 } else {
339 // Full screen off
340 if( mainWindow->isFullScreen())
341 mainWindow->showNormal();
342 // Window size comes from the applyMainWindowSettings call below
345 mainWindow->viewManager()->loadRootItem( configGroup, mainWindow, KUrl(), true, KUrl() );
346 mainWindow->applyMainWindowSettings( configGroup, true );
347 mainWindow->activateChild();
348 return mainWindow;
351 KonqMainWindow *KonqViewManager::openSavedWindow(const KConfigGroup& configGroup,
352 bool openTabsInsideCurrentWindow)
354 if(!openTabsInsideCurrentWindow)
356 return KonqViewManager::openSavedWindow(configGroup);
357 } else {
358 loadRootItem( configGroup, tabContainer(), KUrl(), true, KUrl() );
359 return m_pMainWindow;
364 void KonqViewManager::removeTab( KonqFrameBase* currentFrame, bool emitAboutToRemoveSignal )
366 #ifdef DEBUG_VIEWMGR
367 kDebug(1202) << currentFrame;
368 m_pMainWindow->dumpViewList();
369 printFullHierarchy();
370 #endif
372 if ( m_tabContainer->count() == 1 )
373 return;
375 if(emitAboutToRemoveSignal)
376 emit aboutToRemoveTab(currentFrame);
378 if (currentFrame->asQWidget() == m_tabContainer->currentWidget())
379 setActivePart(0);
381 m_tabContainer->childFrameRemoved(currentFrame);
383 const QList<KonqView*> viewList = KonqViewCollector::collect(currentFrame);
384 foreach ( KonqView* view, viewList )
386 if (view == m_pMainWindow->currentView())
387 setActivePart(0);
388 m_pMainWindow->removeChildView( view );
389 delete view;
392 delete currentFrame;
394 m_tabContainer->slotCurrentChanged(m_tabContainer->currentIndex());
396 #ifdef DEBUG_VIEWMGR
397 m_pMainWindow->dumpViewList();
398 printFullHierarchy();
399 #endif
402 void KonqViewManager::reloadAllTabs( )
404 foreach ( KonqFrameBase* frame, tabContainer()->childFrameList() )
406 if ( frame && frame->activeChildView())
408 if( !frame->activeChildView()->locationBarURL().isEmpty())
409 frame->activeChildView()->openUrl( frame->activeChildView()->url(), frame->activeChildView()->locationBarURL());
414 void KonqViewManager::removeOtherTabs( KonqFrameBase* currentFrame )
416 Q_ASSERT(currentFrame);
418 // currentFrame might be a frame contained inside a splitted frame so what we'll
419 // do here is just compare if the frames are inside the same tab.
420 currentFrame = m_tabContainer->tabContaining(currentFrame);
421 foreach ( KonqFrameBase* frame, m_tabContainer->childFrameList() )
423 if ( frame && m_tabContainer->tabContaining(frame) != currentFrame )
424 removeTab(frame);
429 void KonqViewManager::moveTabBackward()
431 if( m_tabContainer->count() == 1 ) return;
433 int iTab = m_tabContainer->currentIndex();
434 m_tabContainer->moveTabBackward(iTab);
437 void KonqViewManager::moveTabForward()
439 if( m_tabContainer->count() == 1 ) return;
441 int iTab = m_tabContainer->currentIndex();
442 m_tabContainer->moveTabForward(iTab);
445 void KonqViewManager::activateNextTab()
447 if( m_tabContainer->count() == 1 ) return;
449 int iTab = m_tabContainer->currentIndex();
451 iTab++;
453 if( iTab == m_tabContainer->count() )
454 iTab = 0;
456 m_tabContainer->setCurrentIndex( iTab );
459 void KonqViewManager::activatePrevTab()
461 if( m_tabContainer->count() == 1 ) return;
463 int iTab = m_tabContainer->currentIndex();
465 iTab--;
467 if( iTab == -1 )
468 iTab = m_tabContainer->count() - 1;
470 m_tabContainer->setCurrentIndex( iTab );
473 void KonqViewManager::activateTab(int position)
475 if (position<0 || m_tabContainer->count() == 1 || position>=m_tabContainer->count()) return;
477 m_tabContainer->setCurrentIndex( position );
480 void KonqViewManager::showTab( KonqView *view )
482 if (m_tabContainer->currentWidget() != view->frame())
484 m_tabContainer->setCurrentIndex( m_tabContainer->indexOf( view->frame() ) );
485 emitActivePartChanged();
489 void KonqViewManager::updatePixmaps()
491 const QList<KonqView*> viewList = KonqViewCollector::collect(tabContainer());
492 foreach ( KonqView* view, viewList )
493 view->setTabIcon( KUrl( view->locationBarURL() ) );
496 void KonqViewManager::openClosedTab(const KonqClosedTabItem& closedTab)
498 kDebug(1202);
499 loadRootItem( closedTab.configGroup(), m_tabContainer, KUrl(), true, KUrl(), false, closedTab.pos() );
501 int pos = ( closedTab.pos() < m_tabContainer->count() ) ? closedTab.pos() : m_tabContainer->count()-1;
502 kDebug(1202) << "pos, m_tabContainer->count():" << pos << m_tabContainer->count()-1;
504 m_tabContainer->setCurrentIndex( pos );
507 void KonqViewManager::removeView( KonqView *view )
509 #ifdef DEBUG_VIEWMGR
510 kDebug(1202) << view;
511 m_pMainWindow->dumpViewList();
512 printFullHierarchy();
513 #endif
515 if (!view)
516 return;
518 KonqFrame* frame = view->frame();
519 KonqFrameContainerBase* parentContainer = frame->parentContainer();
521 kDebug(1202) << "view=" << view << "frame=" << frame << "parentContainer=" << parentContainer;
523 if (parentContainer->frameType() == KonqFrameBase::Container)
525 setActivePart(0);
527 kDebug(1202) << "parentContainer is a KonqFrameContainer";
529 KonqFrameContainerBase* grandParentContainer = parentContainer->parentContainer();
530 kDebug(1202) << "grandParentContainer=" << grandParentContainer;
532 KonqFrameBase* otherFrame = static_cast<KonqFrameContainer*>(parentContainer)->otherChild( frame );
533 if( !otherFrame ) {
534 kWarning(1202) << "This shouldn't happen!" ;
535 return;
538 static_cast<KonqFrameContainer*>(parentContainer)->setAboutToBeDeleted();
540 grandParentContainer->replaceChildFrame(parentContainer, otherFrame);
542 //kDebug(1202) << "--- Removing otherFrame from parentContainer";
543 parentContainer->childFrameRemoved( otherFrame );
545 m_pMainWindow->removeChildView(view);
546 //kDebug(1202) << "--- Deleting view" << view;
547 delete view; // This deletes the view, which deletes the part, which deletes its widget
549 delete parentContainer;
551 grandParentContainer->setActiveChild( otherFrame );
552 grandParentContainer->activateChild();
554 else if (parentContainer->frameType() == KonqFrameBase::Tabs) {
555 kDebug(1202) << "parentContainer" << parentContainer << "is a KonqFrameTabs";
557 removeTab( frame );
559 else if (parentContainer->frameType() == KonqFrameBase::MainWindow)
560 kDebug(1202) << "parentContainer is a KonqMainWindow. This shouldn't be removeable, not removing.";
561 else
562 kDebug(1202) << "Unrecognized frame type, not removing.";
564 #ifdef DEBUG_VIEWMGR
565 printFullHierarchy();
566 m_pMainWindow->dumpViewList();
568 kDebug(1202) << "done";
569 #endif
572 // reimplemented from PartManager
573 void KonqViewManager::removePart( KParts::Part * part )
575 //kDebug(1202) << part;
576 // This is called when a part auto-deletes itself (case 1), or when
577 // the "delete view" above deletes, in turn, the part (case 2)
579 KParts::PartManager::removePart( part );
581 // If we were called by PartManager::slotObjectDestroyed, then the inheritance has
582 // been deleted already... Can't use inherits().
584 KonqView * view = m_pMainWindow->childView( static_cast<KParts::ReadOnlyPart *>(part) );
585 if ( view ) // the child view still exists, so we are in case 1
587 kDebug(1202) << "Found a child view";
589 view->partDeleted(); // tell the child view that the part auto-deletes itself
591 if (m_pMainWindow->mainViewsCount() == 1)
593 kDebug(1202) << "Deleting last view -> closing the window";
594 clear();
595 kDebug(1202) << "Closing m_pMainWindow" << m_pMainWindow;
596 m_pMainWindow->close(); // will delete it
597 return;
598 } else { // normal case
599 removeView( view );
603 //kDebug(1202) << part << "done";
606 void KonqViewManager::slotPassiveModePartDeleted()
608 // Passive mode parts aren't registered to the part manager,
609 // so we have to handle suicidal ones ourselves
610 KParts::ReadOnlyPart * part = const_cast<KParts::ReadOnlyPart *>( static_cast<const KParts::ReadOnlyPart *>( sender() ) );
611 disconnect( part, SIGNAL( destroyed() ), this, SLOT( slotPassiveModePartDeleted() ) );
612 kDebug(1202) << "part=" << part;
613 KonqView * view = m_pMainWindow->childView( part );
614 kDebug(1202) << "view=" << view;
615 if ( view != 0L) // the child view still exists, so the part suicided
617 view->partDeleted(); // tell the child view that the part deleted itself
618 removeView( view );
622 void KonqViewManager::viewCountChanged()
624 bool bShowActiveViewIndicator = ( m_pMainWindow->viewCount() > 1 );
625 bool bShowLinkedViewIndicator = ( m_pMainWindow->linkableViewsCount() > 1 );
627 const KonqMainWindow::MapViews mapViews = m_pMainWindow->viewMap();
628 KonqMainWindow::MapViews::ConstIterator it = mapViews.begin();
629 KonqMainWindow::MapViews::ConstIterator end = mapViews.end();
630 for ( ; it != end ; ++it )
632 KonqFrameStatusBar* sb = it.value()->frame()->statusbar();
633 sb->showActiveViewIndicator( bShowActiveViewIndicator && !it.value()->isPassiveMode() );
634 sb->showLinkedViewIndicator( bShowLinkedViewIndicator && !it.value()->isFollowActive() );
638 void KonqViewManager::clear()
640 //kDebug(1202);
641 setActivePart(0);
643 if (m_pMainWindow->childFrame() == 0) return;
645 const QList<KonqView*> viewList = KonqViewCollector::collect(m_pMainWindow);
646 if ( !viewList.isEmpty() ) {
647 //kDebug(1202) << viewList.count() << "items";
649 foreach ( KonqView* view, viewList ) {
650 m_pMainWindow->removeChildView( view );
651 //kDebug(1202) << "Deleting" << view;
652 delete view;
656 KonqFrameBase* frame = m_pMainWindow->childFrame();
657 Q_ASSERT( frame );
658 //kDebug(1202) << "deleting mainFrame ";
659 m_pMainWindow->childFrameRemoved( frame ); // will set childFrame() to NULL
660 delete frame;
661 // tab container was deleted by the above
662 m_tabContainer = 0;
665 KonqView *KonqViewManager::chooseNextView(KonqView *view)
667 //kDebug(1202) << view;
668 const KonqMainWindow::MapViews& mapViews = m_pMainWindow->viewMap();
670 KonqMainWindow::MapViews::const_iterator it = mapViews.begin();
671 const KonqMainWindow::MapViews::const_iterator end = mapViews.end();
672 if (view) { // find it in the map - can't use the key since view->part() might be 0L
673 while (it != end && it.value() != view)
674 ++it;
677 // the view should always be in the list
678 if (it == end) {
679 if (view)
680 kWarning() << "View" << view << "is not in list!" ;
681 it = mapViews.begin();
682 if (it == end)
683 return 0; // We have no view at all - this used to happen with totally-empty-profiles
686 KonqMainWindow::MapViews::const_iterator startIt = it;
688 //kDebug(1202) << "count=" << mapViews.count();
689 while (true) {
690 //kDebug(1202) << "*KonqViewManager::chooseNextView going next";
691 if (++it == end) // move to next
692 it = mapViews.begin(); // rewind on end
694 if (it == startIt && view)
695 break; // no next view found
697 KonqView *nextView = it.value();
698 if (nextView && !nextView->isPassiveMode())
699 return nextView;
700 //kDebug(1202) << "nextView=" << nextView << "passive=" << nextView->isPassiveMode();
703 //kDebug(1202) << "returning 0";
704 return 0; // no next view found
707 KonqViewFactory KonqViewManager::createView( const QString &serviceType,
708 const QString &serviceName,
709 KService::Ptr &service,
710 KService::List &partServiceOffers,
711 KService::List &appServiceOffers,
712 bool forceAutoEmbed )
714 KonqViewFactory viewFactory;
716 if( serviceType.isEmpty() && m_pMainWindow->currentView() ) {
717 //clone current view
718 KonqView *cv = m_pMainWindow->currentView();
719 QString _serviceType, _serviceName;
720 if ( cv->service()->desktopEntryName() == "konq_sidebartng" ) {
721 _serviceType = "text/html";
723 else {
724 _serviceType = cv->serviceType();
725 _serviceName = cv->service()->desktopEntryName();
728 KonqFactory konqFactory;
729 viewFactory = konqFactory.createView( _serviceType, _serviceName,
730 &service, &partServiceOffers, &appServiceOffers, forceAutoEmbed );
732 else {
733 //create view with the given servicetype
734 KonqFactory konqFactory;
735 viewFactory = konqFactory.createView( serviceType, serviceName,
736 &service, &partServiceOffers, &appServiceOffers, forceAutoEmbed );
739 return viewFactory;
742 KonqView *KonqViewManager::setupView( KonqFrameContainerBase *parentContainer,
743 KonqViewFactory &viewFactory,
744 const KService::Ptr &service,
745 const KService::List &partServiceOffers,
746 const KService::List &appServiceOffers,
747 const QString &serviceType,
748 bool passiveMode,
749 bool openAfterCurrentPage,
750 int pos )
752 //kDebug(1202) << "passiveMode=" << passiveMode;
754 QString sType = serviceType;
756 if ( sType.isEmpty() ) // TODO remove this -- after checking all callers; splitMainContainer seems to need this logic
757 sType = m_pMainWindow->currentView()->serviceType();
759 //kDebug(1202) << "creating KonqFrame with parent=" << parentContainer;
760 KonqFrame* newViewFrame = new KonqFrame( parentContainer->asQWidget(), parentContainer );
761 newViewFrame->setGeometry( 0, 0, m_pMainWindow->width(), m_pMainWindow->height() );
763 //kDebug(1202) << "Creating KonqView";
764 KonqView *v = new KonqView( viewFactory, newViewFrame,
765 m_pMainWindow, service, partServiceOffers, appServiceOffers, sType, passiveMode );
766 //kDebug(1202) << "KonqView created - v=" << v << "v->part()=" << v->part();
768 QObject::connect( v, SIGNAL( sigPartChanged( KonqView *, KParts::ReadOnlyPart *, KParts::ReadOnlyPart * ) ),
769 m_pMainWindow, SLOT( slotPartChanged( KonqView *, KParts::ReadOnlyPart *, KParts::ReadOnlyPart * ) ) );
771 m_pMainWindow->insertChildView( v );
774 int index = -1;
775 if ( openAfterCurrentPage )
776 index = m_tabContainer->currentIndex() + 1;
777 else if(pos > -1)
778 index = pos;
780 parentContainer->insertChildFrame( newViewFrame, index );
782 if (parentContainer->frameType() != KonqFrameBase::Tabs) newViewFrame->show();
784 // Don't register passive views to the part manager
785 if ( !v->isPassiveMode() ) // note that KonqView's constructor could set this to true even if passiveMode is false
786 addPart( v->part(), false );
787 else
789 // Passive views aren't registered, but we still want to detect the suicidal ones
790 connect( v->part(), SIGNAL( destroyed() ), this, SLOT( slotPassiveModePartDeleted() ) );
793 //kDebug(1202) << "done";
794 return v;
797 ///////////////// Profile stuff ////////////////
799 void KonqViewManager::saveViewProfileToFile(const QString & fileName, const QString & profileName, KonqFrameBase::Options options)
801 const QString path = KStandardDirs::locateLocal("data", QString::fromLatin1("konqueror/profiles/") +
802 fileName, KGlobal::mainComponent());
803 QFile::remove(path); // in case it exists already
805 KConfig _cfg(path, KConfig::SimpleConfig);
806 KConfigGroup profileGroup(&_cfg, "Profile");
807 if (!profileName.isEmpty())
808 profileGroup.writePathEntry("Name", profileName);
810 saveViewProfileToGroup(profileGroup, options);
812 _cfg.sync();
815 void KonqViewManager::saveViewProfileToGroup(KConfigGroup & profileGroup, KonqFrameBase::Options options)
817 if( m_pMainWindow->childFrame() ) {
818 QString prefix = KonqFrameBase::frameTypeToString(m_pMainWindow->childFrame()->frameType())
819 + QString::number(0);
820 profileGroup.writeEntry( "RootItem", prefix );
821 prefix.append( QLatin1Char( '_' ) );
822 m_pMainWindow->saveConfig( profileGroup, prefix, options, tabContainer(), 0, 1);
825 profileGroup.writeEntry( "FullScreen", m_pMainWindow->fullScreenMode());
826 profileGroup.writeEntry("XMLUIFile", m_pMainWindow->xmlFile());
828 m_pMainWindow->saveMainWindowSettings(profileGroup);
831 void KonqViewManager::loadViewProfileFromFile( const QString & path, const QString & filename,
832 const KUrl & forcedUrl, const KonqOpenURLRequest &req,
833 bool resetWindow, bool openUrl )
835 KSharedConfig::Ptr config = KSharedConfig::openConfig(path, KConfig::SimpleConfig);
836 loadViewProfileFromConfig(config, path, filename, forcedUrl, req, resetWindow, openUrl );
839 void KonqViewManager::setCurrentProfile(const QString& profileFileName)
841 m_currentProfile = profileFileName;
843 // We'll use the profile for saving window settings - so ensure we can save to it
844 const QString localPath = KStandardDirs::locateLocal("data", QString::fromLatin1("konqueror/profiles/") +
845 profileFileName, KGlobal::mainComponent());
846 kDebug() << profileFileName << "localPath=" << localPath;
847 KSharedConfigPtr cfg = KSharedConfig::openConfig(localPath, KConfig::SimpleConfig);
848 if (!QFile::exists(localPath)) {
849 const QString globalFile = KStandardDirs::locate("data", QString::fromLatin1("konqueror/profiles/") +
850 profileFileName, KGlobal::mainComponent());
851 kDebug() << "globalFile=" << globalFile;
852 if (!globalFile.isEmpty()) {
853 KSharedConfigPtr globalCfg = KSharedConfig::openConfig(globalFile, KConfig::SimpleConfig);
854 globalCfg->copyTo(localPath, cfg.data());
858 KConfigGroup profileGroup(cfg, "Profile");
859 m_currentProfileText = profileGroup.readPathEntry("Name", m_currentProfile);
861 // setProfileConfig must be done after setting m_currentProfile/m_currentProfileText
862 // We also do it after loadViewProfileFromGroup so that we can override the default size (Width=80%)
863 m_pMainWindow->setProfileConfig(profileGroup);
866 void KonqViewManager::loadViewProfileFromConfig(const KSharedConfigPtr& _cfg,
867 const QString& path,
868 const QString & filename,
869 const KUrl & forcedUrl,
870 const KonqOpenURLRequest &req,
871 bool resetWindow, bool openUrl)
873 Q_UNUSED(path); // _cfg and path could be passed to setCurrentProfile for optimization
874 // resetWindow was used to resize the window to a default size,
875 // not needed anymore, since the size is in the profile (## what about about:blank?)
876 Q_UNUSED(resetWindow);
878 KConfigGroup profileGroup(_cfg, "Profile");
880 loadViewProfileFromGroup(profileGroup, filename, forcedUrl, req, openUrl);
882 setCurrentProfile(filename);
884 #ifdef DEBUG_VIEWMGR
885 printFullHierarchy();
886 #endif
889 void KonqViewManager::loadViewProfileFromGroup( const KConfigGroup &profileGroup, const QString & filename,
890 const KUrl & forcedUrl, const KonqOpenURLRequest &req,
891 bool openUrl )
893 Q_UNUSED(filename); // could be useful in case of error messages
895 KUrl defaultURL;
896 if (m_pMainWindow->currentView())
897 defaultURL = m_pMainWindow->currentView()->url();
899 clear();
901 if (forcedUrl.url() != "about:blank") {
902 loadRootItem( profileGroup, m_pMainWindow, defaultURL, openUrl && forcedUrl.isEmpty(), forcedUrl );
903 } else {
904 // ## in this case we won't resize the window, so bool resetWindow could be useful after all?
905 m_pMainWindow->disableActionsNoView();
906 m_pMainWindow->action("clear_location")->trigger();
909 //kDebug(1202) << "after loadRootItem";
911 // Set an active part first so that we open the URL in the current view
912 // (to set the location bar correctly and asap)
913 KonqView *nextChildView = 0;
914 nextChildView = m_pMainWindow->activeChildView();
915 if (nextChildView == 0) nextChildView = chooseNextView(0);
916 setActivePart(nextChildView ? nextChildView->part() : 0);
918 // #71164
919 if (!req.browserArgs.frameName.isEmpty() && nextChildView) {
920 nextChildView->setViewName(req.browserArgs.frameName);
923 if (openUrl && !forcedUrl.isEmpty()) {
924 KonqOpenURLRequest _req(req);
925 _req.openAfterCurrentPage = KonqSettings::openAfterCurrentPage();
926 _req.forceAutoEmbed = true; // it's a new window, let's use it
928 m_pMainWindow->openUrl( nextChildView /* can be 0 for an empty profile */,
929 forcedUrl, _req.args.mimeType(), _req, _req.browserArgs.trustedSource );
931 // TODO choose a linked view if any (instead of just the first one),
932 // then open the same URL in any non-linked one
933 } else {
934 if (m_pMainWindow->locationBarURL().isEmpty()) // No URL -> the user will want to type one
935 m_pMainWindow->focusLocationBar();
938 // Window size
939 if (!m_pMainWindow->initialGeometrySet()) {
940 if (profileGroup.readEntry("FullScreen", false)) {
941 // Full screen on
942 m_pMainWindow->setWindowState(m_pMainWindow->windowState() | Qt::WindowFullScreen);
943 } else {
944 // Full screen off
945 m_pMainWindow->setWindowState(m_pMainWindow->windowState() & ~Qt::WindowFullScreen);
946 m_pMainWindow->applyWindowSizeFromProfile(profileGroup);
950 //kDebug(1202) << "done";
953 void KonqViewManager::setActivePart(KParts::Part *part, QWidget *)
955 doSetActivePart( part );
958 void KonqViewManager::doSetActivePart( KParts::Part *part )
960 //kDebug(1202) << part;
961 //if ( part )
962 // kDebug(1202) << part->metaObject()->className() << part->name();
964 KParts::Part* mainWindowActivePart = m_pMainWindow->currentView()
965 ? m_pMainWindow->currentView()->part() : 0;
966 if (part == activePart() && mainWindowActivePart == part)
968 if ( part )
969 kDebug(1202) << "Part is already active!";
970 return;
973 // Don't activate when part changed in non-active tab
974 KonqView* partView = m_pMainWindow->childView((KParts::ReadOnlyPart*)part);
975 if (partView)
977 KonqFrameContainerBase* parentContainer = partView->frame()->parentContainer();
978 if (parentContainer->frameType() == KonqFrameBase::Tabs)
980 KonqFrameTabs* parentFrameTabs = static_cast<KonqFrameTabs*>(parentContainer);
981 if (partView->frame() != parentFrameTabs->currentWidget())
982 return;
986 if (m_pMainWindow && m_pMainWindow->currentView())
987 m_pMainWindow->currentView()->setLocationBarURL(m_pMainWindow->locationBarURL());
989 KParts::PartManager::setActivePart( part );
991 if (part && part->widget())
992 part->widget()->setFocus();
994 emitActivePartChanged();
997 void KonqViewManager::slotActivePartChanged ( KParts::Part *newPart )
999 //kDebug(1202) << newPart;
1000 if (newPart == 0L) {
1001 //kDebug(1202) << "newPart = 0L , returning";
1002 return;
1004 // Send event to mainwindow - this is useful for plugins (like searchbar)
1005 KParts::PartActivateEvent ev(true, newPart, newPart->widget());
1006 QApplication::sendEvent(m_pMainWindow, &ev);
1008 KonqView * view = m_pMainWindow->childView( static_cast<KParts::ReadOnlyPart *>(newPart) );
1009 if (view == 0L) {
1010 kDebug(1202) << "No view associated with this part";
1011 return;
1013 if (view->frame()->parentContainer() == 0L) return;
1014 if (!m_bLoadingProfile) {
1015 view->frame()->statusbar()->updateActiveStatus();
1016 view->frame()->parentContainer()->setActiveChild( view->frame() );
1018 //kDebug(1202) << "done";
1021 void KonqViewManager::emitActivePartChanged()
1023 m_pMainWindow->slotPartActivated( activePart() );
1026 QSize KonqViewManager::readDefaultSize(const KConfigGroup &cfg, QWidget *widget)
1028 QString widthStr = cfg.readEntry("Width");
1029 QString heightStr = cfg.readEntry("Height");
1030 int width = -1;
1031 int height = -1;
1032 const QRect geom = KGlobalSettings::desktopGeometry(widget);
1034 bool ok;
1035 if (widthStr.endsWith('%')) {
1036 widthStr.truncate(widthStr.length()-1);
1037 const int relativeWidth = widthStr.toInt(&ok);
1038 if (ok) {
1039 width = relativeWidth * geom.width() / 100;
1041 } else {
1042 width = widthStr.toInt( &ok );
1043 if (!ok)
1044 width = -1;
1047 if (heightStr.endsWith('%')) {
1048 heightStr.truncate(heightStr.length() - 1);
1049 int relativeHeight = heightStr.toInt(&ok);
1050 if (ok) {
1051 height = relativeHeight * geom.height() / 100;
1053 } else {
1054 height = heightStr.toInt(&ok);
1055 if (!ok)
1056 height = -1;
1059 return QSize(width, height);
1062 void KonqViewManager::loadRootItem( const KConfigGroup &cfg, KonqFrameContainerBase *parent,
1063 const KUrl & defaultURL, bool openUrl,
1064 const KUrl& forcedUrl, bool openAfterCurrentPage,
1065 int pos )
1067 const QString rootItem = cfg.readEntry("RootItem", "empty");
1069 // This flag is used by KonqView, to distinguish manual view creation
1070 // from profile loading (e.g. in switchView)
1071 m_bLoadingProfile = true;
1073 loadItem( cfg, parent, rootItem, defaultURL, openUrl, forcedUrl, openAfterCurrentPage, pos );
1075 m_bLoadingProfile = false;
1077 m_pMainWindow->enableAllActions(true);
1079 // This flag disables calls to viewCountChanged while creating the views,
1080 // so we do it once at the end :
1081 viewCountChanged();
1086 void KonqViewManager::loadItem( const KConfigGroup &cfg, KonqFrameContainerBase *parent,
1087 const QString &name, const KUrl & defaultURL, bool openUrl,
1088 const KUrl& forcedUrl,
1089 bool openAfterCurrentPage, int pos )
1091 QString prefix;
1092 if (name != "InitialView") { // InitialView is old stuff, not in use anymore
1093 prefix = name + QLatin1Char( '_' );
1096 //kDebug(1202) << "begin name=" << name << "openUrl=" << openUrl;
1098 if (name.startsWith("View") || name == "empty") {
1099 // load view config
1101 QString serviceType;
1102 QString serviceName;
1103 if (name == "empty") {
1104 // An empty profile is an empty KHTML part. Makes all KHTML actions available, avoids crashes,
1105 // makes it easy to DND a URL onto it, and makes it fast to load a website from there.
1106 serviceType = "text/html";
1107 serviceName = "html";
1108 } else {
1109 serviceType = cfg.readEntry( QString::fromLatin1( "ServiceType" ).prepend( prefix ), QString("inode/directory"));
1110 serviceName = cfg.readEntry( QString::fromLatin1( "ServiceName" ).prepend( prefix ), QString() );
1111 if (serviceName == "konq_aboutpage") {
1112 if ( (!forcedUrl.isEmpty() && forcedUrl.protocol() != "about") ||
1113 (forcedUrl.isEmpty() && openUrl == false)) // e.g. window.open
1115 // No point in loading the about page if we're going to replace it with a KHTML part right away
1116 serviceType = "text/html";
1117 serviceName = "html";
1121 //kDebug(1202) << "serviceType" << serviceType << serviceName;
1123 KService::Ptr service;
1124 KService::List partServiceOffers, appServiceOffers;
1126 KonqFactory konqFactory;
1127 KonqViewFactory viewFactory = konqFactory.createView( serviceType, serviceName, &service, &partServiceOffers, &appServiceOffers, true /*forceAutoEmbed*/ );
1128 if (viewFactory.isNull()) {
1129 kWarning(1202) << "Profile Loading Error: View creation failed" ;
1130 return; //ugh..
1133 bool passiveMode = cfg.readEntry( QString::fromLatin1( "PassiveMode" ).prepend( prefix ), false );
1135 //kDebug(1202) << "Creating View Stuff; parent=" << parent;
1136 if ( parent == m_pMainWindow )
1137 parent = tabContainer();
1138 KonqView *childView = setupView( parent, viewFactory, service, partServiceOffers, appServiceOffers, serviceType, passiveMode, openAfterCurrentPage, pos );
1140 if (!childView->isFollowActive())
1141 childView->setLinkedView( cfg.readEntry( QString::fromLatin1( "LinkedView" ).prepend( prefix ), false ) );
1142 childView->setToggleView( cfg.readEntry( QString::fromLatin1( "ToggleView" ).prepend( prefix ), false ) );
1143 if( !cfg.readEntry( QString::fromLatin1( "ShowStatusBar" ).prepend( prefix ), true ) )
1144 childView->frame()->statusbar()->hide();
1146 #if 0 // currently unused
1147 KonqConfigEvent ev( cfg.config(), prefix+'_', false/*load*/);
1148 QApplication::sendEvent( childView->part(), &ev );
1149 #endif
1151 childView->frame()->show();
1153 if (openUrl) {
1154 const QString keyHistoryItems = QString::fromLatin1( "NumberOfHistoryItems" ).prepend( prefix );
1155 if( cfg.hasKey(keyHistoryItems) ) {
1156 childView->loadHistoryConfig(cfg, prefix);
1157 m_pMainWindow->updateHistoryActions();
1158 } else {
1159 // determine URL
1160 const QString urlKey = QString::fromLatin1("URL").prepend(prefix);
1161 KUrl url;
1162 if (cfg.hasKey(urlKey)) {
1163 url = cfg.readPathEntry(urlKey, QString::fromLatin1("about:blank"));
1164 } else if (urlKey == "empty_URL") { // old stuff, not in use anymore
1165 url = QString::fromLatin1("about:blank");
1166 } else {
1167 url = defaultURL;
1170 if ( !url.isEmpty() ) {
1171 //kDebug(1202) << "calling openUrl" << url;
1172 //childView->openUrl( url, url.prettyUrl() );
1173 // We need view-follows-view (for the dirtree, for instance)
1174 KonqOpenURLRequest req;
1175 if (url.protocol() != "about")
1176 req.typedUrl = url.prettyUrl();
1177 m_pMainWindow->openView( serviceType, url, childView, req );
1179 //else kDebug(1202) << "url is empty";
1182 // Do this after opening the URL, so that it's actually possible to open it :)
1183 childView->setLockedLocation( cfg.readEntry( QString::fromLatin1( "LockedLocation" ).prepend( prefix ), false ) );
1185 else if( name.startsWith("Container") ) {
1186 //kDebug(1202) << "Item is Container";
1188 //load container config
1189 QString ostr = cfg.readEntry( QString::fromLatin1( "Orientation" ).prepend( prefix ), QString() );
1190 //kDebug(1202) << "Orientation:" << ostr;
1191 Qt::Orientation o;
1192 if( ostr == "Vertical" )
1193 o = Qt::Vertical;
1194 else if( ostr == "Horizontal" )
1195 o = Qt::Horizontal;
1196 else {
1197 kWarning() << "Profile Loading Error: No orientation specified in" << name ;
1198 o = Qt::Horizontal;
1201 QList<int> sizes =
1202 cfg.readEntry( QString::fromLatin1( "SplitterSizes" ).prepend( prefix ),QList<int>());
1204 int index = cfg.readEntry( QString::fromLatin1( "activeChildIndex" ).prepend(prefix), -1 );
1206 QStringList childList = cfg.readEntry( QString::fromLatin1( "Children" ).prepend( prefix ),QStringList() );
1207 if( childList.count() < 2 )
1209 kWarning() << "Profile Loading Error: Less than two children in" << name ;
1210 // fallback to defaults
1211 loadItem( cfg, parent, "InitialView", defaultURL, openUrl, forcedUrl );
1213 else
1215 KonqFrameContainer *newContainer = new KonqFrameContainer( o, parent->asQWidget(), parent );
1216 connect(newContainer,SIGNAL(ctrlTabPressed()),m_pMainWindow,SLOT(slotCtrlTabPressed()));
1218 int tabindex = pos;
1219 if(openAfterCurrentPage && parent->frameType() == KonqFrameBase::Tabs) // Need to honor it, if possible
1220 tabindex = static_cast<KonqFrameTabs*>(parent)->currentIndex() + 1;
1221 parent->insertChildFrame( newContainer, tabindex );
1223 loadItem( cfg, newContainer, childList.at(0), defaultURL, openUrl, forcedUrl );
1224 loadItem( cfg, newContainer, childList.at(1), defaultURL, openUrl, forcedUrl );
1226 //kDebug(1202) << "setSizes" << sizes;
1227 newContainer->setSizes( sizes );
1229 if (index == 1)
1230 newContainer->setActiveChild( newContainer->secondChild() );
1231 else if (index == 0)
1232 newContainer->setActiveChild( newContainer->firstChild() );
1234 newContainer->show();
1237 else if( name.startsWith("Tabs") )
1239 //kDebug(1202) << "Item is a Tabs";
1241 int index = cfg.readEntry( QString::fromLatin1( "activeChildIndex" ).prepend(prefix), 0 );
1242 if ( !m_tabContainer ) {
1243 createTabContainer(parent->asQWidget(), parent);
1244 parent->insertChildFrame( m_tabContainer );
1247 const QStringList childList = cfg.readEntry( QString::fromLatin1( "Children" ).prepend( prefix ),QStringList() );
1248 for ( QStringList::const_iterator it = childList.begin(); it != childList.end(); ++it )
1250 loadItem( cfg, tabContainer(), *it, defaultURL, openUrl, forcedUrl );
1251 QWidget* currentPage = m_tabContainer->currentWidget();
1252 if (currentPage != 0L) {
1253 KonqView* activeChildView = dynamic_cast<KonqFrameBase*>(currentPage)->activeChildView();
1254 if (activeChildView != 0L) {
1255 activeChildView->setCaption( activeChildView->caption() );
1256 activeChildView->setTabIcon( activeChildView->url() );
1261 QWidget* w = m_tabContainer->widget(index);
1262 Q_ASSERT(w);
1263 m_tabContainer->setActiveChild( dynamic_cast<KonqFrameBase*>(w) );
1264 m_tabContainer->setCurrentIndex( index );
1265 m_tabContainer->show();
1267 else
1268 kWarning() << "Profile Loading Error: Unknown item" << name;
1270 //kDebug(1202) << "end" << name;
1273 void KonqViewManager::setProfiles( KActionMenu *profiles )
1275 m_pamProfiles = profiles;
1276 connect(m_pamProfiles->menu(), SIGNAL(triggered(QAction *)),
1277 this, SLOT(slotProfileActivated(QAction *)));
1278 connect(m_pamProfiles->menu(), SIGNAL(aboutToShow()),
1279 this, SLOT(slotProfileListAboutToShow()));
1280 //KonqMainWindow::enableAllActions will call it anyway
1281 //profileListDirty();
1284 void KonqViewManager::showProfileDlg( const QString & preselectProfile )
1286 KonqProfileDlg dlg( this, preselectProfile, m_pMainWindow );
1287 dlg.exec();
1288 profileListDirty();
1291 void KonqViewManager::slotProfileDlg()
1293 showProfileDlg( QString() );
1296 void KonqViewManager::profileListDirty( bool broadcast )
1298 if (!broadcast) {
1299 m_bProfileListDirty = true;
1300 return;
1303 // Send signal to all konqueror instances
1304 QDBusMessage message =
1305 QDBusMessage::createSignal("/KonqMain", "org.kde.Konqueror.Main", "updateAllProfileList");
1306 QDBusConnection::sessionBus().send(message);
1309 void KonqViewManager::slotProfileActivated(QAction* action)
1311 if ( tabContainer()->count() > 1 ) {
1312 if ( KMessageBox::warningContinueCancel( m_pMainWindow,
1313 i18n("You have multiple tabs open in this window.\n"
1314 "Loading a view profile will close them."),
1315 i18n("Confirmation"),
1316 KGuiItem(i18n("Load View Profile")),
1317 KStandardGuiItem::cancel(),
1318 "LoadProfileTabsConfirm" ) == KMessageBox::Cancel )
1319 return;
1321 KonqView *originalView = m_pMainWindow->currentView();
1322 bool showTabCalled = false;
1323 foreach ( KonqFrameBase* frame, m_tabContainer->childFrameList() )
1325 KonqView *view = frame->activeChildView();
1326 if (view && view->part() && (view->part()->metaObject()->indexOfProperty("modified") != -1)) {
1327 QVariant prop = view->part()->property("modified");
1328 if (prop.isValid() && prop.toBool()) {
1329 showTab( view );
1330 showTabCalled = true;
1331 if ( KMessageBox::warningContinueCancel( 0,
1332 i18n("This tab contains changes that have not been submitted.\nLoading a profile will discard these changes."),
1333 i18n("Discard Changes?"), KGuiItem(i18n("&Discard Changes")), KStandardGuiItem::cancel(), "discardchangesloadprofile") != KMessageBox::Continue )
1334 /* WE: maybe KStandardGuiItem(Discard) here? */
1336 showTab( originalView );
1337 return;
1342 if ( showTabCalled && originalView )
1343 showTab( originalView );
1346 const QString profilePath = action->data().toString();
1347 const QString fileName = KUrl(profilePath).fileName();
1348 KConfig cfg(profilePath);
1349 KConfigGroup profileGroup( &cfg, "Profile" );
1350 const QString xmluiFile = normalizedXMLFileName(profileGroup.readEntry("XMLUIFile","konqueror.rc"));
1352 //If the profile specifies an xmlgui file that differs from the currently
1353 //loaded one, then we have no choice but to recreate the window. I've
1354 //experimented with trying to get xmlgui to recreate the gui, but it is
1355 //too brittle. The only other choice is to ignore the profile which is
1356 //not very nice.
1357 if (xmluiFile != m_pMainWindow->xmlFile()) {
1358 m_pMainWindow->deleteLater();
1359 KonqMisc::createBrowserWindowFromProfile(profilePath, fileName, m_pMainWindow->currentView()->url());
1360 } else {
1361 loadViewProfileFromFile(profilePath, fileName);
1365 void KonqViewManager::slotProfileListAboutToShow()
1367 if ( !m_pamProfiles || !m_bProfileListDirty )
1368 return;
1370 KMenu *popup = m_pamProfiles->menu();
1371 popup->clear();
1373 // Fetch profiles
1374 m_mapProfileNames = KonqProfileDlg::readAllProfiles();
1376 // Generate accelerators
1377 const QStringList profileNames = m_mapProfileNames.keys();
1378 QStringList accel_strings;
1379 KAccelGen::generate(profileNames, accel_strings);
1381 // Store menu items
1382 const QStringList profilePaths = m_mapProfileNames.values();
1383 for (int i = 0; i < accel_strings.count(); ++i) {
1384 QAction* action = new QAction(accel_strings.at(i), popup);
1385 action->setData(profilePaths.at(i));
1386 popup->addAction(action);
1389 m_bProfileListDirty = false;
1392 void KonqViewManager::setLoading( KonqView *view, bool loading )
1394 m_tabContainer->setLoading(view->frame(), loading);
1397 void KonqViewManager::showHTML(bool b)
1399 foreach ( KonqFrameBase* frame, tabContainer()->childFrameList() ) {
1400 KonqView* view = frame->activeChildView();
1401 if ( view && view != m_pMainWindow->currentView() ) {
1402 view->setAllowHTML( b );
1403 if( !view->locationBarURL().isEmpty() ) {
1404 m_pMainWindow->showHTML( view, b, false );
1412 ///////////////// Debug stuff ////////////////
1414 #ifndef NDEBUG
1415 void KonqViewManager::printSizeInfo( KonqFrameBase* frame,
1416 KonqFrameContainerBase* parent,
1417 const char* msg )
1419 const QRect r = frame->asQWidget()->geometry();
1420 qDebug("Child size %s : x: %d, y: %d, w: %d, h: %d", msg, r.x(),r.y(),r.width(),r.height() );
1422 if (parent->frameType() == KonqFrameBase::Container) {
1423 const QList<int> sizes = static_cast<KonqFrameContainer*>(parent)->sizes();
1424 printf( "Parent sizes %s :", msg );
1425 foreach( int i, sizes ) {
1426 printf( " %d", i );
1428 printf("\n");
1432 class KonqDebugFrameVisitor : public KonqFrameVisitor
1434 public:
1435 KonqDebugFrameVisitor() {}
1436 virtual bool visit(KonqFrame* frame) {
1437 QString className;
1438 if ( !frame->part() )
1439 className = "NoPart!";
1440 else if ( !frame->part()->widget() )
1441 className = "NoWidget!";
1442 else
1443 className = frame->part()->widget()->metaObject()->className();
1444 kDebug(1202) << m_spaces << "KonqFrame" << frame
1445 << "visible=" << frame->isVisible()
1446 << "containing view" << frame->childView()
1447 << "and part" << frame->part()
1448 << "whose widget is a" << className;
1449 return true;
1451 virtual bool visit(KonqFrameContainer* container) {
1452 kDebug(1202) << m_spaces << "KonqFrameContainer" << container
1453 << "visible=" << container->isVisible()
1454 << "activeChild=" << container->activeChild();
1455 if (!container->activeChild())
1456 kDebug(1202) << "WARNING:" << container << "has a null active child!";
1458 m_spaces += " ";
1459 return true;
1461 virtual bool visit(KonqFrameTabs* tabs) {
1462 kDebug(1202) << m_spaces << "KonqFrameTabs" << tabs
1463 << "visible=" << tabs->isVisible()
1464 << "activeChild=" << tabs->activeChild();
1465 if (!tabs->activeChild())
1466 kDebug(1202) << "WARNING:" << tabs << "has a null active child!";
1467 m_spaces += " ";
1468 return true;
1470 virtual bool visit(KonqMainWindow*) { return true; }
1471 virtual bool endVisit(KonqFrameTabs*) {
1472 m_spaces.resize( m_spaces.size() - 2 );
1473 return true;
1475 virtual bool endVisit(KonqFrameContainer*) {
1476 m_spaces.resize( m_spaces.size() - 2 );
1477 return true;
1479 virtual bool endVisit(KonqMainWindow*) { return true; }
1480 private:
1481 QString m_spaces;
1484 void KonqViewManager::printFullHierarchy()
1486 kDebug(1202) << "currentView=" << m_pMainWindow->currentView();
1487 KonqDebugFrameVisitor visitor;
1488 m_pMainWindow->accept( &visitor );
1490 #endif
1492 KonqFrameTabs * KonqViewManager::tabContainer()
1494 if ( !m_tabContainer ) {
1495 createTabContainer(m_pMainWindow /*as widget*/, m_pMainWindow /*as container*/);
1496 m_pMainWindow->insertChildFrame( m_tabContainer );
1498 return m_tabContainer;
1501 bool KonqViewManager::isTabBarVisible() const
1503 if (!m_tabContainer)
1504 return false;
1505 return !m_tabContainer->isTabBarHidden();
1509 void KonqViewManager::createTabContainer(QWidget* parent, KonqFrameContainerBase* parentContainer)
1511 //kDebug(1202) << "createTabContainer" << parent << parentContainer;
1512 m_tabContainer = new KonqFrameTabs( parent, parentContainer, this );
1513 connect( m_tabContainer, SIGNAL(ctrlTabPressed()), m_pMainWindow, SLOT(slotCtrlTabPressed()) );
1514 // Delay the opening of the URL for #106641
1515 bool ok = connect( m_tabContainer, SIGNAL(openUrl(KonqView*, KUrl)), m_pMainWindow, SLOT(openUrl(KonqView*, KUrl)), Qt::QueuedConnection);
1516 Q_ASSERT(ok);
1517 applyConfiguration();
1520 void KonqViewManager::applyConfiguration()
1522 tabContainer()->setAlwaysTabbedMode( KonqSettings::alwaysTabbedMode() );
1525 KonqMainWindow* KonqViewManager::duplicateWindow()
1527 KTemporaryFile tempFile;
1528 tempFile.open();
1529 KConfig config( tempFile.fileName() );
1530 KConfigGroup profileGroup( &config, "Profile" );
1531 KonqFrameBase::Options flags = KonqFrameBase::saveHistoryItems;
1532 saveViewProfileToGroup(profileGroup, flags);
1534 KonqMainWindow *mainWindow = openSavedWindow(profileGroup);
1535 #ifndef NDEBUG
1536 mainWindow->viewManager()->printFullHierarchy();
1537 #endif
1538 return mainWindow;
1541 QString KonqViewManager::normalizedXMLFileName(const QString& xmluiFile)
1543 // Compatibility with pre-kde-4.2 times where there were 2 forks of konqueror.rc
1544 // Those have been merged back again, so convert to "konqueror.rc".
1545 if (xmluiFile == "konq-filemanagement.rc" || xmluiFile == "konq-webbrowsing.rc")
1546 return "konqueror.rc";
1547 return xmluiFile;
1550 #include "konqviewmanager.moc"