1 /* This file is part of the KDE project
2 Copyright (C) 1998, 1999 Simon Hausmann <hausmann@kde.org>
3 Copyright (C) 2000 Carsten Pfeiffer <pfeiffer@kde.org>
4 Copyright (C) 2000-2005 David Faure <faure@kde.org>
5 Copyright (C) 2007 Eduardo Robles Elvira <edulix@gmail.com>
6 Copyright (C) 2007 Daniel GarcĂa Moreno <danigm@gmail.com>
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public
10 License as published by the Free Software Foundation; either
11 version 2 of the License, or (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; see the file COPYING. If not, write to
20 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA.
24 #include "konqmainwindow.h"
25 #include "konqclosedwindowsmanager.h"
26 #include "konqsessionmanager.h"
27 #include "konqsessiondlg.h"
28 #include "konqdraggablelabel.h"
29 #include "konqcloseditem.h"
30 #include "konqapplication.h"
31 #include "konqguiclients.h"
32 #include "KonqMainWindowAdaptor.h"
33 #include "KonquerorAdaptor.h"
37 #include "konqviewmanager.h"
38 #include "konqframestatusbar.h"
40 #include "konqactions.h"
41 #include "konqsettingsxt.h"
42 #include "konqextensionmanager.h"
43 #include "konqueror_interface.h"
44 #include "delayedinitializer.h"
45 #include "konqextendedbookmarkowner.h"
46 #include "konqframevisitor.h"
47 #include "konqbookmarkbar.h"
48 #include "konqundomanager.h"
49 #include <config-konqueror.h>
50 #include <kstringhandler.h>
52 #include <konq_events.h>
53 #include <konqpixmapprovider.h>
54 #include <konq_operations.h>
55 #include <kbookmarkmanager.h>
56 #include <kinputdialog.h>
57 #include <klineedit.h>
58 #include <kanimatedbutton.h>
61 // we define STRICT_ANSI to get rid of some warnings in glibc
62 #ifndef __STRICT_ANSI__
63 #define __STRICT_ANSI__
64 #define _WE_DEFINED_IT_
67 #ifdef _WE_DEFINED_IT_
68 #undef __STRICT_ANSI__
69 #undef _WE_DEFINED_IT_
75 #include <sys/types.h>
79 #include <QtCore/QFile>
80 #include <QtGui/QClipboard>
81 #include <QtCore/QArgument>
82 #include <QtGui/QLayout>
83 #include <QStackedWidget>
84 #include <QtCore/QFileInfo>
88 #include <QtCore/QEvent>
89 #include <QtGui/QKeyEvent>
90 #include <QtCore/QByteRef>
91 #include <QtCore/QList>
92 #include <QtGui/QPixmap>
93 #include <QtGui/QLineEdit>
95 #include <kaboutdata.h>
97 #include <konqbookmarkmenu.h>
98 #include <kcmultidialog.h>
100 #include <kedittoolbar.h>
101 #include <klocalizedstring.h>
102 #include <kmenubar.h>
103 #include <kmessagebox.h>
104 #include <knewmenu.h>
105 #include <konq_popupmenu.h>
106 #include "konqsettings.h"
107 #include <kprotocolinfo.h>
108 #include <kprotocolmanager.h>
109 #include <kstandardshortcut.h>
110 #include <kstandardaction.h>
111 #include <kstandarddirs.h>
113 #include <ktemporaryfile.h>
114 #include <ktogglefullscreenaction.h>
115 #include <ktoolbarpopupaction.h>
116 #include <kurlcompletion.h>
117 #include <kurlrequesterdialog.h>
118 #include <kurlrequester.h>
119 #include <kmimetypetrader.h>
120 #include <kwindowsystem.h>
121 #include <kfiledialog.h>
124 #include <kiconloader.h>
126 #include <kprocess.h>
127 #include <kio/scheduler.h>
128 #include <kio/netaccess.h>
129 #include <kacceleratormanager.h>
131 #include <kxmlguifactory.h>
133 #include <sonnet/configdialog.h>
134 #ifdef KDE_MALLINFO_MALLOC
138 #include <sys/time.h>
140 #include <X11/Xlib.h>
141 #include <X11/Xatom.h>
144 #include <kauthorized.h>
145 #include <ktoolinvocation.h>
146 #include <QtDBus/QtDBus>
147 #include <kconfiggroup.h>
149 template class QList
<QPixmap
*>;
150 template class QList
<KToggleAction
*>;
152 KBookmarkManager
* s_bookmarkManager
= 0;
153 QList
<KonqMainWindow
*> *KonqMainWindow::s_lstViews
= 0;
154 KConfig
* KonqMainWindow::s_comboConfig
= 0;
155 KCompletion
* KonqMainWindow::s_pCompletion
= 0;
156 QFile
* KonqMainWindow::s_crashlog_file
= 0;
158 bool KonqMainWindow::s_preloaded
= false;
159 KonqMainWindow
* KonqMainWindow::s_preloadedWindow
= 0;
160 static int s_initialMemoryUsage
= -1;
161 static time_t s_startupTime
;
162 static int s_preloadUsageCount
;
164 KonqOpenURLRequest
KonqOpenURLRequest::null
;
166 static int current_memory_usage( int* limit
= NULL
);
168 static unsigned short int s_closedItemsListLength
= 10;
169 static unsigned long s_konqMainWindowInstancesCount
= 0;
171 KonqExtendedBookmarkOwner::KonqExtendedBookmarkOwner(KonqMainWindow
*w
)
173 m_pKonqMainWindow
= w
;
176 KonqMainWindow::KonqMainWindow( const KUrl
&initialURL
, const QString
& xmluiFile
)
177 : KParts::MainWindow()
179 , m_fullyConstructed(false)
182 setPreloadedFlag( false );
185 s_lstViews
= new QList
<KonqMainWindow
*>;
187 s_lstViews
->append( this );
189 m_urlCompletionStarted
= false;
196 (void) new KonqMainWindowAdaptor( this );
198 m_bURLEnterLock
= false;
199 m_bLocationBarConnected
= false;
201 m_pURLCompletion
= 0;
203 m_configureDialog
= 0;
205 m_viewModesGroup
= new QActionGroup(this);
206 m_viewModesGroup
->setExclusive(true);
207 connect(m_viewModesGroup
, SIGNAL(triggered(QAction
*)),
208 this, SLOT(slotViewModeTriggered(QAction
*)),
209 Qt::QueuedConnection
); // Queued so that we don't delete the action from the code that triggered it.
211 m_prevMenuBarVisible
= true;
213 // This has to be called before any action is created for this mainwindow
214 setComponentData(KGlobal::mainComponent(), false /*don't load plugins yet*/);
216 m_pViewManager
= new KonqViewManager( this );
222 m_bookmarkBarInitialized
= false;
224 m_toggleViewGUIClient
= new ToggleViewGUIClient( this );
226 m_pBookmarksOwner
= new KonqExtendedBookmarkOwner(this);
228 // init history-manager, load history, get completion object
229 if ( !s_pCompletion
) {
230 s_bookmarkManager
= KBookmarkManager::userBookmarksManager();
232 // let the KBookmarkManager know that we are a browser, equals to "keditbookmarks --browser"
233 s_bookmarkManager
->setEditorOptions("konqueror", true);
235 KonqHistoryManager
* mgr
= new KonqHistoryManager(s_bookmarkManager
);
236 s_pCompletion
= mgr
->completionObject();
238 // setup the completion object before createGUI(), so that the combo
239 // picks up the correct mode from the HistoryManager (in slotComboPlugged)
240 int mode
= KonqSettings::settingsCompletionMode();
241 s_pCompletion
->setCompletionMode( (KGlobalSettings::Completion
) mode
);
243 connect(KParts::HistoryProvider::self(), SIGNAL(cleared()), SLOT(slotClearComboHistory()));
245 KonqPixmapProvider
*prov
= KonqPixmapProvider::self();
246 if ( !s_comboConfig
) {
247 s_comboConfig
= new KConfig("konq_history", KConfig::NoGlobals
);
248 KonqCombo::setConfig( s_comboConfig
);
249 KConfigGroup
locationBarGroup( s_comboConfig
, "Location Bar" );
250 prov
->load( locationBarGroup
, "ComboIconCache" );
253 connect( prov
, SIGNAL( changed() ), SLOT( slotIconsChanged() ) );
255 m_pUndoManager
= new KonqUndoManager(this);
256 connect( m_pUndoManager
, SIGNAL( undoAvailable( bool ) ),
257 this, SLOT( slotUndoAvailable( bool ) ) );
262 connect( KSycoca::self(), SIGNAL( databaseChanged() ),
263 this, SLOT( slotDatabaseChanged() ) );
265 connect( KGlobalSettings::self(), SIGNAL( kdisplayFontChanged()), SLOT(slotReconfigure()));
267 //load the xmlui file specified in the profile or the default konqueror.rc
268 setXMLFile( KonqViewManager::normalizedXMLFileName(xmluiFile
) );
270 setStandardToolBarMenuEnabled( true );
274 m_combo
->setParent( toolBar("locationToolBar") );
275 m_combo
->setFont( KGlobalSettings::generalFont() );
278 checkDisableClearButton();
280 connect(toolBarMenuAction(),SIGNAL(triggered()),this,SLOT(slotForceSaveMainWindowSettings()) );
282 if ( !m_toggleViewGUIClient
->empty() )
283 plugActionList( QLatin1String( "toggleview" ), m_toggleViewGUIClient
->actions() );
286 delete m_toggleViewGUIClient
;
287 m_toggleViewGUIClient
= 0;
290 m_bHTMLAllowed
= KonqSettings::htmlAllowed();
292 m_ptaUseHTML
->setChecked( m_bHTMLAllowed
);
294 m_bNeedApplyKonqMainWindowSettings
= true;
296 if ( !initialURL
.isEmpty() ) {
297 openFilteredUrl( initialURL
.url() );
300 m_bNeedApplyKonqMainWindowSettings
= false;
303 if ( !initialGeometrySet() )
306 //kDebug(1202) << this << "done";
308 if( s_initialMemoryUsage
== -1 )
310 s_initialMemoryUsage
= current_memory_usage();
311 s_startupTime
= time( NULL
);
312 s_preloadUsageCount
= 0;
314 KonqSessionManager::self();
315 m_fullyConstructed
= true;
318 KonqMainWindow::~KonqMainWindow()
320 //kDebug(1202) << this;
322 delete m_pViewManager
;
326 s_lstViews
->removeAll(this);
327 if (s_lstViews
->isEmpty()) {
333 qDeleteAll(m_openWithActions
);
334 m_openWithActions
.clear();
336 delete m_pBookmarkMenu
;
337 delete m_paBookmarkBar
;
338 delete m_pBookmarksOwner
;
339 delete m_pURLCompletion
;
340 delete m_paClosedItems
;
342 if ( s_lstViews
== 0 ) {
343 delete s_comboConfig
;
347 delete m_configureDialog
;
348 m_configureDialog
= 0;
351 delete m_locationLabel
;
353 m_pUndoManager
->disconnect();
354 delete m_pUndoManager
;
357 //kDebug(1202) << this << "done";
360 void KonqMainWindow::incInstancesCount()
362 s_konqMainWindowInstancesCount
++;
365 void KonqMainWindow::decInstancesCount()
367 s_konqMainWindowInstancesCount
--;
370 QWidget
* KonqMainWindow::createContainer( QWidget
*parent
, int index
, const QDomElement
&element
, QAction
* &containerAction
)
372 QWidget
*res
= KParts::MainWindow::createContainer( parent
, index
, element
, containerAction
);
374 static QString nameBookmarkBar
= QLatin1String( "bookmarkToolBar" );
375 static QString tagToolBar
= QLatin1String( "ToolBar" );
376 if ( res
&& (element
.tagName() == tagToolBar
) && (element
.attribute( "name" ) == nameBookmarkBar
) )
378 assert( ::qobject_cast
<KToolBar
*>( res
) );
379 if (!KAuthorized::authorizeKAction("bookmarks")) {
384 if ( !m_bookmarkBarInitialized
) {
385 // The actual menu needs a different action collection, so that the bookmarks
386 // don't appear in kedittoolbar
387 m_bookmarkBarInitialized
= true;
388 DelayedInitializer
*initializer
= new DelayedInitializer( QEvent::Show
, res
);
389 connect( initializer
, SIGNAL( initialize() ), this, SLOT(initBookmarkBar()) );
393 if (res
&& element
.tagName() == QLatin1String("Menu")) {
394 const QString
& menuName
= element
.attribute("name");
395 if (menuName
== "edit" || menuName
== "tools") {
396 Q_ASSERT(qobject_cast
<QMenu
*>(res
));
397 KAcceleratorManager::manage(static_cast<QMenu
*>(res
));
404 void KonqMainWindow::initBookmarkBar()
406 KToolBar
* bar
= qFindChild
<KToolBar
*>( this, "bookmarkToolBar" );
410 delete m_paBookmarkBar
;
411 m_paBookmarkBar
= new KBookmarkBar( s_bookmarkManager
, m_pBookmarksOwner
, bar
, this );
414 if (bar
->actions().count() == 0 )
418 void KonqMainWindow::removeContainer( QWidget
*container
, QWidget
*parent
, QDomElement
&element
, QAction
* containerAction
)
420 static QString nameBookmarkBar
= QLatin1String( "bookmarkToolBar" );
421 static QString tagToolBar
= QLatin1String( "ToolBar" );
423 if ( element
.tagName() == tagToolBar
&& element
.attribute( "name" ) == nameBookmarkBar
)
425 assert( ::qobject_cast
<KToolBar
*>( container
) );
427 m_paBookmarkBar
->clear();
430 KParts::MainWindow::removeContainer( container
, parent
, element
, containerAction
);
433 // Detect a name filter (e.g. *.txt) in the url.
434 // Note that KShortURIFilter does the same, but we have no way of getting it from there
436 // Note: this removes the filter from the URL.
437 QString
KonqMainWindow::detectNameFilter( KUrl
& url
)
439 if ( !KProtocolManager::supportsListing(url
) )
442 // Look for wildcard selection
444 QString path
= url
.path();
445 int lastSlash
= path
.lastIndexOf( '/' );
446 if ( lastSlash
> -1 )
448 if ( !url
.query().isEmpty() && lastSlash
== (int)path
.length()-1 ) { // In /tmp/?foo, foo isn't a query
449 path
+= url
.query(); // includes the '?'
450 url
.setQuery( QString() );
452 QString fileName
= path
.mid( lastSlash
+ 1 );
453 QString testPath
= path
.left( lastSlash
+ 1 );
454 if ( fileName
.indexOf( '*' ) != -1 || fileName
.indexOf( '[' ) != -1 || fileName
.indexOf( '?' ) != -1 )
456 // Check that a file or dir with all the special chars in the filename doesn't exist
457 if ( url
.isLocalFile() ? !QFile::exists( path
) : !KIO::NetAccess::exists( url
, KIO::NetAccess::DestinationSide
, this ) )
459 nameFilter
= fileName
;
460 url
.setFileName( QString() );
461 kDebug(1202) << "Found wildcard. nameFilter=" << nameFilter
<< " New url=" << url
;
469 void KonqMainWindow::openFilteredUrl(const QString
& url
, const KonqOpenURLRequest
& req
)
471 // Filter URL to build a correct one
472 if (m_currentDir
.isEmpty() && m_currentView
)
473 m_currentDir
= m_currentView
->url().path( KUrl::AddTrailingSlash
);
475 KUrl
filteredURL ( KonqMisc::konqFilteredURL( this, url
, m_currentDir
) );
476 kDebug(1202) << "url" << url
<< "filtered into" << filteredURL
;
478 if ( filteredURL
.isEmpty() ) // initially empty, or error (e.g. ~unknown_user)
481 m_currentDir
.clear();
483 openUrl(0, filteredURL
, QString(), req
);
485 // #4070: Give focus to view after URL was entered manually
486 // Note: we do it here if the view mode (i.e. part) wasn't changed
487 // If it is changed, then it's done in KonqView::changePart
488 if ( m_currentView
&& m_currentView
->part() )
489 m_currentView
->part()->widget()->setFocus();
493 void KonqMainWindow::openFilteredUrl(const QString
& _url
, bool inNewTab
, bool tempFile
)
495 KonqOpenURLRequest
req( _url
);
496 req
.browserArgs
.setNewTab(inNewTab
);
497 req
.newTabInFront
= true;
498 req
.tempFile
= tempFile
;
500 openFilteredUrl( _url
, req
);
503 void KonqMainWindow::openUrl(KonqView
*_view
, const KUrl
&_url
,
504 const QString
&_mimeType
, const KonqOpenURLRequest
& _req
,
507 #ifndef NDEBUG // needed for req.debug()
508 kDebug(1202) << "url=" << _url
<< "mimeType=" << _mimeType
509 << "_req=" << _req
.debug() << "view=" << _view
;
512 // We like modifying args in this method :)
514 QString
mimeType(_mimeType
);
515 KonqOpenURLRequest
req(_req
);
517 if ( url
.url() == "about:blank" )
519 mimeType
= "text/html";
521 else if ( !url
.isValid() )
523 KMessageBox::error(0, i18n("Malformed URL\n%1", url
.url()));
526 else if ( !KProtocolInfo::isKnownProtocol( url
) && url
.protocol() != "about" )
528 KMessageBox::error(0, i18n("Protocol not supported\n%1", url
.protocol()));
532 QString nameFilter
= detectNameFilter( url
);
533 if ( !nameFilter
.isEmpty() )
535 req
.nameFilter
= nameFilter
;
536 url
.setFileName( QString() );
539 KonqView
*view
= _view
;
541 // When clicking a 'follow active' view (e.g. view is the sidebar),
542 // open the URL in the active view
543 if (view
&& view
->isFollowActive())
544 view
= m_currentView
;
546 if (!view
&& !req
.browserArgs
.newTab())
547 view
= m_currentView
; /* Note, this can be 0, e.g. on startup */
548 else if (!view
&& req
.browserArgs
.newTab()) {
549 // The URL should be opened in a new tab. Let's create the tab right away,
550 // it gives faster user feedback (#163628). For a short while (kde-4.1-beta1)
551 // I removed this entire block so that we wouldn't end up with a useless tab when
552 // launching an external application for this mimetype. But user feedback
553 // in all cases is more important than empty tabs in some cases.
554 view
= m_pViewManager
->addTab("text/html",
557 req
.openAfterCurrentPage
);
559 view
->setCaption(i18nc("@title:tab", "Loading..."));
560 view
->setLocationBarURL(_url
);
561 if (!req
.browserArgs
.frameName
.isEmpty())
562 view
->setViewName(req
.browserArgs
.frameName
); // #44961
564 if (req
.newTabInFront
)
565 m_pViewManager
->showTab(view
);
567 updateViewActions(); //A new tab created -- we may need to enable the "remove tab" button (#56318)
569 req
.browserArgs
.setNewTab(false);
573 const QString oldLocationBarURL
= m_combo
->currentText();
576 if ( view
== m_currentView
)
578 //will do all the stuff below plus GUI stuff
584 // Don't change location bar if not current view
588 // Fast mode for local files: do the stat ourselves instead of letting KRun do it.
589 if ( mimeType
.isEmpty() && url
.isLocalFile() )
591 QByteArray
_path( QFile::encodeName(url
.path()));
592 KDE_struct_stat buff
;
593 if ( KDE_stat( _path
.data(), &buff
) != -1 )
594 mimeType
= KMimeType::findByUrl( url
, buff
.st_mode
)->name();
597 if (url
.isLocalFile()) {
598 // Generic mechanism for redirecting to tar:/<path>/ when clicking on a tar file,
599 // zip:/<path>/ when clicking on a zip file, etc.
600 // The .protocol file specifies the mimetype that the kioslave handles.
601 // Note that we don't use mimetype inheritance since we don't want to
602 // open OpenDocument files as zip folders...
603 // Also note that we do this here and not in openView anymore,
604 // because in the case of foo.bz2 we don't know the final mimetype, we need a konqrun...
605 const QString protocol
= KProtocolManager::protocolForArchiveMimetype(mimeType
);
606 if (!protocol
.isEmpty() && KonqFMSettings::settings()->shouldEmbed(mimeType
)) {
607 url
.setProtocol( protocol
);
608 if (mimeType
== "application/x-webarchive") {
609 url
.addPath("index.html");
610 mimeType
= "text/html";
612 if (KProtocolManager::outputType(url
) == KProtocolInfo::T_FILESYSTEM
) {
613 url
.adjustPath(KUrl::AddTrailingSlash
);
614 mimeType
= "inode/directory";
622 //kDebug(1202) << "trying openView for" << url << "( mimeType" << mimeType << ")";
623 if ( ( !mimeType
.isEmpty() && mimeType
!= "application/octet-stream") ||
624 url
.url() == "about:" || url
.url().startsWith("about:konqueror") || url
.url() == "about:plugins" )
626 KService::Ptr offer
= KMimeTypeTrader::self()->preferredService(mimeType
, "Application");
627 const bool associatedAppIsKonqueror
= isMimeTypeAssociatedWithSelf( mimeType
, offer
);
628 // If the associated app is konqueror itself, then make sure we try to embed before bailing out.
629 if ( associatedAppIsKonqueror
)
630 req
.forceAutoEmbed
= true;
633 if ( !openView( mimeType
, url
, view
/* can be 0 */, req
) )
635 //kDebug(1202) << "openView returned false";
636 // Are we following another view ? Then forget about this URL. Otherwise fire app.
637 if ( !req
.followMode
)
639 //kDebug(1202) << "we were not following. Fire app.";
640 // The logic below is similar to BrowserRun::handleNonEmbeddable(),
641 // but we don't have a BrowserRun instance here, and since it uses
642 // some virtual methods [like save, for KHTMLRun], we can't just
643 // move all the logic to static methods... catch 22...
645 if ( !url
.isLocalFile() && !trustedSource
&& KonqRun::isTextExecutable( mimeType
) )
646 mimeType
= "text/plain"; // view, don't execute
647 // Remote URL: save or open ?
648 QString protClass
= KProtocolInfo::protocolClass(url
.protocol());
649 bool open
= url
.isLocalFile() || protClass
==":local";
651 // Use askSave from filetypesrc
652 KMessageBox::setDontShowAskAgainConfig(KonqFMSettings::settings()->fileTypesConfig().data());
653 KParts::BrowserRun::AskSaveResult res
= KonqRun::askSave( url
, offer
, mimeType
);
654 KMessageBox::setDontShowAskAgainConfig(0);
655 if ( res
== KParts::BrowserRun::Save
)
656 KParts::BrowserRun::simpleSave( url
, QString(), this );
657 open
= ( res
== KParts::BrowserRun::Open
);
661 if ( associatedAppIsKonqueror
&& refuseExecutingKonqueror(mimeType
) )
665 //kDebug(1202) << "Got offer" << (offer ? offer->name() : QString("0"));
666 const bool allowExecution
= trustedSource
|| KParts::BrowserRun::allowExecution( mimeType
, url
);
667 if ( allowExecution
&&
668 ( KonqRun::isExecutable( mimeType
) || !offer
|| !KRun::run( *offer
, lst
, this ) ) )
670 setLocationBarURL( oldLocationBarURL
); // Revert to previous locationbar URL
671 (void)new KRun( url
, this );
677 else // no known mimeType, use KonqRun
679 bool earlySetLocationBarURL
= false;
680 if (!view
&& !m_currentView
) // no view yet, e.g. starting with url as argument
681 earlySetLocationBarURL
= true;
682 else if (view
== m_currentView
&& view
->url().isEmpty()) // opening in current view
683 earlySetLocationBarURL
= true;
684 if (req
.browserArgs
.newTab()) // it's going into a new tab anyway
685 earlySetLocationBarURL
= false;
686 if (earlySetLocationBarURL
) {
687 // Show it for now in the location bar, but we'll need to store it in the view
688 // later on (can't do it yet since either view == 0 or updateHistoryEntry will be called).
689 kDebug(1202) << "url=" << url
;
690 setLocationBarURL( url
);
693 kDebug(1202) << "Creating new konqrun for" << url
<< "req.typedUrl=" << req
.typedUrl
;
695 KonqRun
* run
= new KonqRun( this, view
/* can be 0 */, url
, req
, trustedSource
);
697 // Never start in external browser
698 run
->setEnableExternalBrowser(false);
703 if ( view
== m_currentView
)
706 connect( run
, SIGNAL( finished() ), this, SLOT( slotRunFinished() ) );
710 bool KonqMainWindow::openView( QString mimeType
, const KUrl
&_url
, KonqView
*childView
, const KonqOpenURLRequest
& req
)
712 // Second argument is referring URL
713 if ( !KAuthorized::authorizeUrlAction("open", childView
? childView
->url() : KUrl(), _url
) )
715 QString msg
= KIO::buildErrorString(KIO::ERR_ACCESS_DENIED
, _url
.prettyUrl());
716 KMessageBox::queuedMessageBox( this, KMessageBox::Error
, msg
);
717 return true; // Nothing else to do.
720 if ( KonqRun::isExecutable( mimeType
) )
721 return false; // execute, don't open
722 // Contract: the caller of this method should ensure the view is stopped first.
725 kDebug(1202) << mimeType
<< _url
<< "childView=" << childView
<< "req:" << req
.debug();
727 bool bOthersFollowed
= false;
731 // If we're not already following another view (and if we are not reloading)
732 if ( !req
.followMode
&& !req
.args
.reload() && !m_pViewManager
->isLoadingProfile() )
734 // When clicking a 'follow active' view (e.g. childView is the sidebar),
735 // open the URL in the active view
736 // (it won't do anything itself, since it's locked to its location)
737 if ( childView
->isFollowActive() && childView
!= m_currentView
)
740 setLocationBarURL( _url
);
741 KonqOpenURLRequest newreq
;
742 newreq
.forceAutoEmbed
= true;
743 newreq
.followMode
= true;
744 newreq
.args
= req
.args
;
745 newreq
.browserArgs
= req
.browserArgs
;
746 bOthersFollowed
= openView( mimeType
, _url
, m_currentView
, newreq
);
748 // "link views" feature, and "sidebar follows active view" feature
749 bOthersFollowed
= makeViewsFollow(_url
, req
.args
, req
.browserArgs
, mimeType
, childView
) || bOthersFollowed
;
751 if ( childView
->isLockedLocation() && !req
.args
.reload() /* allow to reload a locked view*/ )
752 return bOthersFollowed
;
757 // In case we open an index.html, we want the location bar
758 // to still display the original URL (so that 'up' uses that URL,
759 // and since that's what the user entered).
760 // changePart will take care of setting and storing that url.
761 QString originalURL
= url
.pathOrUrl();
762 if (!req
.nameFilter
.isEmpty()) { // keep filter in location bar
763 if (!originalURL
.endsWith('/'))
765 originalURL
+= req
.nameFilter
;
768 QString serviceName
; // default: none provided
769 const QString urlStr
= url
.url();
770 if ( urlStr
== "about:" || urlStr
.startsWith("about:konqueror") || urlStr
== "about:plugins" ) {
771 mimeType
= "KonqAboutPage"; // not KParts/ReadOnlyPart, it fills the Location menu ! :)
772 serviceName
= "konq_aboutpage";
773 originalURL
= req
.typedUrl
.isEmpty() ? QString() : req
.typedUrl
;
775 else if ( urlStr
== "about:blank" && req
.typedUrl
.isEmpty() ) {
780 bool forceAutoEmbed
= req
.forceAutoEmbed
|| req
.userRequestedReload
;
781 if (!req
.typedUrl
.isEmpty()) // the user _typed_ the URL, he wants it in Konq.
782 forceAutoEmbed
= true;
783 if (url
.protocol() == "about" || url
.protocol() == "error")
784 forceAutoEmbed
= true;
785 // Related to KonqFactory::createView
786 if (!forceAutoEmbed
&& !KonqFMSettings::settings()->shouldEmbed(mimeType
)) {
787 kDebug(1202) << "KonqFMSettings says: don't embed this servicetype";
790 // Do we even have a part to embed? Otherwise don't ask, since we'd ask twice.
791 if (!forceAutoEmbed
) {
792 KService::List partServiceOffers
;
793 KonqFactory::getOffers(mimeType
, &partServiceOffers
);
794 if (partServiceOffers
.isEmpty()) {
795 kDebug(1202) << "No part available for" << mimeType
;
800 // If the protocol doesn't support writing (e.g. HTTP) then we might want to save instead of just embedding.
801 // So (if embedding would succeed, hence the checks above) we ask the user
802 // Otherwise the user will get asked 'open or save' in openUrl anyway.
803 if (!forceAutoEmbed
&& !KProtocolManager::supportsWriting(url
)) {
804 QString suggestedFilename
;
805 KonqRun
* run
= childView
? childView
->run() : 0;
808 suggestedFilename
= run
->suggestedFileName();
809 attachment
= (run
->serverSuggestsSave()) ? KParts::BrowserRun::AttachmentDisposition
: KParts::BrowserRun::InlineDisposition
;
812 // Use askEmbedOrSave from filetypesrc
813 KMessageBox::setDontShowAskAgainConfig(KonqFMSettings::settings()->fileTypesConfig().data());
815 KParts::BrowserRun::AskSaveResult res
= KParts::BrowserRun::askEmbedOrSave(
816 url
, mimeType
, suggestedFilename
, attachment
);
817 KMessageBox::setDontShowAskAgainConfig(0);
818 if (res
== KParts::BrowserRun::Open
)
819 forceAutoEmbed
= true;
820 else if (res
== KParts::BrowserRun::Cancel
)
821 return true; // handled, don't do anything else
823 KParts::BrowserRun::simpleSave(url
, suggestedFilename
, this);
824 return true; // handled
829 // Look for which view mode to use, if a directory - not if view locked
830 if ( ( !childView
|| (!childView
->isLockedViewMode()) )
831 && mimeType
== "inode/directory" ) {
833 if ( url
.isLocalFile() ) { // local, check .directory file
834 // Read HTMLAllowed in the .directory file, default to m_bHTMLAllowed
835 KUrl
urlDotDir( url
);
836 urlDotDir
.addPath(".directory");
837 bool HTMLAllowed
= m_bHTMLAllowed
;
838 QFile
f( urlDotDir
.path() );
839 if ( f
.open(QIODevice::ReadOnly
) ) {
841 KConfig
config(urlDotDir
.path(), KConfig::SimpleConfig
);
842 KConfigGroup
urlProperties( &config
, "URL properties" );
843 HTMLAllowed
= urlProperties
.readEntry( "HTMLAllowed", m_bHTMLAllowed
);
844 //serviceName = urlProperties.readEntry( "ViewMode", serviceName );
845 //kDebug(1202) << "serviceName=" << serviceName;
849 ( !( indexFile
= findIndexFile( url
.path() ) ).isEmpty() ) ) {
850 mimeType
= "text/html";
851 url
= KUrl(indexFile
);
852 //serviceName.clear(); // cancel what we just set, this is not a dir finally
855 // Reflect this setting in the menu
856 m_ptaUseHTML
->setChecked( HTMLAllowed
);
863 if (req
.browserArgs
.newTab())
865 KonqFrameTabs
* tabContainer
= m_pViewManager
->tabContainer();
866 int index
= tabContainer
->currentIndex();
867 childView
= m_pViewManager
->addTab( mimeType
, serviceName
, false, req
.openAfterCurrentPage
);
869 if (req
.newTabInFront
&& childView
)
871 if ( req
.openAfterCurrentPage
)
872 tabContainer
->setCurrentIndex( index
+ 1 );
874 tabContainer
->setCurrentIndex( tabContainer
->count()-1 );
881 // createFirstView always uses force auto-embed even if user setting is "separate viewer",
882 // since this window has no view yet - we don't want to keep an empty mainwindow.
883 // This can happen with e.g. application/pdf from a target="_blank" link, or window.open.
884 childView
= m_pViewManager
->createFirstView( mimeType
, serviceName
);
888 enableAllActions( true );
889 m_currentView
= childView
;
894 return false; // It didn't work out.
896 childView
->setViewName( m_initialFrameName
.isEmpty() ? req
.browserArgs
.frameName
: m_initialFrameName
);
897 m_initialFrameName
.clear();
899 else // We know the child view
901 if ( !childView
->isLockedViewMode() ) {
904 // When typing a new URL, the current context doesn't matter anymore
905 // -> select the preferred part for a given mimetype (even if the current part can handle this mimetype).
906 // This fixes the "get katepart and then type a website URL -> loaded into katepart" problem
907 // (first fixed in r168902 from 2002!, see also unittest KonqHtmlTest::textThenHtml())
909 if (!req
.typedUrl
.isEmpty() || !serviceName
.isEmpty()) {
910 ok
= childView
->changePart( mimeType
, serviceName
, forceAutoEmbed
);
912 ok
= childView
->ensureViewSupports( mimeType
, forceAutoEmbed
);
920 //kDebug(1202) << "req.nameFilter= " << req.nameFilter;
921 //kDebug(1202) << "req.typedUrl= " << req.typedUrl;
922 //kDebug(1202) << "Browser extension? " << (childView->browserExtension() ? "YES" : "NO");
923 //kDebug(1202) << "Referrer: " << req.args.metaData()["referrer"];
924 childView
->setTypedURL( req
.typedUrl
);
925 if ( childView
->part() )
926 childView
->part()->setArguments( req
.args
);
927 if ( childView
->browserExtension() )
928 childView
->browserExtension()->setBrowserArguments( req
.browserArgs
);
930 KonqDirPart
* dirPart
= ::qobject_cast
<KonqDirPart
*>( childView
->part() );
932 dirPart
->setFilesToSelect( req
.filesToSelect
);
934 if ( !url
.isEmpty() )
935 childView
->openUrl( url
, originalURL
, req
.nameFilter
, req
.tempFile
);
937 //kDebug(1202) << "ok=" << ok << "bOthersFollowed=" << bOthersFollowed
938 // << "returning" << (ok || bOthersFollowed);
939 return ok
|| bOthersFollowed
;
942 static KonqView
* findChildView( KParts::ReadOnlyPart
*callingPart
, const QString
&name
, KonqMainWindow
*&mainWindow
, KParts::BrowserHostExtension
*&hostExtension
, KParts::ReadOnlyPart
**part
)
944 if ( !KonqMainWindow::mainWindowList() )
947 foreach ( KonqMainWindow
* window
, *KonqMainWindow::mainWindowList() ) {
948 KonqView
*res
= window
->childView( callingPart
, name
, hostExtension
, part
);
958 void KonqMainWindow::slotOpenURLRequest( const KUrl
&url
, const KParts::OpenUrlArguments
& args
, const KParts::BrowserArguments
&browserArgs
)
960 //kDebug(1202) << "frameName=" << browserArgs.frameName;
962 KParts::ReadOnlyPart
*callingPart
= static_cast<KParts::ReadOnlyPart
*>( sender()->parent() );
963 QString frameName
= browserArgs
.frameName
;
965 if ( !frameName
.isEmpty() )
967 static QString _top
= QLatin1String( "_top" );
968 static QString _self
= QLatin1String( "_self" );
969 static QString _parent
= QLatin1String( "_parent" );
970 static QString _blank
= QLatin1String( "_blank" );
972 if ( frameName
.toLower() == _blank
)
974 slotCreateNewWindow( url
, args
, browserArgs
);
978 if ( frameName
.toLower() != _top
&&
979 frameName
.toLower() != _self
&&
980 frameName
.toLower() != _parent
)
982 KParts::BrowserHostExtension
*hostExtension
= 0;
983 KonqView
*view
= childView( callingPart
, frameName
, hostExtension
, 0 );
986 KonqMainWindow
*mainWindow
= 0;
987 view
= findChildView( callingPart
, frameName
, mainWindow
, hostExtension
, 0 );
989 if ( !view
|| !mainWindow
)
991 slotCreateNewWindow( url
, args
, browserArgs
);
996 hostExtension
->openUrlInFrame( url
, args
, browserArgs
);
998 mainWindow
->openUrlRequestHelper( view
, url
, args
, browserArgs
);
1002 if ( hostExtension
)
1003 hostExtension
->openUrlInFrame( url
, args
, browserArgs
);
1005 openUrlRequestHelper( view
, url
, args
, browserArgs
);
1010 KonqView
*view
= browserArgs
.newTab() ? 0 : childView( callingPart
);
1011 openUrlRequestHelper( view
, url
, args
, browserArgs
);
1014 //Called by slotOpenURLRequest
1015 void KonqMainWindow::openUrlRequestHelper( KonqView
*childView
, const KUrl
&url
, const KParts::OpenUrlArguments
& args
, const KParts::BrowserArguments
&browserArgs
)
1017 //kDebug(1202) << "url=" << url;
1018 KonqOpenURLRequest req
;
1020 req
.browserArgs
= browserArgs
;
1021 openUrl(childView
, url
, args
.mimeType(), req
, browserArgs
.trustedSource
);
1024 QObject
*KonqMainWindow::lastFrame( KonqView
*view
)
1026 QObject
*nextFrame
, *viewFrame
;
1027 nextFrame
= view
->frame();
1029 while ( nextFrame
!= 0 && !::qobject_cast
<QStackedWidget
*>(nextFrame
) ) {
1030 viewFrame
= nextFrame
;
1031 nextFrame
= nextFrame
->parent();
1033 return nextFrame
? viewFrame
: 0;
1036 // Linked-views feature, plus "sidebar follows URL opened in the active view" feature
1037 bool KonqMainWindow::makeViewsFollow( const KUrl
& url
,
1038 const KParts::OpenUrlArguments
& args
,
1039 const KParts::BrowserArguments
&browserArgs
,
1040 const QString
& serviceType
, KonqView
* senderView
)
1042 if ( !senderView
->isLinkedView() && senderView
!= m_currentView
)
1043 return false; // none of those features apply -> return
1046 //kDebug(1202) << senderView->metaObject()->className() << "url=" << url << "serviceType=" << serviceType;
1047 KonqOpenURLRequest req
;
1048 req
.forceAutoEmbed
= true;
1049 req
.followMode
= true;
1051 req
.browserArgs
= browserArgs
;
1052 // We can't iterate over the map here, and openUrl for each, because the map can get modified
1053 // (e.g. by part changes). Better copy the views into a list.
1054 const QList
<KonqView
*> listViews
= m_mapViews
.values();
1056 QObject
*senderFrame
= lastFrame( senderView
);
1058 foreach (KonqView
* view
, listViews
)
1060 if (view
== senderView
)
1062 bool followed
= false;
1063 // Views that should follow this URL as both views are linked
1064 if (view
->isLinkedView() && senderView
->isLinkedView()) {
1065 QObject
*viewFrame
= lastFrame(view
);
1067 // Only views in the same tab of the sender will follow
1068 if (senderFrame
&& viewFrame
&& viewFrame
!= senderFrame
)
1071 kDebug(1202) << "sending openUrl to view" << view
->part()->metaObject()->className() << "url=" << url
;
1073 // XXX duplicate code from ::openUrl
1074 if (view
== m_currentView
) {
1076 setLocationBarURL(url
);
1081 followed
= openView(serviceType
, url
, view
, req
);
1083 // Make the sidebar follow the URLs opened in the active view
1084 if (view
->isFollowActive() && senderView
== m_currentView
) {
1085 followed
= openView(serviceType
, url
, view
, req
);
1089 // Ignore return value if the view followed but doesn't really
1090 // show the file contents. We still want to see that
1091 // file, e.g. in a separate viewer.
1092 // This happens in views locked to a directory mode,
1093 // like sidebar and konsolepart (#52161).
1094 const bool ignore
= view
->isLockedViewMode() && view
->showsDirectory();
1095 //kDebug(1202) << "View " << view->service()->name()
1096 // << " supports dirs: " << view->showsDirectory()
1097 // << " is locked-view-mode:" << view->isLockedViewMode()
1098 // << " ignore=" << ignore;
1100 res
= followed
|| res
;
1106 void KonqMainWindow::abortLoading()
1108 if ( m_currentView
) {
1109 m_currentView
->stop(); // will take care of the statusbar
1114 // Are there any indications that this window has a strong popup
1115 // nature and should therefore not be embedded into a tab?
1116 static bool isPopupWindow( const KParts::WindowArgs
&windowArgs
)
1118 // ### other settings to respect?
1119 return windowArgs
.x() != -1 || windowArgs
.y() != -1 ||
1120 windowArgs
.width() != -1 || windowArgs
.height() != -1 ||
1121 !windowArgs
.isMenuBarVisible() ||
1122 !windowArgs
.toolBarsVisible() ||
1123 !windowArgs
.isStatusBarVisible();
1126 // This is called for the javascript window.open call.
1127 // Also called for MMB on link, target="_blank" link, MMB on folder, etc.
1128 void KonqMainWindow::slotCreateNewWindow( const KUrl
&url
,
1129 const KParts::OpenUrlArguments
& args
,
1130 const KParts::BrowserArguments
&browserArgs
,
1131 const KParts::WindowArgs
&windowArgs
, KParts::ReadOnlyPart
**part
)
1133 // NOTE: 'part' may be null
1135 kDebug(1202) << "url=" << url
<< "args.mimeType()=" << args
.mimeType()
1136 << "browserArgs.frameName=" << browserArgs
.frameName
;
1139 *part
= 0; // Make sure to be initialized in case of failure...
1141 KonqMainWindow
*mainWindow
= 0;
1142 if ( !browserArgs
.frameName
.isEmpty() && browserArgs
.frameName
.toLower() != "_blank" ) {
1143 KParts::BrowserHostExtension
*hostExtension
= 0;
1144 KParts::ReadOnlyPart
*ro_part
= 0;
1145 KParts::BrowserExtension
*be
= ::qobject_cast
<KParts::BrowserExtension
*>(sender());
1147 ro_part
= ::qobject_cast
<KParts::ReadOnlyPart
*>(be
->parent());
1148 if ( findChildView( ro_part
, browserArgs
.frameName
, mainWindow
, hostExtension
, part
) ) {
1149 // Found a view. If url isn't empty, we should open it - but this never happens currently
1150 // findChildView put the resulting part in 'part', so we can just return now
1151 //kDebug() << "frame=" << browserArgs.frameName << "-> found part=" << part << part->name();
1156 bool createTab
= false;
1157 if (args
.actionRequestedByUser()) { // MMB or some RMB popupmenu action
1158 createTab
= KonqSettings::mmbOpensTab() &&
1159 !args
.metaData().contains("forcenewwindow"); // RMB / Frame / Open in New Window
1161 createTab
= KonqSettings::popupsWithinTabs() &&
1162 !isPopupWindow( windowArgs
);
1165 kDebug() << "createTab=" << createTab
<< "part=" << part
;
1169 bool newtabsinfront
= KonqSettings::newTabsInFront();
1170 if ( windowArgs
.lowerWindow() || (QApplication::keyboardModifiers() & Qt::ShiftModifier
))
1171 newtabsinfront
= !newtabsinfront
;
1172 const bool aftercurrentpage
= KonqSettings::openAfterCurrentPage();
1174 // Can we use the standard way (openUrl), or do we need the part pointer immediately?
1176 KonqOpenURLRequest req
;
1177 req
.browserArgs
.setNewTab(true);
1178 req
.newTabInFront
= newtabsinfront
;
1179 req
.openAfterCurrentPage
= aftercurrentpage
;
1180 openUrl(0, url
, args
.mimeType(), req
);
1182 KonqView
* newView
= m_pViewManager
->addTab("text/html", QString(), false, aftercurrentpage
);
1183 if (newView
== 0) return;
1186 m_pViewManager
->showTab( newView
);
1188 openUrl( newView
, url
.isEmpty() ? KUrl("about:blank") : url
, QString() );
1189 newView
->setViewName( browserArgs
.frameName
);
1191 *part
= newView
->part();
1196 // Pass the URL to createNewWindow so that it can select the right profile for it
1197 // Note that it's always empty in case of window.open, though.
1198 mainWindow
= KonqMisc::createNewWindow(url
, args
, browserArgs
, false, QStringList(), false, false /*do not open URL*/);
1199 mainWindow
->resetAutoSaveSettings(); // Don't autosave
1201 KonqOpenURLRequest req
;
1203 req
.browserArgs
= browserArgs
;
1204 req
.browserArgs
.setNewTab(false); // we got a new window, no need for a new tab in that window
1205 req
.forceAutoEmbed
= true;
1207 // Do we know the mimetype? If not, go to generic openUrl which will use a KonqRun.
1208 if ( args
.mimeType().isEmpty() ) {
1209 mainWindow
->openUrl( 0, url
, QString(), req
);
1210 } else if (!mainWindow
->openView(args
.mimeType(), url
, m_currentView
, req
)) {
1211 // we have problems. abort.
1219 KonqView
* view
= 0;
1220 // cannot use activePart/currentView, because the activation through the partmanager
1221 // is delayed by a singleshot timer (see KonqViewManager::setActivePart)
1222 // ### TODO: not true anymore
1223 if ( mainWindow
->viewMap().count() )
1225 MapViews::ConstIterator it
= mainWindow
->viewMap().begin();
1232 // activate the view now in order to make the menuBar() hide call work
1233 if ( part
&& *part
) {
1234 mainWindow
->viewManager()->setActivePart(*part
);
1237 if ( windowArgs
.x() != -1 )
1238 mainWindow
->move( windowArgs
.x(), mainWindow
->y() );
1239 if ( windowArgs
.y() != -1 )
1240 mainWindow
->move( mainWindow
->x(), windowArgs
.y() );
1243 if ( windowArgs
.width() != -1 )
1244 width
= windowArgs
.width();
1246 width
= mainWindow
->width();
1249 if ( windowArgs
.height() != -1 )
1250 height
= windowArgs
.height();
1252 height
= mainWindow
->height();
1254 mainWindow
->resize( width
, height
);
1256 // process the window args
1258 if ( !windowArgs
.isMenuBarVisible() )
1260 mainWindow
->menuBar()->hide();
1261 mainWindow
->m_paShowMenuBar
->setChecked( false );
1264 if ( !windowArgs
.toolBarsVisible() )
1266 foreach (KToolBar
* bar
, mainWindow
->findChildren
<KToolBar
*>())
1271 if ( !windowArgs
.scrollBarsVisible() )
1272 view
->disableScrolling();
1273 if ( !windowArgs
.isStatusBarVisible() )
1274 view
->frame()->statusbar()->hide();
1277 if ( !windowArgs
.isResizable() )
1278 // ### this doesn't seem to work :-(
1279 mainWindow
->setSizePolicy( QSizePolicy( QSizePolicy::Fixed
, QSizePolicy::Fixed
) );
1281 // Trying to show the window initially behind the current window is a bit tricky,
1282 // as this involves the window manager, which may see things differently.
1283 // Many WMs raise and activate new windows, which means without WM support this won't work very
1284 // well. If the WM has support for _NET_WM_USER_TIME, it will be just set to 0 (=don't focus on show),
1285 // and the WM should take care of it itself.
1286 bool wm_usertime_support
= false;
1289 Time saved_last_input_time
= QX11Info::appUserTime();
1290 if ( windowArgs
.lowerWindow() )
1292 NETRootInfo
wm_info( QX11Info::display(), NET::Supported
);
1293 wm_usertime_support
= wm_info
.isSupported( NET::WM2UserTime
);
1294 if( wm_usertime_support
)
1296 // *sigh*, and I thought nobody would need QWidget::dontFocusOnShow().
1297 // Avoid Qt's support for user time by setting it to 0, and
1298 // set the property ourselves.
1299 QX11Info::setAppUserTime( 0 );
1300 KWindowSystem::setUserTime( mainWindow
->winId(), 0 );
1302 // Put below the current window before showing, in case that actually works with the WM.
1303 // First do complete lower(), then stackUnder(), because the latter may not work with many WMs.
1304 mainWindow
->lower();
1305 mainWindow
->stackUnder( this );
1310 if ( windowArgs
.lowerWindow() )
1312 QX11Info::setAppUserTime( saved_last_input_time
);
1313 if( !wm_usertime_support
)
1314 { // No WM support. Let's try ugly tricks.
1315 mainWindow
->lower();
1316 mainWindow
->stackUnder( this );
1317 if( this->isActiveWindow())
1318 this->activateWindow();
1325 if ( windowArgs
.isFullScreen() )
1326 mainWindow
->action( "fullscreen" )->trigger();
1329 void KonqMainWindow::slotNewWindow()
1331 // Use profile from current window, if set
1332 QString profile
= m_pViewManager
->currentProfile();
1333 if ( profile
.isEmpty() )
1335 if ( m_currentView
&& m_currentView
->url().protocol().startsWith( "http" ) )
1336 profile
= QLatin1String("webbrowsing");
1338 profile
= QLatin1String("filemanagement");
1340 KonqMisc::createBrowserWindowFromProfile(
1341 KStandardDirs::locate( "data", QLatin1String("konqueror/profiles/")+profile
),
1345 void KonqMainWindow::slotDuplicateWindow()
1347 m_pViewManager
->duplicateWindow()->show();
1350 void KonqMainWindow::slotSendURL()
1352 const KUrl::List lst
= currentURLs();
1354 QString fileNameList
;
1355 for ( KUrl::List::ConstIterator it
= lst
.begin() ; it
!= lst
.end() ; ++it
)
1357 if ( !body
.isEmpty() ) body
+= '\n';
1358 body
+= (*it
).prettyUrl();
1359 if ( !fileNameList
.isEmpty() ) fileNameList
+= ", ";
1360 fileNameList
+= (*it
).fileName();
1363 if (m_currentView
&& !m_currentView
->showsDirectory())
1364 subject
= m_currentView
->caption();
1365 else // directory view
1366 subject
= fileNameList
;
1367 KToolInvocation::invokeMailer(QString(),QString(),QString(),
1371 void KonqMainWindow::slotSendFile()
1373 const KUrl::List lst
= currentURLs();
1375 QString fileNameList
;
1376 for ( KUrl::List::ConstIterator it
= lst
.begin() ; it
!= lst
.end() ; ++it
)
1378 if ( !fileNameList
.isEmpty() ) fileNameList
+= ", ";
1379 if ( (*it
).isLocalFile() && QFileInfo((*it
).path()).isDir() )
1381 // Create a temp dir, so that we can put the ZIP file in it with a proper name
1382 QString zipFileName
;
1384 //TODO This should use KTempDir
1385 KTemporaryFile zipFile
;
1387 zipFileName
= zipFile
.fileName();
1390 QDir().mkdir(zipFileName
);
1391 zipFileName
= zipFileName
+'/'+(*it
).fileName()+".zip";
1392 KZip
zip( zipFileName
);
1393 if ( !zip
.open( QIODevice::WriteOnly
) )
1394 continue; // TODO error message
1395 zip
.addLocalDirectory( (*it
).path(), QString() );
1397 fileNameList
+= (*it
).fileName()+".zip";
1398 urls
.append( zipFileName
);
1402 fileNameList
+= (*it
).fileName();
1403 urls
.append( (*it
).url() );
1407 if ( m_currentView
&& !m_currentView
->showsDirectory())
1408 subject
= m_currentView
->caption();
1410 subject
= fileNameList
;
1411 KToolInvocation::invokeMailer(QString(), QString(), QString(), subject
,
1414 urls
); // attachments
1417 void KonqMainWindow::slotOpenLocation()
1420 m_combo
->lineEdit()->selectAll();
1423 void KonqMainWindow::slotOpenFile()
1426 if (m_currentView
&& m_currentView
->url().isLocalFile())
1427 currentUrl
= m_currentView
->url();
1429 currentUrl
= KUrl::fromPath(QDir::homePath());
1431 KUrl url
= KFileDialog::getOpenUrl(currentUrl
, QString(), this);
1433 openFilteredUrl( url
.url().trimmed() );
1437 void KonqMainWindow::slotToolFind()
1439 if ( m_currentView
&& ::qobject_cast
<KonqDirPart
*>( m_currentView
->part() ) )
1441 KonqDirPart
* dirPart
= static_cast<KonqDirPart
*>(m_currentView
->part());
1443 if (!m_paFindFiles
->isChecked())
1445 dirPart
->slotFindClosed();
1449 KonqFactory konqFactory
;
1450 KonqViewFactory factory
= konqFactory
.createView( "Konqueror/FindPart" );
1451 if ( factory
.isNull() )
1453 KMessageBox::error( this, i18n("Cannot create the find part, check your installation.") );
1454 m_paFindFiles
->setChecked(false);
1458 KParts::ReadOnlyPart
* findPart
= factory
.create( m_currentView
->frame(), dirPart
);
1459 dirPart
->setFindPart( findPart
);
1461 m_currentView
->frame()->insertTopWidget( findPart
->widget() );
1462 findPart
->widget()->show();
1463 findPart
->widget()->setFocus();
1465 connect( dirPart
, SIGNAL( findClosed(KonqDirPart
*) ),
1466 this, SLOT( slotFindClosed(KonqDirPart
*) ) );
1468 else if ( ::qobject_cast
<KAction
*>(sender()) ) // don't go there if called by the singleShot below
1471 if ( m_currentView
&& m_currentView
->url().isLocalFile() )
1472 url
= m_currentView
->locationBarURL();
1474 url
.setPath( QDir::homePath() );
1475 KonqMainWindow
* mw
= KonqMisc::createBrowserWindowFromProfile(
1476 KStandardDirs::locate( "data", QLatin1String("konqueror/profiles/filemanagement") ),
1477 "filemanagement", url
, KParts::URLArgs(), true /* forbid "use html"*/ );
1478 mw
->m_paFindFiles
->setChecked(true);
1479 // Delay it after the openUrl call (hacky!)
1480 QTimer::singleShot( 1, mw
, SLOT(slotToolFind()));
1481 m_paFindFiles
->setChecked(false);
1487 void KonqMainWindow::slotFindOpen( KonqDirPart
* dirPart
)
1489 Q_ASSERT( m_currentView
);
1490 Q_ASSERT( m_currentView
->part() == dirPart
);
1491 slotToolFind(); // lazy me
1494 void KonqMainWindow::slotFindClosed( KonqDirPart
* dirPart
)
1496 KonqView
* dirView
= m_mapViews
.value( dirPart
);
1498 if ( dirView
&& dirView
== m_currentView
)
1499 m_paFindFiles
->setEnabled( true );
1500 m_paFindFiles
->setChecked(false);
1504 void KonqMainWindow::slotIconsChanged()
1507 m_combo
->updatePixmaps();
1508 m_pViewManager
->updatePixmaps();
1512 void KonqMainWindow::slotOpenWith()
1515 lst
.append(m_currentView
->url());
1517 const QString serviceName
= sender()->objectName();
1519 const KService::List offers
= m_currentView
->appServiceOffers();
1520 KService::List::ConstIterator it
= offers
.begin();
1521 const KService::List::ConstIterator end
= offers
.end();
1522 for (; it
!= end
; ++it
) {
1523 if ((*it
)->desktopEntryName() == serviceName
) {
1524 KRun::run(**it
, lst
, this);
1530 void KonqMainWindow::slotViewModeTriggered(QAction
* action
)
1532 // Gather data from the action, since the action will be deleted by changePart
1533 const QString modeName
= action
->objectName();
1534 const QString internalViewMode
= action
->data().toString();
1536 if ( m_currentView
->service()->desktopEntryName() != modeName
) {
1537 m_currentView
->stop();
1538 m_currentView
->lockHistory();
1540 // Save those, because changePart will lose them
1541 KUrl url
= m_currentView
->url();
1542 QString locationBarURL
= m_currentView
->locationBarURL();
1544 QStringList filesToSelect
;
1545 KonqDirPart
* dirPart
= ::qobject_cast
<KonqDirPart
*>(m_currentView
->part());
1547 const KFileItemList fileItemsToSelect
= dirPart
->selectedFileItems();
1548 KFileItemList::const_iterator it
= fileItemsToSelect
.begin();
1549 const KFileItemList::const_iterator end
= fileItemsToSelect
.end();
1550 for ( ; it
!= end
; ++it
) {
1551 filesToSelect
+= (*it
)->name();
1556 m_currentView
->changePart( m_currentView
->serviceType(), modeName
);
1557 KUrl
locURL( locationBarURL
);
1558 QString nameFilter
= detectNameFilter( locURL
);
1560 KonqDirPart
* dirPart
= ::qobject_cast
<KonqDirPart
*>(m_currentView
->part());
1562 dirPart
->setFilesToSelect( filesToSelect
);
1564 m_currentView
->openUrl( locURL
, locationBarURL
, nameFilter
);
1567 if (!internalViewMode
.isEmpty() && internalViewMode
!= m_currentView
->internalViewMode()) {
1568 m_currentView
->setInternalViewMode(internalViewMode
);
1572 void KonqMainWindow::showHTML( KonqView
* _view
, bool b
, bool _activateView
)
1574 // Save this setting
1575 // This has to be done before calling openView since it relies on it
1576 KonqSettings::setHtmlAllowed( b
);
1577 KonqSettings::self()->writeConfig();
1578 if ( _activateView
)
1581 if ( b
&& _view
->showsDirectory()) {
1582 _view
->lockHistory();
1583 openView( "inode/directory", _view
->url(), _view
);
1585 else if ( !b
&& _view
->supportsMimeType( "text/html" ) )
1587 KUrl
u( _view
->url() );
1588 QString fileName
= u
.fileName().toLower();
1589 if ( KProtocolManager::supportsListing( u
) && fileName
.startsWith("index.htm") ) {
1590 _view
->lockHistory();
1591 u
.setPath( u
.directory() );
1592 openView( "inode/directory", u
, _view
);
1597 void KonqMainWindow::slotShowHTML()
1599 bool b
= !m_currentView
->allowHTML();
1601 m_currentView
->stop();
1602 m_currentView
->setAllowHTML( b
);
1603 showHTML( m_currentView
, b
, true ); //current view
1604 m_pViewManager
->showHTML(b
);
1608 void KonqMainWindow::setShowHTML( bool b
)
1611 if ( m_currentView
)
1612 m_currentView
->setAllowHTML( b
);
1613 m_ptaUseHTML
->setChecked( b
);
1616 void KonqMainWindow::slotLockView()
1618 m_currentView
->setLockedLocation( m_paLockView
->isChecked() );
1621 void KonqMainWindow::slotStop()
1624 if ( m_currentView
)
1626 m_currentView
->frame()->statusbar()->message( i18n("Canceled.") );
1630 void KonqMainWindow::slotLinkView()
1632 // Can't access this action in passive mode anyway
1633 assert(!m_currentView
->isPassiveMode());
1634 bool mode
= !m_currentView
->isLinkedView();
1636 if (linkableViewsCount() == 2)
1638 // Exactly two linkable views : link both
1639 KonqMainWindow::MapViews::ConstIterator it
= viewMap().begin();
1640 if( (*it
)->isFollowActive() ) // skip sidebar
1642 (*it
)->setLinkedView( mode
);
1644 if( (*it
)->isFollowActive() ) // skip sidebar
1646 (*it
)->setLinkedView( mode
);
1648 else // Normal case : just this view
1649 m_currentView
->setLinkedView( mode
);
1652 void KonqMainWindow::slotReload( KonqView
* reloadView
, bool softReload
)
1655 reloadView
= m_currentView
;
1657 if ( !reloadView
|| reloadView
->url().isEmpty() )
1660 if ( reloadView
->part() && (reloadView
->part()->metaObject()->indexOfProperty("modified") != -1) ) {
1661 QVariant prop
= reloadView
->part()->property("modified");
1662 if (prop
.isValid() && prop
.toBool())
1663 if ( KMessageBox::warningContinueCancel( this,
1664 i18n("This page contains changes that have not been submitted.\nReloading the page will discard these changes."),
1665 i18n("Discard Changes?"), KGuiItem(i18n("&Discard Changes"),"view-refresh"), KStandardGuiItem::cancel(), "discardchangesreload") != KMessageBox::Continue
)
1669 KonqOpenURLRequest
req( reloadView
->typedUrl() );
1670 req
.userRequestedReload
= true;
1671 if ( reloadView
->prepareReload( req
.args
, req
.browserArgs
, softReload
) )
1673 reloadView
->lockHistory();
1674 // Reuse current servicetype for local files, but not for remote files (it could have changed, e.g. over HTTP)
1675 QString serviceType
= reloadView
->url().isLocalFile() ? reloadView
->serviceType() : QString();
1676 // By using locationBarURL instead of url, we preserve name filters (#54687)
1677 openUrl( reloadView
, reloadView
->locationBarURL(), serviceType
, req
);
1681 void KonqMainWindow::slotForceReload()
1683 // A forced reload is simply a "hard" (i.e. - not soft!) reload.
1684 slotReload(0L /* Current view */, false /* Not softReload*/);
1687 void KonqMainWindow::slotReloadPopup()
1690 slotReload( m_pWorkingTab
->activeChildView() );
1693 void KonqMainWindow::slotHome(Qt::MouseButtons buttons
, Qt::KeyboardModifiers modifiers
)
1695 const QString homeURL
= m_currentView
&& m_currentView
->showsDirectory() ? QDir::homePath()
1696 : KonqSettings::homeURL();
1698 KonqOpenURLRequest req
;
1699 req
.browserArgs
.setNewTab(true);
1700 req
.newTabInFront
= KonqSettings::newTabsInFront();
1702 if (modifiers
& Qt::ShiftModifier
)
1703 req
.newTabInFront
= !req
.newTabInFront
;
1705 if( modifiers
& Qt::ControlModifier
) // Ctrl Left/MMB
1706 openFilteredUrl( homeURL
, req
);
1707 else if( buttons
& Qt::MidButton
)
1709 if(KonqSettings::mmbOpensTab())
1710 openFilteredUrl( homeURL
, req
);
1713 KUrl finalURL
= KonqMisc::konqFilteredURL( this, homeURL
);
1714 KonqMisc::createNewWindow( finalURL
.url() );
1718 openFilteredUrl( homeURL
, false );
1721 void KonqMainWindow::slotHome()
1723 slotHome(Qt::LeftButton
, Qt::NoModifier
);
1726 void KonqMainWindow::slotGoHistory()
1728 QAction
*a
= m_toggleViewGUIClient
->action("konq_sidebartng");
1730 KMessageBox::sorry(0, i18n("Your sidebar is not functional or unavailable."), i18n("Show History Sidebar"));
1735 if (!static_cast<KToggleAction
*>(a
)->isChecked()) {
1737 QTimer::singleShot( 0, this, SLOT(slotGoHistory()));
1741 // Tell it to show the history plugin
1742 MapViews::ConstIterator it
;
1743 for (it
= viewMap().begin(); it
!= viewMap().end(); ++it
) {
1744 KonqView
*view
= it
.value();
1746 KService::Ptr svc
= view
->service();
1747 if (svc
->desktopEntryName() == "konq_sidebartng") {
1748 if (!view
->part()->openUrl( KUrl( "sidebar:history.desktop" ) ) )
1749 KMessageBox::sorry(0, i18n("Cannot find running history plugin in your sidebar."), i18n("Show History Sidebar"));
1756 void KonqMainWindow::slotConfigureExtensions()
1758 KonqExtensionManager
extensionManager(this, this, m_currentView
? m_currentView
->part() : 0);
1759 extensionManager
.exec();
1762 void KonqMainWindow::slotConfigure()
1764 if( !m_configureDialog
)
1766 m_configureDialog
= new KCMultiDialog( this );
1767 m_configureDialog
->setObjectName( "configureDialog" );
1768 connect(m_configureDialog
, SIGNAL(finished()), this, SLOT(slotConfigureDone()));
1769 connect(m_configureDialog
, SIGNAL(hidden()), this, SLOT(slotConfigureDone()));
1771 //BEGIN SYNC with initActions()
1772 const char* toplevelModules
[]={
1775 "kcmkonqyperformance",
1778 for (uint i
=0;i
<sizeof(toplevelModules
)/sizeof(char*);++i
)
1779 if (KAuthorized::authorizeControlModule(toplevelModules
[i
]))
1780 m_configureDialog
->addModule(KCModuleInfo(toplevelModules
[i
]));
1783 if (KAuthorized::authorizeControlModule("filebehavior") )
1785 KPageWidgetItem
* fileManagementGroup
= m_configureDialog
->addModule("filebehavior");
1786 fileManagementGroup
->setName(i18n("File Management"));
1787 const char* fmModules
[]={
1788 "kcmdolphinviewmodes",
1791 for (uint i
=0;i
<sizeof(fmModules
)/sizeof(char*);++i
)
1792 if (KAuthorized::authorizeControlModule(fmModules
[i
]))
1793 m_configureDialog
->addModule(KCModuleInfo(fmModules
[i
]),fileManagementGroup
);
1796 if (KAuthorized::authorizeControlModule("khtml_behavior"))
1798 KPageWidgetItem
* webGroup
= m_configureDialog
->addModule("khtml_behavior");
1799 webGroup
->setName(i18n("Web Browsing"));
1801 const char* webModules
[]={
1813 for (uint i
=0;i
<sizeof(webModules
)/sizeof(char*);++i
)
1814 if (KAuthorized::authorizeControlModule(webModules
[i
]))
1815 m_configureDialog
->addModule(KCModuleInfo(webModules
[i
]),webGroup
);
1818 //END SYNC with initActions()
1822 m_configureDialog
->show();
1826 void KonqMainWindow::slotConfigureDone()
1828 // Cleanup the dialog so other instances can use it..
1829 if ( m_configureDialog
)
1831 m_configureDialog
->deleteLater();
1832 m_configureDialog
= 0;
1836 void KonqMainWindow::slotConfigureSpellChecking()
1838 Sonnet::ConfigDialog
dialog( KGlobal::config().data(), this);
1839 dialog
.setWindowIcon( KIcon( "konqueror" ));
1843 void KonqMainWindow::slotConfigureToolbars()
1845 slotForceSaveMainWindowSettings();
1846 KEditToolBar
dlg(factory(), this);
1847 connect(&dlg
,SIGNAL(newToolBarConfig()),this,SLOT(slotNewToolbarConfig()));
1848 connect(&dlg
,SIGNAL(newToolBarConfig()),this,SLOT(initBookmarkBar()));
1850 checkDisableClearButton();
1853 void KonqMainWindow::slotNewToolbarConfig() // This is called when OK or Apply is clicked
1855 if ( m_toggleViewGUIClient
)
1856 plugActionList( QLatin1String( "toggleview" ), m_toggleViewGUIClient
->actions() );
1857 if ( m_currentView
&& m_currentView
->appServiceOffers().count() > 0 )
1858 plugActionList( "openwith", m_openWithActions
);
1860 plugViewModeActions();
1862 KConfigGroup cg
= KGlobal::config()->group( "KonqMainWindow" );
1863 applyMainWindowSettings( cg
);
1866 void KonqMainWindow::slotUndoAvailable( bool avail
)
1868 m_paUndo
->setEnabled( avail
);
1871 void KonqMainWindow::slotPartChanged( KonqView
*childView
, KParts::ReadOnlyPart
*oldPart
, KParts::ReadOnlyPart
*newPart
)
1873 m_mapViews
.remove( oldPart
);
1874 m_mapViews
.insert( newPart
, childView
);
1876 // Remove the old part, and add the new part to the manager
1877 // Note: this makes the new part active... so it calls slotPartActivated
1879 m_pViewManager
->replacePart( oldPart
, newPart
, false );
1880 // Set active immediately
1881 m_pViewManager
->setActivePart(newPart
);
1887 void KonqMainWindow::slotRunFinished()
1889 const KonqRun
*run
= static_cast<const KonqRun
*>( sender() );
1891 if ( !run
->mailtoURL().isEmpty() )
1893 KToolInvocation::invokeMailer( run
->mailtoURL() );
1896 if ( run
->hasError() ) { // we had an error
1897 QDBusMessage message
= QDBusMessage::createSignal( KONQ_MAIN_PATH
, "org.kde.Konqueror.Main", "removeFromCombo" );
1898 message
<< run
->url().prettyUrl();
1899 QDBusConnection::sessionBus().send( message
);
1902 KonqView
*childView
= run
->childView();
1904 // Check if we found a mimetype _and_ we got no error (example: cancel in openwith dialog)
1905 if ( run
->wasMimeTypeFound() && !run
->hasError() )
1908 // We do this here and not in the constructor, because
1909 // we are waiting for the first view to be set up before doing this...
1910 // Note: this is only used when konqueror is started from command line.....
1911 if ( m_bNeedApplyKonqMainWindowSettings
)
1913 m_bNeedApplyKonqMainWindowSettings
= false; // only once
1914 applyKonqMainWindowSettings();
1920 // An error happened in KonqRun - stop wheel etc.
1923 childView
->setLoading(false);
1925 if (childView
== m_currentView
) {
1928 // Revert to working URL - unless the URL was typed manually
1929 if (run
->typedUrl().isEmpty() && childView
->currentHistoryEntry()) // not typed
1930 childView
->setLocationBarURL(childView
->currentHistoryEntry()->locationBarURL
);
1932 } else { // No view, e.g. empty webbrowsing profile
1937 void KonqMainWindow::applyKonqMainWindowSettings()
1939 const QStringList toggableViewsShown
= KonqSettings::toggableViewsShown();
1940 QStringList::ConstIterator togIt
= toggableViewsShown
.begin();
1941 QStringList::ConstIterator togEnd
= toggableViewsShown
.end();
1942 for ( ; togIt
!= togEnd
; ++togIt
)
1944 // Find the action by name
1945 // KAction * act = m_toggleViewGUIClient->actionCollection()->action( (*togIt).toLatin1() );
1946 QAction
*act
= m_toggleViewGUIClient
->action( *togIt
);
1950 kWarning(1202) << "Unknown toggable view in ToggableViewsShown " << *togIt
;
1954 void KonqMainWindow::slotSetStatusBarText( const QString
& )
1956 // Reimplemented to disable KParts::MainWindow default behaviour
1957 // Does nothing here, see KonqFrame
1960 void KonqMainWindow::slotViewCompleted( KonqView
* view
)
1964 // Need to update the current working directory
1965 // of the completion object every time the user
1966 // changes the directory!! (DA)
1967 if( m_pURLCompletion
)
1969 KUrl
u( view
->locationBarURL() );
1970 if( u
.isLocalFile() )
1971 m_pURLCompletion
->setDir( u
.path() );
1973 m_pURLCompletion
->setDir( u
.url() ); //needs work!! (DA)
1977 void KonqMainWindow::slotPartActivated(KParts::Part
*part
)
1979 //kDebug(1202) << part
1980 // << (part && part->componentData().isValid() && part->componentData().aboutData() ? part->componentData().aboutData()->appName() : "");
1982 KonqView
*newView
= 0;
1983 KonqView
*oldView
= m_currentView
;
1986 newView
= m_mapViews
.value( static_cast<KParts::ReadOnlyPart
*>(part
) );
1988 if (newView
->isPassiveMode()) {
1989 // Passive view. Don't connect anything, don't change m_currentView
1990 // Another view will become the current view very soon
1991 //kDebug(1202) << "Passive mode - return";
1996 KParts::BrowserExtension
*ext
= 0;
1999 ext
= oldView
->browserExtension();
2001 //kDebug(1202) << "Disconnecting extension for view" << oldView;
2002 disconnectExtension( ext
);
2006 //kDebug(1202) << "New current view" << newView;
2007 m_currentView
= newView
;
2009 //kDebug(1202) << "No part activated - returning";
2010 unplugViewModeActions();
2012 KParts::MainWindow::setCaption(QString());
2016 ext
= m_currentView
->browserExtension();
2019 connectExtension(ext
);
2021 kDebug(1202) << "No Browser Extension for the new part";
2022 // Disable all browser-extension actions
2024 KParts::BrowserExtension::ActionSlotMap
* actionSlotMap
= KParts::BrowserExtension::actionSlotMapPtr();
2025 KParts::BrowserExtension::ActionSlotMap::ConstIterator it
= actionSlotMap
->constBegin();
2026 const KParts::BrowserExtension::ActionSlotMap::ConstIterator itEnd
= actionSlotMap
->constEnd();
2027 for (; it
!= itEnd
; ++it
) {
2028 QAction
* act
= actionCollection()->action(QString::fromLatin1(it
.key()));
2031 act
->setEnabled( false );
2035 m_paCopyFiles
->setEnabled(false);
2037 m_paMoveFiles
->setEnabled(false);
2042 // View-dependent GUI
2044 KParts::MainWindow::setCaption( m_currentView
->caption() );
2045 // This line causes #170470 when removing the current tab, because QTabBar
2046 // emits currentChanged before calling tabRemoved, so KTabWidget gets confused.
2047 // I don't see a need for it anyway...
2048 //m_currentView->frame()->setTitle(m_currentView->caption(), 0);
2050 updateOpenWithActions();
2051 updateViewActions(); // undo, lock, link and other view-dependent actions
2052 updateViewModeActions();
2054 m_paHome
->setIcon(KIcon(m_currentView
->showsDirectory() ? "user-home" : "go-home"));
2055 m_paHome
->setText( m_currentView
->showsDirectory() ? i18n( "Home Folder") : i18n( "Home Page" ) );
2056 m_paHome
->setToolTip( m_currentView
->showsDirectory() ? i18n( "Navigate to your 'Home Folder'") : i18n( "Navigate to your 'Home Page'" ) );
2057 m_paHome
->setWhatsThis(m_currentView
->showsDirectory() ? i18n( "Navigate to your local 'Home Folder'" ) :
2058 i18n( "<html>Navigate to your 'Home Page'<br /><br />"
2059 "You can configure the location where this button takes you "
2060 "under <b>Settings -> Configure Konqueror -> General</b>.</html>" ) );
2062 m_currentView
->frame()->statusbar()->updateActiveStatus();
2064 if ( oldView
&& oldView
->frame() )
2065 oldView
->frame()->statusbar()->updateActiveStatus();
2067 //kDebug(1202) << "setting location bar url to"
2068 // << m_currentView->locationBarURL() << "m_currentView=" << m_currentView;
2069 m_currentView
->setLocationBarURL( m_currentView
->locationBarURL() );
2071 updateToolBarActions();
2073 m_currentView
->setActiveComponent();
2076 void KonqMainWindow::insertChildView( KonqView
*childView
)
2078 //kDebug(1202) << childView;
2079 m_mapViews
.insert(childView
->part(), childView
);
2081 connect(childView
, SIGNAL(viewCompleted(KonqView
*)),
2082 this, SLOT(slotViewCompleted(KonqView
*)));
2084 if (!m_pViewManager
->isLoadingProfile()) // see KonqViewManager::loadViewProfile
2086 emit
viewAdded(childView
);
2089 // Called by KonqViewManager, internal
2090 void KonqMainWindow::removeChildView( KonqView
*childView
)
2092 //kDebug(1202) << childView;
2094 disconnect( childView
, SIGNAL( viewCompleted( KonqView
* ) ),
2095 this, SLOT( slotViewCompleted( KonqView
* ) ) );
2101 MapViews::Iterator it
= m_mapViews
.begin();
2102 const MapViews::Iterator end
= m_mapViews
.end();
2104 // find it in the map - can't use the key since childView->part() might be 0
2106 //kDebug(1202) << "Searching map";
2108 while ( it
!= end
&& it
.value() != childView
)
2111 //kDebug(1202) << "Verifying search results";
2113 if ( it
== m_mapViews
.end() )
2115 kWarning(1202) << "KonqMainWindow::removeChildView childView " << childView
<< " not in map !" ;
2119 //kDebug(1202) << "Removing view" << childView;
2121 m_mapViews
.erase( it
);
2124 emit
viewRemoved( childView
);
2130 // KonqViewManager takes care of m_currentView
2133 void KonqMainWindow::viewCountChanged()
2135 // This is called when the number of views changes.
2137 int lvc
= linkableViewsCount();
2138 m_paLinkView
->setEnabled( lvc
> 1 );
2140 // Only one view (or one view + sidebar) -> make it/them unlinked
2142 MapViews::Iterator it
= m_mapViews
.begin();
2143 MapViews::Iterator end
= m_mapViews
.end();
2144 for (; it
!= end
; ++it
)
2145 it
.value()->setLinkedView( false );
2150 m_pViewManager
->viewCountChanged();
2153 void KonqMainWindow::viewsChanged()
2155 // This is called when the number of views changes OR when
2156 // the type of some view changes.
2158 // Nothing here anymore, but don't cleanup, some might come back later.
2160 updateViewActions(); // undo, lock, link and other view-dependent actions
2163 KonqView
* KonqMainWindow::childView( KParts::ReadOnlyPart
*view
)
2165 MapViews::ConstIterator it
= m_mapViews
.constFind( view
);
2166 if ( it
!= m_mapViews
.constEnd() )
2172 KonqView
* KonqMainWindow::childView( KParts::ReadOnlyPart
*callingPart
, const QString
&name
, KParts::BrowserHostExtension
*&hostExtension
, KParts::ReadOnlyPart
**part
)
2174 //kDebug() << "this=" << this << "looking for" << name;
2176 MapViews::ConstIterator it
= m_mapViews
.constBegin();
2177 MapViews::ConstIterator end
= m_mapViews
.constEnd();
2178 for (; it
!= end
; ++it
)
2180 KonqView
* view
= it
.value();
2181 QString viewName
= view
->viewName();
2182 //kDebug() << " - viewName=" << viewName
2183 // << "frame names:" << view->frameNames();
2185 // First look for a hostextension containing this frame name
2186 KParts::BrowserHostExtension
*ext
= KParts::BrowserHostExtension::childObject( view
->part() );
2189 ext
= ext
->findFrameParent(callingPart
, name
);
2190 kDebug(1202) << "BrowserHostExtension found part" << ext
;
2192 continue; // Don't use this window
2195 if ( !viewName
.isEmpty() && viewName
== name
)
2197 kDebug(1202) << "found existing view by name:" << view
;
2200 *part
= view
->part();
2204 // KParts::BrowserHostExtension* ext = KonqView::hostExtension( view->part(), name );
2208 const QList
<KParts::ReadOnlyPart
*> frames
= ext
->frames();
2209 QListIterator
<KParts::ReadOnlyPart
*> frameIt(frames
);
2210 while (frameIt
.hasNext())
2212 KParts::ReadOnlyPart
*item
= frameIt
.next();
2213 if ( item
->objectName() == name
)
2215 kDebug(1202) << "found a frame of name" << name
<< ":" << item
;
2216 hostExtension
= ext
;
2228 int KonqMainWindow::activeViewsCount() const
2231 MapViews::ConstIterator end
= m_mapViews
.constEnd();
2232 for (MapViews::ConstIterator it
= m_mapViews
.constBegin(); it
!= end
; ++it
)
2233 if ( !it
.value()->isPassiveMode() )
2239 int KonqMainWindow::activeViewsNotLockedCount() const
2242 MapViews::ConstIterator end
= m_mapViews
.constEnd();
2243 for (MapViews::ConstIterator it
= m_mapViews
.constBegin(); it
!= end
; ++it
) {
2244 if ( !it
.value()->isPassiveMode() && !it
.value()->isLockedLocation() )
2251 int KonqMainWindow::linkableViewsCount() const
2254 MapViews::ConstIterator it
= m_mapViews
.constBegin();
2255 MapViews::ConstIterator end
= m_mapViews
.constEnd();
2256 for (; it
!= end
; ++it
)
2257 if ( !it
.value()->isFollowActive() )
2263 int KonqMainWindow::mainViewsCount() const
2266 MapViews::ConstIterator it
= m_mapViews
.constBegin();
2267 const MapViews::ConstIterator end
= m_mapViews
.constEnd();
2268 for (; it
!= end
; ++it
) {
2269 if ( !it
.value()->isPassiveMode() && !it
.value()->isToggleView() ) {
2270 //kDebug(1202) << res << it.value() << it.value()->part()->widget();
2278 void KonqMainWindow::slotURLEntered(const QString
&text
, Qt::KeyboardModifiers modifiers
)
2280 if (m_bURLEnterLock
|| text
.isEmpty())
2283 m_bURLEnterLock
= true;
2285 if ((modifiers
& Qt::ControlModifier
) || (modifiers
& Qt::AltModifier
)) {
2286 m_combo
->setURL(m_currentView
? m_currentView
->url().prettyUrl() : QString());
2287 openFilteredUrl(text
.trimmed(), true /*inNewTab*/);
2289 openFilteredUrl(text
.trimmed());
2292 m_bURLEnterLock
= false;
2295 void KonqMainWindow::slotSplitViewHorizontal()
2297 if ( !m_currentView
)
2299 KonqView
* oldView
= m_currentView
;
2300 KonqView
* newView
= m_pViewManager
->splitView(m_currentView
, Qt::Horizontal
);
2303 KonqOpenURLRequest req
;
2304 req
.forceAutoEmbed
= true;
2305 openView(oldView
->serviceType(), oldView
->url(), newView
, req
);
2308 void KonqMainWindow::slotSplitViewVertical()
2310 if ( !m_currentView
)
2312 KonqView
* oldView
= m_currentView
;
2313 KonqView
* newView
= m_pViewManager
->splitView(m_currentView
, Qt::Vertical
);
2316 KonqOpenURLRequest req
;
2317 req
.forceAutoEmbed
= true;
2318 openView(oldView
->serviceType(), oldView
->url(), newView
, req
);
2321 void KonqMainWindow::slotAddTab()
2323 // we can hardcode text/html because this is what about:blank will use anyway
2324 KonqView
* newView
= m_pViewManager
->addTab("text/html",
2327 KonqSettings::openAfterCurrentPage());
2331 openUrl( newView
, KUrl("about:blank"), QString() );
2333 //HACK!! QTabBar likes to steal focus when changing widgets. This can result
2334 //in a flicker since we don't want it to get focus we want the combo to get
2336 QWidget
*widget
= newView
->frame() && newView
->frame()->part() ?
2337 newView
->frame()->part()->widget() : 0;
2339 widget
->setFocusProxy(m_combo
);
2341 m_pViewManager
->showTab( newView
);
2344 widget
->setFocusProxy(0);
2349 void KonqMainWindow::slotDuplicateTab()
2351 if ( !m_currentView
)
2353 // TODO does this work with splitted views? sounds like I'll get only the current view
2354 // in the new tab, not the whole contents of the current tab...
2355 m_pViewManager
->duplicateTab( m_currentView
->frame(), KonqSettings::openAfterCurrentPage() );
2358 void KonqMainWindow::slotDuplicateTabPopup()
2360 m_pViewManager
->duplicateTab( m_pWorkingTab
, KonqSettings::openAfterCurrentPage() );
2363 void KonqMainWindow::slotBreakOffTab()
2365 if ( !m_currentView
)
2367 if (m_currentView
->part() &&
2368 (m_currentView
->part()->metaObject()->indexOfProperty("modified") != -1) ) {
2369 QVariant prop
= m_currentView
->part()->property("modified");
2370 if (prop
.isValid() && prop
.toBool())
2371 if ( KMessageBox::warningContinueCancel( this,
2372 i18n("This tab contains changes that have not been submitted.\nDetaching the tab will discard these changes."),
2373 i18n("Discard Changes?"), KGuiItem(i18n("&Discard Changes"),"tab-detach"), KStandardGuiItem::cancel(), "discardchangesdetach") != KMessageBox::Continue
)
2377 m_pViewManager
->breakOffTab( m_currentView
->frame(), size() );
2378 updateViewActions();
2381 void KonqMainWindow::slotBreakOffTabPopup()
2383 KonqView
* originalView
= m_currentView
;
2384 KonqView
*view
= m_pWorkingTab
->activeChildView();
2385 if (view
&& view
->part() && (view
->part()->metaObject()->indexOfProperty("modified") != -1) ) {
2386 QVariant prop
= view
->part()->property("modified");
2387 if (prop
.isValid() && prop
.toBool()) {
2388 m_pViewManager
->showTab( view
);
2389 if ( KMessageBox::warningContinueCancel( this,
2390 i18n("This tab contains changes that have not been submitted.\nDetaching the tab will discard these changes."),
2391 i18n("Discard Changes?"), KGuiItem(i18n("&Discard Changes"),"tab-detach"), KStandardGuiItem::cancel(), "discardchangesdetach") != KMessageBox::Continue
)
2393 m_pViewManager
->showTab( originalView
);
2398 m_pViewManager
->showTab( originalView
);
2400 //Can't do this safely here as the tabbar may disappear and we're
2402 QTimer::singleShot(0, this, SLOT( slotBreakOffTabPopupDelayed() ) );
2405 void KonqMainWindow::slotBreakOffTabPopupDelayed()
2407 m_pViewManager
->breakOffTab( m_pWorkingTab
, size() );
2408 updateViewActions();
2411 void KonqMainWindow::slotPopupNewWindow()
2413 KFileItemList::const_iterator it
= m_popupItems
.constBegin();
2414 const KFileItemList::const_iterator end
= m_popupItems
.constEnd();
2415 for ( ; it
!= end
; ++it
) {
2416 KonqMisc::createNewWindow((*it
).targetUrl(), m_popupUrlArgs
, m_popupUrlBrowserArgs
);
2420 void KonqMainWindow::slotPopupThisWindow()
2422 openUrl(0, m_popupItems
.first().url());
2425 void KonqMainWindow::slotPopupNewTab()
2427 bool openAfterCurrentPage
= KonqSettings::openAfterCurrentPage();
2428 bool newTabsInFront
= KonqSettings::newTabsInFront();
2430 if (QApplication::keyboardModifiers() & Qt::ShiftModifier
)
2431 newTabsInFront
= !newTabsInFront
;
2433 popupNewTab(newTabsInFront
, openAfterCurrentPage
);
2436 void KonqMainWindow::popupNewTab(bool infront
, bool openAfterCurrentPage
)
2438 KonqOpenURLRequest req
;
2439 req
.newTabInFront
= false;
2440 req
.forceAutoEmbed
= true;
2441 req
.openAfterCurrentPage
= openAfterCurrentPage
;
2442 req
.args
= m_popupUrlArgs
;
2443 req
.browserArgs
= m_popupUrlBrowserArgs
;
2444 req
.browserArgs
.setNewTab(true);
2446 for ( int i
= 0; i
< m_popupItems
.count(); ++i
)
2448 if ( infront
&& i
== m_popupItems
.count()-1 )
2450 req
.newTabInFront
= true;
2452 openUrl( 0, m_popupItems
[i
].targetUrl(), QString(), req
);
2456 void KonqMainWindow::openMultiURL( const KUrl::List
& url
)
2458 KUrl::List::ConstIterator it
= url
.constBegin();
2459 const KUrl::List::ConstIterator end
= url
.constEnd();
2460 for (; it
!= end
; ++it
)
2462 KonqView
* newView
= m_pViewManager
->addTab("text/html");
2463 Q_ASSERT( newView
);
2464 if (newView
== 0) continue;
2465 openUrl( newView
, *it
, QString() );
2466 m_pViewManager
->showTab( newView
);
2472 void KonqMainWindow::slotRemoveView()
2474 if (m_currentView
&& m_currentView
->part() &&
2475 (m_currentView
->part()->metaObject()->indexOfProperty("modified") != -1) ) {
2476 QVariant prop
= m_currentView
->part()->property("modified");
2477 if (prop
.isValid() && prop
.toBool())
2478 if ( KMessageBox::warningContinueCancel( this,
2479 i18n("This view contains changes that have not been submitted.\nClosing the view will discard these changes."),
2480 i18n("Discard Changes?"), KGuiItem(i18n("&Discard Changes"),"view-close"), KStandardGuiItem::cancel(), "discardchangesclose") != KMessageBox::Continue
)
2484 // takes care of choosing the new active view
2485 m_pViewManager
->removeView( m_currentView
);
2488 void KonqMainWindow::slotRemoveTab()
2490 if ( !m_currentView
)
2492 if ( m_currentView
->part() &&
2493 (m_currentView
->part()->metaObject()->indexOfProperty("modified") != -1) ) {
2494 QVariant prop
= m_currentView
->part()->property("modified");
2495 if (prop
.isValid() && prop
.toBool())
2496 if ( KMessageBox::warningContinueCancel( this,
2497 i18n("This tab contains changes that have not been submitted.\nClosing the tab will discard these changes."),
2498 i18n("Discard Changes?"), KGuiItem(i18n("&Discard Changes"),"tab-close"), KStandardGuiItem::cancel(), "discardchangesclose") != KMessageBox::Continue
)
2502 KonqFrameBase
* frame
= dynamic_cast<KonqFrameBase
*>(m_pViewManager
->tabContainer()->currentWidget());
2505 m_pViewManager
->removeTab( frame
);
2508 void KonqMainWindow::slotRemoveTabPopup()
2510 KonqView
*originalView
= m_currentView
;
2511 KonqView
*view
= m_pWorkingTab
->activeChildView();
2512 if (view
&& view
->part() && (view
->part()->metaObject()->indexOfProperty("modified") != -1) ) {
2513 QVariant prop
= view
->part()->property("modified");
2514 if (prop
.isValid() && prop
.toBool()) {
2515 m_pViewManager
->showTab( view
);
2516 if ( KMessageBox::warningContinueCancel( this,
2517 i18n("This tab contains changes that have not been submitted.\nClosing the tab will discard these changes."),
2518 i18n("Discard Changes?"), KGuiItem(i18n("&Discard Changes"),"tab-close"), KStandardGuiItem::cancel(), "discardchangesclose") != KMessageBox::Continue
)
2520 m_pViewManager
->showTab( originalView
);
2524 m_pViewManager
->showTab( originalView
);
2527 //Can't do immediately - may kill the tabbar, and we're in an event path down from it
2528 QTimer::singleShot( 0, this, SLOT( slotRemoveTabPopupDelayed() ) );
2531 void KonqMainWindow::slotRemoveTabPopupDelayed()
2533 m_pViewManager
->removeTab( m_pWorkingTab
);
2536 void KonqMainWindow::slotRemoveOtherTabs()
2538 // This action is triggered by the shortcut that removes other tabs, so
2539 // we need to set the working tab to the current tab
2540 m_pWorkingTab
= m_pViewManager
->tabContainer()->tabContaining(m_currentView
->frame());
2541 slotRemoveOtherTabsPopup();
2544 void KonqMainWindow::slotRemoveOtherTabsPopup()
2546 if ( KMessageBox::warningContinueCancel( this,
2547 i18n("Do you really want to close all other tabs?"),
2548 i18n("Close Other Tabs Confirmation"), KGuiItem(i18n("Close &Other Tabs"),"tab-close-other"),
2549 KStandardGuiItem::cancel(), "CloseOtherTabConfirm") != KMessageBox::Continue
)
2552 KonqView
*originalView
= m_currentView
;
2553 MapViews::ConstIterator it
= m_mapViews
.constBegin();
2554 MapViews::ConstIterator end
= m_mapViews
.constEnd();
2555 for (; it
!= end
; ++it
) {
2556 KonqView
*view
= it
.value();
2557 // m_currentView might be a view contained inside a splitted view so what we'll
2558 // do here is just compare if the views are inside the same tab.
2559 if ( view
!= originalView
&& view
&& m_pViewManager
->tabContainer()->tabContaining(view
->frame()) != m_pWorkingTab
&&
2560 view
->part() && (view
->part()->metaObject()->indexOfProperty("modified") != -1) ) {
2561 QVariant prop
= view
->part()->property("modified");
2562 if (prop
.isValid() && prop
.toBool()) {
2563 m_pViewManager
->showTab( view
);
2564 if ( KMessageBox::warningContinueCancel( this,
2565 i18n("This tab contains changes that have not been submitted.\nClosing other tabs will discard these changes."),
2566 i18n("Discard Changes?"), KGuiItem(i18n("&Discard Changes"),"tab-close"), KStandardGuiItem::cancel(), "discardchangescloseother") != KMessageBox::Continue
)
2568 m_pViewManager
->showTab( originalView
);
2574 m_pViewManager
->showTab( originalView
);
2576 //Can't do immediately - kills the tabbar, and we're in an event path down from it
2577 QTimer::singleShot( 0, this, SLOT( slotRemoveOtherTabsPopupDelayed() ) );
2580 void KonqMainWindow::slotRemoveOtherTabsPopupDelayed()
2582 m_pViewManager
->removeOtherTabs( m_pWorkingTab
);
2583 updateViewActions();
2586 void KonqMainWindow::slotReloadAllTabs()
2588 KonqView
*originalView
= m_currentView
;
2589 MapViews::ConstIterator it
= m_mapViews
.constBegin();
2590 MapViews::ConstIterator end
= m_mapViews
.constEnd();
2591 for (; it
!= end
; ++it
) {
2592 KonqView
*view
= it
.value();
2593 if (view
&& view
->part() && (view
->part()->metaObject()->indexOfProperty("modified") != -1) ) {
2594 QVariant prop
= view
->part()->property("modified");
2595 if (prop
.isValid() && prop
.toBool()) {
2596 m_pViewManager
->showTab( view
);
2597 if ( KMessageBox::warningContinueCancel( this,
2598 i18n("This tab contains changes that have not been submitted.\nReloading all tabs will discard these changes."),
2599 i18n("Discard Changes?"), KGuiItem(i18n("&Discard Changes"),"view-refresh"), KStandardGuiItem::cancel(), "discardchangesreload") != KMessageBox::Continue
)
2601 m_pViewManager
->showTab( originalView
);
2607 m_pViewManager
->showTab( originalView
);
2609 m_pViewManager
->reloadAllTabs();
2610 updateViewActions();
2614 void KonqMainWindow::slotActivateNextTab()
2616 m_pViewManager
->activateNextTab();
2619 void KonqMainWindow::slotActivatePrevTab()
2621 m_pViewManager
->activatePrevTab();
2624 void KonqMainWindow::slotActivateTab()
2626 m_pViewManager
->activateTab( sender()->objectName().right( 2 ).toInt() -1 );
2629 void KonqMainWindow::slotDumpDebugInfo()
2633 m_pViewManager
->printFullHierarchy();
2637 bool KonqMainWindow::askForTarget(const KLocalizedString
& text
, KUrl
& url
)
2639 const KUrl initialUrl
= (viewCount()==2) ? otherView(m_currentView
)->url() : m_currentView
->url();
2640 QString label
= text
.subs( m_currentView
->url().pathOrUrl() ).toString();
2641 KUrlRequesterDialog
dlg(initialUrl
.pathOrUrl(), label
, this);
2642 dlg
.setCaption(i18n("Enter Target"));
2643 dlg
.urlRequester()->setMode( KFile::File
| KFile::ExistingOnly
| KFile::Directory
);
2646 url
= dlg
.selectedUrl();
2647 if ( url
.isValid() )
2651 KMessageBox::error( this, i18n("<qt><b>%1</b> is not valid</qt>", url
.url()));
2658 void KonqMainWindow::slotRequesterClicked( KUrlRequester
*req
)
2660 req
->fileDialog()->setMode(KFile::Directory
|KFile::ExistingOnly
);
2663 void KonqMainWindow::slotCopyFiles()
2666 if (!askForTarget(ki18n("Copy selected files from %1 to:"), dest
))
2669 KonqOperations::copy(this, KonqOperations::COPY
, currentURLs(), dest
);
2672 void KonqMainWindow::slotMoveFiles()
2675 if (!askForTarget(ki18n("Move selected files from %1 to:"), dest
))
2678 KonqOperations::copy(this, KonqOperations::MOVE
, currentURLs(), dest
);
2681 KUrl::List
KonqMainWindow::currentURLs() const
2684 if ( m_currentView
) {
2685 urls
.append( m_currentView
->url() );
2687 KonqDirPart
* dirPart
= ::qobject_cast
<KonqDirPart
*>(m_currentView
->part());
2689 const KFileItemList itemList
= dirPart
->selectedFileItems();
2690 if (!itemList
.isEmpty()) { // Return list of selected items only if we have a selection
2691 urls
= itemList
.urlList();
2699 // Only valid if there are one or two views
2700 KonqView
* KonqMainWindow::otherView( KonqView
* view
) const
2702 assert( viewCount() <= 2 );
2703 MapViews::ConstIterator it
= m_mapViews
.constBegin();
2704 if ( (*it
) == view
)
2706 if ( it
!= m_mapViews
.constEnd() )
2711 void KonqMainWindow::slotSaveViewProfile()
2713 m_pViewManager
->showProfileDlg( m_pViewManager
->currentProfile() );
2716 void KonqMainWindow::slotUpAboutToShow()
2718 QMenu
*popup
= m_paUp
->menu();
2723 // Use the location bar URL, because in case we display a index.html
2724 // we want to go up from the dir, not from the index.html
2725 KUrl
u(m_currentView
->locationBarURL());
2727 while (u
.hasPath()) {
2728 QAction
* action
= new QAction(KIcon(KonqPixmapProvider::self()->iconNameFor(u
)),
2732 popup
->addAction(action
);
2734 if (u
.path() == "/" || ++i
> 10)
2741 void KonqMainWindow::slotUp(Qt::MouseButtons buttons
, Qt::KeyboardModifiers modifiers
)
2743 m_goMouseState
= buttons
;
2744 m_goKeyboardState
= modifiers
;
2745 QTimer::singleShot( 0, this, SLOT( slotUpDelayed() ) );
2748 void KonqMainWindow::slotUp()
2750 m_goMouseState
= Qt::LeftButton
;
2751 m_goKeyboardState
= Qt::NoModifier
;
2752 QTimer::singleShot( 0, this, SLOT( slotUpDelayed() ) );
2755 void KonqMainWindow::slotUpDelayed()
2757 KonqOpenURLRequest req
;
2758 req
.browserArgs
.setNewTab(true);
2759 req
.forceAutoEmbed
= true;
2761 req
.openAfterCurrentPage
= KonqSettings::openAfterCurrentPage();
2762 req
.newTabInFront
= KonqSettings::newTabsInFront();
2764 if (m_goKeyboardState
& Qt::ShiftModifier
)
2765 req
.newTabInFront
= !req
.newTabInFront
;
2767 const QString
& url
= m_currentView
->upUrl().url();
2768 if(m_goKeyboardState
& Qt::ControlModifier
)
2769 openFilteredUrl(url
, req
);
2770 else if(m_goMouseState
& Qt::MidButton
)
2772 if(KonqSettings::mmbOpensTab())
2773 openFilteredUrl( url
, req
);
2775 KonqMisc::createNewWindow( url
);
2778 openFilteredUrl( url
, false );
2779 m_goMouseState
= Qt::LeftButton
;
2782 void KonqMainWindow::slotUpActivated(QAction
* action
)
2784 openUrl( 0, action
->data().value
<KUrl
>() );
2787 void KonqMainWindow::slotGoHistoryActivated( int steps
)
2789 slotGoHistoryActivated( steps
, Qt::LeftButton
, Qt::NoModifier
);
2792 void KonqMainWindow::slotGoHistoryActivated( int steps
, Qt::MouseButtons buttons
, Qt::KeyboardModifiers modifiers
)
2796 // Only start 1 timer.
2798 m_goMouseState
= buttons
;
2799 m_goKeyboardState
= modifiers
;
2800 QTimer::singleShot( 0, this, SLOT(slotGoHistoryDelayed()));
2804 void KonqMainWindow::slotGoHistoryDelayed()
2806 if (!m_currentView
) return;
2808 bool openAfterCurrentPage
= KonqSettings::openAfterCurrentPage();
2809 bool mmbOpensTab
= KonqSettings::mmbOpensTab();
2810 bool inFront
= KonqSettings::newTabsInFront();
2811 if(m_goKeyboardState
& Qt::ShiftModifier
)
2814 if(m_goKeyboardState
& Qt::ControlModifier
)
2816 KonqView
* newView
= m_pViewManager
->addTabFromHistory( m_currentView
, m_goBuffer
, openAfterCurrentPage
);
2817 if (newView
&& inFront
)
2818 m_pViewManager
->showTab( newView
);
2820 else if(m_goMouseState
& Qt::MidButton
)
2824 KonqView
* newView
= m_pViewManager
->addTabFromHistory( m_currentView
, m_goBuffer
, openAfterCurrentPage
);
2825 if (newView
&& inFront
)
2826 m_pViewManager
->showTab( newView
);
2829 KonqMisc::newWindowFromHistory(this->currentView(), m_goBuffer
);
2833 m_currentView
->go( m_goBuffer
);
2834 makeViewsFollow(m_currentView
->url(),
2835 KParts::OpenUrlArguments(),
2836 KParts::BrowserArguments(),
2837 m_currentView
->serviceType(),
2842 m_goMouseState
= Qt::LeftButton
;
2843 m_goKeyboardState
= Qt::NoModifier
;
2847 void KonqMainWindow::slotBackAboutToShow()
2849 m_paBack
->menu()->clear();
2851 KonqActions::fillHistoryPopup(m_currentView
->history(), m_currentView
->historyIndex(), m_paBack
->menu(), true, false);
2856 * Fill the closed tabs action menu before it's shown
2858 void KonqMainWindow::slotClosedItemsListAboutToShow()
2860 QMenu
* popup
= m_paClosedItems
->menu();
2861 // Clear the menu and fill it with a maximum of s_closedItemsListLength number of urls
2863 QAction
* clearAction
= popup
->addAction( i18nc("This menu entry empties the closed items history", "Empty Closed Items History") );
2864 connect(clearAction
, SIGNAL(triggered()), m_pUndoManager
, SLOT(clearClosedItemsList()));
2865 popup
->insertSeparator((QAction
*)0);
2867 QList
<KonqClosedItem
*>::ConstIterator it
=
2868 m_pUndoManager
->closedItemsList().constBegin();
2869 const QList
<KonqClosedItem
*>::ConstIterator end
=
2870 m_pUndoManager
->closedItemsList().constEnd();
2871 for ( int i
= 0; it
!= end
&& i
< s_closedItemsListLength
; ++it
, ++i
) {
2872 const QString text
= QString::number(i
) + ' ' + (*it
)->title();
2873 QAction
* action
= popup
->addAction( (*it
)->icon(), text
);
2874 action
->setActionGroup(m_closedItemsGroup
);
2877 KAcceleratorManager::manage(popup
);
2881 * Fill the sessions list action menu before it's shown
2883 void KonqMainWindow::slotSessionsListAboutToShow()
2885 QMenu
* popup
= m_paSessions
->menu();
2886 // Clear the menu and fill it with a maximum of s_closedItemsListLength number of urls
2888 QAction
* saveSessionAction
= popup
->addAction( KIcon("document-save"), i18n("Save As...") );
2889 connect(saveSessionAction
, SIGNAL(triggered()), this, SLOT(saveCurrentSession()));
2890 QAction
* manageSessionsAction
= popup
->addAction( KIcon("view-choose"), i18n("Manage...") );
2891 connect(manageSessionsAction
, SIGNAL(triggered()), this, SLOT(manageSessions()));
2892 popup
->insertSeparator((QAction
*)0);
2894 QString dir
= KStandardDirs::locateLocal("appdata", "sessions/");
2895 QDirIterator
it(dir
, QDir::Readable
|QDir::NoDotAndDotDot
|QDir::Dirs
);
2897 while (it
.hasNext())
2899 QFileInfo
fileInfo(it
.next());
2901 QAction
* action
= popup
->addAction( fileInfo
.baseName() );
2902 action
->setActionGroup(m_sessionsGroup
);
2903 action
->setData(fileInfo
.filePath());
2905 KAcceleratorManager::manage(popup
);
2908 void KonqMainWindow::saveCurrentSession()
2910 KonqNewSessionDlg
dlg( this );
2914 void KonqMainWindow::manageSessions()
2916 KonqSessionDlg
dlg( m_pViewManager
, this );
2920 void KonqMainWindow::slotSessionActivated(QAction
* action
)
2922 QString dirpath
= action
->data().toString();
2923 KonqSessionManager::self()->restoreSessions(dirpath
);
2926 void KonqMainWindow::updateClosedItemsAction()
2928 bool available
= m_pUndoManager
->undoAvailable();
2929 m_paClosedItems
->setEnabled(available
);
2931 m_paUndo
->setText(m_pUndoManager
->undoText());
2934 void KonqMainWindow::slotBack()
2936 slotGoHistoryActivated(-1);
2939 void KonqMainWindow::slotBack(Qt::MouseButtons buttons
, Qt::KeyboardModifiers modifiers
)
2941 slotGoHistoryActivated( -1, buttons
, modifiers
);
2944 void KonqMainWindow::slotBackActivated(QAction
* action
)
2946 KMenu
* backMenu
= static_cast<KMenu
*>( m_paBack
->menu() );
2947 slotGoHistoryActivated( action
->data().toInt(), backMenu
->mouseButtons(), backMenu
->keyboardModifiers());
2950 void KonqMainWindow::slotForwardAboutToShow()
2952 m_paForward
->menu()->clear();
2954 KonqActions::fillHistoryPopup(m_currentView
->history(), m_currentView
->historyIndex(), m_paForward
->menu(), false, true);
2957 void KonqMainWindow::slotForward()
2959 slotGoHistoryActivated( 1 );
2962 void KonqMainWindow::slotForward(Qt::MouseButtons buttons
, Qt::KeyboardModifiers modifiers
)
2964 slotGoHistoryActivated( 1, buttons
, modifiers
);
2967 void KonqMainWindow::slotForwardActivated(QAction
* action
)
2969 KMenu
* forwardMenu
= static_cast<KMenu
*>( m_paForward
->menu() );
2970 slotGoHistoryActivated( action
->data().toInt(), forwardMenu
->mouseButtons(), forwardMenu
->keyboardModifiers() );
2973 void KonqMainWindow::checkDisableClearButton()
2975 // if the location toolbar already has the clear_location action,
2976 // disable the combobox's embedded clear icon.
2977 KToolBar
* ltb
= toolBar("locationToolBar");
2978 QAction
* clearAction
= action("clear_location");
2980 foreach(QToolButton
* atb
, qFindChildren
<QToolButton
*>(ltb
))
2982 if (atb
->defaultAction() == clearAction
) {
2987 if (KLineEdit
* kle
= qobject_cast
<KLineEdit
*>(m_combo
->lineEdit()))
2988 kle
->setClearButtonShown( enable
);
2991 void KonqMainWindow::initCombo()
2993 m_combo
= new KonqCombo(0);
2995 m_combo
->init( s_pCompletion
);
2997 connect( m_combo
, SIGNAL(activated(const QString
&,Qt::KeyboardModifiers
)),
2998 this, SLOT(slotURLEntered(const QString
&,Qt::KeyboardModifiers
)) );
2999 connect( m_combo
, SIGNAL(showPageSecurity()),
3000 this, SLOT(showPageSecurity()) );
3002 m_pURLCompletion
= new KUrlCompletion();
3003 m_pURLCompletion
->setCompletionMode( s_pCompletion
->completionMode() );
3005 // This only turns completion off. ~ is still there in the result
3006 // We do want completion of user names, right?
3007 //m_pURLCompletion->setReplaceHome( false ); // Leave ~ alone! Will be taken care of by filters!!
3009 connect( m_combo
, SIGNAL(completionModeChanged(KGlobalSettings::Completion
)),
3010 SLOT( slotCompletionModeChanged( KGlobalSettings::Completion
)));
3011 connect( m_combo
, SIGNAL( completion( const QString
& )),
3012 SLOT( slotMakeCompletion( const QString
& )));
3013 connect( m_combo
, SIGNAL( substringCompletion( const QString
& )),
3014 SLOT( slotSubstringcompletion( const QString
& )));
3015 connect( m_combo
, SIGNAL( textRotation( KCompletionBase::KeyBindingType
) ),
3016 SLOT( slotRotation( KCompletionBase::KeyBindingType
)));
3017 connect( m_combo
, SIGNAL( cleared() ),
3018 SLOT ( slotClearHistory() ) );
3019 connect( m_pURLCompletion
, SIGNAL( match(const QString
&) ),
3020 SLOT( slotMatch(const QString
&) ));
3022 m_combo
->installEventFilter(this);
3024 static bool bookmarkCompletionInitialized
= false;
3025 if ( !bookmarkCompletionInitialized
)
3027 bookmarkCompletionInitialized
= true;
3028 DelayedInitializer
*initializer
= new DelayedInitializer( QEvent::KeyPress
, m_combo
->lineEdit() );
3029 connect( initializer
, SIGNAL( initialize() ), this, SLOT( bookmarksIntoCompletion() ) );
3033 void KonqMainWindow::bookmarksIntoCompletion()
3035 // add all bookmarks to the completion list for easy access
3036 bookmarksIntoCompletion( s_bookmarkManager
->root() );
3039 // the user changed the completion mode in the combo
3040 void KonqMainWindow::slotCompletionModeChanged( KGlobalSettings::Completion m
)
3042 s_pCompletion
->setCompletionMode( m
);
3044 KonqSettings::setSettingsCompletionMode( (int)m_combo
->completionMode() );
3045 KonqSettings::self()->writeConfig();
3047 // tell the other windows too (only this instance currently)
3048 foreach ( KonqMainWindow
* window
, *s_lstViews
) {
3049 if ( window
&& window
->m_combo
) {
3050 window
->m_combo
->setCompletionMode( m
);
3051 window
->m_pURLCompletion
->setCompletionMode( m
);
3056 // at first, try to find a completion in the current view, then use the global
3057 // completion (history)
3058 void KonqMainWindow::slotMakeCompletion( const QString
& text
)
3060 if( m_pURLCompletion
)
3062 m_urlCompletionStarted
= true; // flag for slotMatch()
3064 // kDebug(1202) << "Local Completion object found!";
3065 QString completion
= m_pURLCompletion
->makeCompletion( text
);
3066 m_currentDir
.clear();
3068 if ( completion
.isNull() && !m_pURLCompletion
->isRunning() )
3070 // No match() signal will come from m_pURLCompletion
3071 // ask the global one
3072 // tell the static completion object about the current completion mode
3073 completion
= s_pCompletion
->makeCompletion( text
);
3075 // some special handling necessary for CompletionPopup
3076 if ( m_combo
->completionMode() == KGlobalSettings::CompletionPopup
||
3077 m_combo
->completionMode() == KGlobalSettings::CompletionPopupAuto
)
3078 m_combo
->setCompletedItems( historyPopupCompletionItems( text
) );
3080 else if ( !completion
.isNull() )
3081 m_combo
->setCompletedText( completion
);
3085 // To be continued in slotMatch()...
3086 if( !m_pURLCompletion
->dir().isEmpty() )
3087 m_currentDir
= m_pURLCompletion
->dir();
3090 // kDebug(1202) << "Current dir:" << m_currentDir << "Current text:" << text;
3093 void KonqMainWindow::slotSubstringcompletion( const QString
& text
)
3095 QString currentURL
= m_currentView
->url().prettyUrl();
3096 bool filesFirst
= currentURL
.startsWith( '/' ) ||
3097 currentURL
.startsWith( "file:/" );
3099 if ( filesFirst
&& m_pURLCompletion
)
3100 items
= m_pURLCompletion
->substringCompletion( text
);
3102 items
+= s_pCompletion
->substringCompletion( text
);
3103 if ( !filesFirst
&& m_pURLCompletion
)
3104 items
+= m_pURLCompletion
->substringCompletion( text
);
3106 m_combo
->setCompletedItems( items
);
3109 void KonqMainWindow::slotRotation( KCompletionBase::KeyBindingType type
)
3111 // Tell slotMatch() to do nothing
3112 m_urlCompletionStarted
= false;
3114 bool prev
= (type
== KCompletionBase::PrevCompletionMatch
);
3115 if ( prev
|| type
== KCompletionBase::NextCompletionMatch
) {
3116 QString completion
= prev
? m_pURLCompletion
->previousMatch() :
3117 m_pURLCompletion
->nextMatch();
3119 if( completion
.isNull() ) { // try the history KCompletion object
3120 completion
= prev
? s_pCompletion
->previousMatch() :
3121 s_pCompletion
->nextMatch();
3123 if ( completion
.isEmpty() || completion
== m_combo
->currentText() )
3126 m_combo
->setCompletedText( completion
);
3130 // Handle match() from m_pURLCompletion
3131 void KonqMainWindow::slotMatch( const QString
&match
)
3133 if ( match
.isEmpty() ) // this case is handled directly
3136 // Check flag to avoid match() raised by rotation
3137 if ( m_urlCompletionStarted
) {
3138 m_urlCompletionStarted
= false;
3140 // some special handling necessary for CompletionPopup
3141 if ( m_combo
->completionMode() == KGlobalSettings::CompletionPopup
||
3142 m_combo
->completionMode() == KGlobalSettings::CompletionPopupAuto
) {
3143 QStringList items
= m_pURLCompletion
->allMatches();
3144 items
+= historyPopupCompletionItems( m_combo
->currentText() );
3145 // items.sort(); // should we?
3146 m_combo
->setCompletedItems( items
);
3148 else if ( !match
.isNull() )
3149 m_combo
->setCompletedText( match
);
3153 void KonqMainWindow::slotCtrlTabPressed()
3155 KonqView
* view
= m_pViewManager
->chooseNextView( m_currentView
);
3157 m_pViewManager
->setActivePart( view
->part() );
3160 void KonqMainWindow::slotClearHistory()
3162 KonqHistoryManager::kself()->emitClear();
3165 void KonqMainWindow::slotClearComboHistory()
3167 if (m_combo
&& m_combo
->count())
3168 m_combo
->clearHistory();
3171 bool KonqMainWindow::eventFilter(QObject
*obj
,QEvent
*ev
)
3173 if ( ( ev
->type()==QEvent::FocusIn
|| ev
->type()==QEvent::FocusOut
) &&
3174 m_combo
&& m_combo
->lineEdit() && m_combo
== obj
)
3176 //kDebug(1202) << obj << obj->metaObject()->className() << obj->name();
3178 QFocusEvent
* focusEv
= static_cast<QFocusEvent
*>(ev
);
3179 if (focusEv
->reason() == Qt::PopupFocusReason
)
3181 return KParts::MainWindow::eventFilter( obj
, ev
);
3184 KParts::BrowserExtension
* ext
= 0;
3185 if ( m_currentView
)
3186 ext
= m_currentView
->browserExtension();
3188 const QMetaObject
* slotMetaObject
= 0;
3190 slotMetaObject
= ext
->metaObject();
3192 if (ev
->type()==QEvent::FocusIn
)
3194 //kDebug(1202) << "ComboBox got the focus...";
3195 if (m_bLocationBarConnected
)
3197 //kDebug(1202) << "Was already connected...";
3198 return KParts::MainWindow::eventFilter( obj
, ev
);
3200 m_bLocationBarConnected
= true;
3202 // Workaround for Qt issue: usually, QLineEdit reacts on Ctrl-D,
3203 // but the duplicate_window action also has Ctrl-D as accel and
3204 // prevents the lineedit from getting this event. IMHO the accel
3205 // should be disabled in favor of the focus-widget.
3206 QAction
*duplicate
= actionCollection()->action("duplicate_window");
3207 if ( duplicate
->shortcuts().contains( QKeySequence(Qt::CTRL
+Qt::Key_D
) ))
3208 duplicate
->setEnabled( false );
3210 connect( m_paCut
, SIGNAL( triggered() ), m_combo
->lineEdit(), SLOT( cut() ) );
3211 connect( m_paCopy
, SIGNAL( triggered() ), m_combo
->lineEdit(), SLOT( copy() ) );
3212 connect( m_paPaste
, SIGNAL( triggered() ), m_combo
->lineEdit(), SLOT( paste() ) );
3213 connect( QApplication::clipboard(), SIGNAL(dataChanged()), this, SLOT(slotClipboardDataChanged()) );
3214 connect( m_combo
->lineEdit(), SIGNAL(textChanged(const QString
&)), this, SLOT(slotCheckComboSelection()) );
3215 connect( m_combo
->lineEdit(), SIGNAL(selectionChanged()), this, SLOT(slotCheckComboSelection()) );
3217 slotClipboardDataChanged();
3219 else if ( ev
->type()==QEvent::FocusOut
)
3221 //kDebug(1202) << "ComboBox lost focus...";
3222 if (!m_bLocationBarConnected
)
3224 //kDebug(1202) << "Was already disconnected...";
3225 return KParts::MainWindow::eventFilter( obj
, ev
);
3227 m_bLocationBarConnected
= false;
3229 // see above in FocusIn for explanation
3230 // we use new_window as reference, as it's always in the same state
3231 // as duplicate_window
3232 QAction
*duplicate
= actionCollection()->action("duplicate_window");
3233 if ( duplicate
->shortcuts().contains( QKeySequence(Qt::CTRL
+Qt::Key_D
) ) )
3234 duplicate
->setEnabled( actionCollection()->action("new_window")->isEnabled() );
3236 disconnect( m_paCut
, SIGNAL( triggered() ), m_combo
->lineEdit(), SLOT( cut() ) );
3237 disconnect( m_paCopy
, SIGNAL( triggered() ), m_combo
->lineEdit(), SLOT( copy() ) );
3238 disconnect( m_paPaste
, SIGNAL( triggered() ), m_combo
->lineEdit(), SLOT( paste() ) );
3239 disconnect( QApplication::clipboard(), SIGNAL(dataChanged()), this, SLOT(slotClipboardDataChanged()) );
3240 disconnect( m_combo
->lineEdit(), SIGNAL(textChanged(const QString
&)), this, SLOT(slotCheckComboSelection()) );
3241 disconnect( m_combo
->lineEdit(), SIGNAL(selectionChanged()), this, SLOT(slotCheckComboSelection()) );
3245 m_paCut
->setEnabled( ext
->isActionEnabled( "cut" ) );
3246 m_paCopy
->setEnabled( ext
->isActionEnabled( "copy" ) );
3247 m_paPaste
->setEnabled( ext
->isActionEnabled( "paste" ) );
3251 m_paCut
->setEnabled( false );
3252 m_paCopy
->setEnabled( false );
3253 m_paPaste
->setEnabled( false );
3257 return KParts::MainWindow::eventFilter( obj
, ev
);
3260 void KonqMainWindow::slotClipboardDataChanged()
3262 const QMimeData
*data
= QApplication::clipboard()->mimeData();
3263 m_paPaste
->setEnabled( data
->hasText() );
3264 slotCheckComboSelection();
3267 void KonqMainWindow::slotCheckComboSelection()
3269 bool hasSelection
= m_combo
->lineEdit()->hasSelectedText();
3270 //kDebug(1202) << "m_combo->lineEdit()->hasMarkedText():" << hasSelection;
3271 m_paCopy
->setEnabled( hasSelection
);
3272 m_paCut
->setEnabled( hasSelection
);
3275 void KonqMainWindow::slotClearLocationBar()
3278 m_combo
->clearTemporary();
3282 void KonqMainWindow::slotForceSaveMainWindowSettings()
3284 if ( autoSaveSettings() ) { // don't do it on e.g. JS window.open windows with no toolbars!
3285 saveAutoSaveSettings();
3289 void KonqMainWindow::slotShowMenuBar()
3291 if (menuBar()->isVisible())
3295 slotForceSaveMainWindowSettings();
3298 void KonqMainWindow::slotUpdateFullScreen( bool set
)
3300 KToggleFullScreenAction::setFullScreen( this, set
);
3303 // Create toolbar button for exiting from full-screen mode
3304 // ...but only if there isn't one already...
3306 bool haveFullScreenButton
= false;
3308 //Walk over the toolbars and check whether there is a show fullscreen button in any of them
3309 foreach (KToolBar
* bar
, findChildren
<KToolBar
*>())
3311 //Are we plugged here, in a visible toolbar?
3312 if (bar
->isVisible() &&
3313 action( "fullscreen" )->associatedWidgets().contains(bar
))
3315 haveFullScreenButton
= true;
3320 if (!haveFullScreenButton
)
3322 QList
<QAction
*> lst
;
3323 lst
.append( m_ptaFullScreen
);
3324 plugActionList( "fullscreen", lst
);
3328 m_prevMenuBarVisible
= menuBar()->isVisible();
3330 m_paShowMenuBar
->setChecked( false );
3332 // Qt bug, the flags are lost. They know about it.
3333 // happens only with the hackish non-_NET_WM_STATE_FULLSCREEN way
3334 setAttribute( Qt::WA_DeleteOnClose
);
3335 // Qt bug (see below)
3336 //### KDE4: still relevant?
3338 setAcceptDrops( false );
3340 setAcceptDrops( true );
3345 unplugActionList( "fullscreen" );
3347 if (m_prevMenuBarVisible
)
3350 m_paShowMenuBar
->setChecked( true );
3353 // Qt bug, the flags aren't restored. They know about it.
3354 //setWFlags( WType_TopLevel | WDestructiveClose );
3356 #warning "Dunno how to port this, is the workaround still needed?"
3359 setAttribute( Qt::WA_DeleteOnClose
);
3361 #if 0 //### KDE4: is this still relevant?
3363 setAcceptDrops( false );
3365 setAcceptDrops( true );
3370 void KonqMainWindow::setLocationBarURL( const KUrl
&url
)
3372 setLocationBarURL( url
.pathOrUrl() );
3375 void KonqMainWindow::setLocationBarURL( const QString
&url
)
3377 if (url
!= m_combo
->lineEdit()->text()) {
3378 //kDebug(1202) << "url=" << url;
3379 m_combo
->setURL( url
);
3384 void KonqMainWindow::setPageSecurity( PageSecurity pageSecurity
)
3386 m_combo
->setPageSecurity( pageSecurity
);
3389 void KonqMainWindow::showPageSecurity()
3391 if ( m_currentView
&& m_currentView
->part() ) {
3392 QAction
*act
= m_currentView
->part()->action( "security" );
3398 // Called via DBUS from KonquerorApplication
3399 void KonqMainWindow::comboAction( int action
, const QString
& url
, const QString
& senderId
)
3401 if (!s_lstViews
) // this happens in "konqueror --silent"
3404 KonqCombo
*combo
= 0;
3405 foreach ( KonqMainWindow
* window
, *s_lstViews
) {
3406 if ( window
&& window
->m_combo
) {
3407 combo
= window
->m_combo
;
3411 combo
->insertPermanent( url
);
3414 combo
->clearHistory();
3417 combo
->removeURL( url
);
3425 // only one instance should save...
3426 if ( combo
&& senderId
== QDBusConnection::sessionBus().baseService() )
3430 QString
KonqMainWindow::locationBarURL() const
3432 return m_combo
->currentText();
3435 void KonqMainWindow::focusLocationBar()
3437 if ( m_combo
->isVisible() || !isVisible() )
3438 m_combo
->setFocus();
3441 void KonqMainWindow::startAnimation()
3443 m_paAnimatedLogo
->start();
3444 m_paStop
->setEnabled( true );
3447 void KonqMainWindow::stopAnimation()
3449 m_paAnimatedLogo
->stop();
3450 m_paStop
->setEnabled( false );
3453 void KonqMainWindow::setUpEnabled( const KUrl
&url
)
3455 bool bHasUpURL
= ( (url
.hasPath() && url
.path() != "/" && url
.path()[0] == '/')
3456 || !url
.query().isEmpty() /*e.g. lists.kde.org*/ );
3458 bHasUpURL
= url
.hasSubUrl();
3460 m_paUp
->setEnabled(bHasUpURL
);
3464 int KonqMainWindow::maxThrobberHeight()
3466 // This comes from QMenuBar::sizeHint and QMenuBarPrivate::calcActionRects
3467 const QFontMetrics fm
= menuBar()->fontMetrics();
3468 QSize
sz(100, fm
.height());
3469 //let the style modify the above size..
3470 QStyleOptionMenuItem opt
;
3471 opt
.fontMetrics
= fm
;
3472 opt
.state
= QStyle::State_Enabled
;
3473 opt
.menuRect
= menuBar()->rect();
3475 sz
= menuBar()->style()->sizeFromContents(QStyle::CT_MenuBarItem
, &opt
, sz
, menuBar());
3476 //kDebug() << "maxThrobberHeight=" << sz.height();
3480 void KonqMainWindow::setAnimatedLogoSize()
3482 const int buttonHeight
= maxThrobberHeight();
3483 // This gives the best results: we force a bigger icon size onto the style, and it'll just have to eat up its margin.
3484 // So we don't need to ask sizeFromContents at all.
3485 int iconSize
= buttonHeight
;
3487 QStyleOptionToolButton opt
;
3488 opt
.initFrom(m_paAnimatedLogo
);
3489 const QSize finalSize
= style()->sizeFromContents(QStyle::CT_ToolButton
, &opt
, opt
.iconSize
, m_paAnimatedLogo
);
3490 //kDebug() << "throbberIconSize=" << buttonHeight << "-" << finalSize.height() - opt.iconSize.height();
3491 int iconSize
= buttonHeight
- (finalSize
.height() - opt
.iconSize
.height());
3494 m_paAnimatedLogo
->setFixedSize(QSize(buttonHeight
, buttonHeight
));
3496 //kDebug() << "buttonHeight=" << buttonHeight << "max iconSize=" << iconSize;
3497 if ( iconSize
< KIconLoader::SizeSmallMedium
)
3498 iconSize
= KIconLoader::SizeSmall
;
3499 else if ( iconSize
< KIconLoader::SizeMedium
)
3500 iconSize
= KIconLoader::SizeSmallMedium
;
3501 else if ( iconSize
< KIconLoader::SizeLarge
)
3502 iconSize
= KIconLoader::SizeMedium
;
3503 else if ( iconSize
< KIconLoader::SizeHuge
)
3504 iconSize
= KIconLoader::SizeLarge
;
3505 //kDebug() << "final iconSize=" << iconSize;
3506 m_paAnimatedLogo
->setIconSize(QSize(iconSize
, iconSize
));
3509 void KonqMainWindow::initActions()
3511 // Note about this method : don't call setEnabled() on any of the actions.
3512 // They are all disabled then re-enabled with enableAllActions
3513 // If any one needs to be initially disabled, put that code in enableAllActions
3515 // For the popup menu only.
3516 m_pMenuNew
= new KNewMenu(actionCollection(), this, "new_menu");
3520 KAction
* action
= actionCollection()->addAction("new_window");
3521 action
->setIcon(KIcon("window-new"));
3522 action
->setText(i18n( "New &Window" ));
3523 connect(action
, SIGNAL(triggered()), SLOT( slotNewWindow() ));
3524 action
->setShortcuts(KStandardShortcut::shortcut(KStandardShortcut::New
));
3525 action
= actionCollection()->addAction("duplicate_window");
3526 action
->setIcon(KIcon("window-duplicate"));
3527 action
->setText(i18n( "&Duplicate Window" ));
3528 connect(action
, SIGNAL(triggered()), SLOT( slotDuplicateWindow() ));
3529 action
->setShortcut(Qt::CTRL
+Qt::Key_D
);
3530 action
= actionCollection()->addAction("sendURL");
3531 action
->setIcon(KIcon("mail-message-new"));
3532 action
->setText(i18n( "Send &Link Address..." ));
3533 connect(action
, SIGNAL(triggered()), SLOT( slotSendURL() ));
3534 action
= actionCollection()->addAction("sendPage");
3535 action
->setIcon(KIcon("mail-message-new"));
3536 action
->setText(i18n( "S&end File..." ));
3537 connect(action
, SIGNAL(triggered()), SLOT( slotSendFile() ));
3538 action
= actionCollection()->addAction("open_location");
3539 action
->setIcon(KIcon("document-open-remote"));
3540 action
->setText(i18n( "&Open Location" ));
3541 action
->setShortcut(Qt::ALT
+Qt::Key_O
);
3542 connect(action
, SIGNAL(triggered()), SLOT( slotOpenLocation() ));
3544 action
= actionCollection()->addAction("open_file");
3545 action
->setIcon(KIcon("document-open"));
3546 action
->setText(i18n( "&Open File..." ));
3547 connect(action
, SIGNAL(triggered()), SLOT( slotOpenFile() ));
3548 action
->setShortcuts(KStandardShortcut::shortcut(KStandardShortcut::Open
));
3551 m_paFindFiles
= new KToggleAction(KIcon("edit-find"), i18n( "&Find File..." ), this);
3552 actionCollection()->addAction( "findfile", m_paFindFiles
);
3553 connect(m_paFindFiles
, SIGNAL(triggered() ), SLOT( slotToolFind() ));
3554 m_paFindFiles
->setShortcuts(KStandardShortcut::shortcut(KStandardShortcut::Find
));
3557 m_paPrint
= actionCollection()->addAction( KStandardAction::Print
, "print", 0, 0 );
3558 actionCollection()->addAction( KStandardAction::Quit
, "quit", this, SLOT( close() ) );
3560 m_ptaUseHTML
= new KToggleAction( i18n( "&Use index.html" ), this );
3561 actionCollection()->addAction( "usehtml", m_ptaUseHTML
);
3562 connect(m_ptaUseHTML
, SIGNAL(triggered() ), SLOT( slotShowHTML() ));
3563 m_paLockView
= new KToggleAction( i18n( "Lock to Current Location"), this );
3564 actionCollection()->addAction( "lock", m_paLockView
);
3565 connect(m_paLockView
, SIGNAL(triggered() ), SLOT( slotLockView() ));
3566 m_paLinkView
= new KToggleAction( i18nc( "This option links konqueror views", "Lin&k View"), this );
3567 actionCollection()->addAction( "link", m_paLinkView
);
3568 connect(m_paLinkView
, SIGNAL(triggered() ), SLOT( slotLinkView() ));
3571 m_paUp
= new KToolBarPopupAction( KIcon("go-up"), i18n( "&Up" ), this );
3572 actionCollection()->addAction( "go_up", m_paUp
);
3573 m_paUp
->setShortcuts( KStandardShortcut::shortcut(KStandardShortcut::Up
) );
3574 connect( m_paUp
, SIGNAL( triggered( Qt::MouseButtons
, Qt::KeyboardModifiers
) ), this,
3575 SLOT( slotUp(Qt::MouseButtons
, Qt::KeyboardModifiers
) ) );
3576 connect( m_paUp
->menu(), SIGNAL( aboutToShow() ), this, SLOT( slotUpAboutToShow() ) );
3577 connect( m_paUp
->menu(), SIGNAL(triggered(QAction
*)), this, SLOT(slotUpActivated(QAction
*)) );
3579 QPair
< KGuiItem
, KGuiItem
> backForward
= KStandardGuiItem::backAndForward();
3582 // Trash bin of closed tabs
3583 m_paClosedItems
= new KToolBarPopupAction( KIcon("edit-undo-closed-tabs"), i18n( "Closed Items" ), this );
3584 actionCollection()->addAction( "closeditems", m_paClosedItems
);
3585 m_closedItemsGroup
= new QActionGroup(m_paClosedItems
->menu());
3587 // set the closed tabs list shown
3588 connect( m_paClosedItems
, SIGNAL(triggered()), m_pUndoManager
, SLOT(undoLastClosedItem()) );
3589 connect( m_paClosedItems
->menu(), SIGNAL(aboutToShow()), this, SLOT(slotClosedItemsListAboutToShow()) );
3590 connect( m_closedItemsGroup
, SIGNAL(triggered(QAction
*)), m_pUndoManager
, SLOT(slotClosedItemsActivated(QAction
*)) );
3591 connect( m_pViewManager
, SIGNAL(aboutToRemoveTab(KonqFrameBase
*)), this, SLOT(slotAddClosedUrl(KonqFrameBase
*)) );
3592 connect( m_pUndoManager
, SIGNAL(openClosedTab(const KonqClosedTabItem
&)), m_pViewManager
, SLOT(openClosedTab(const KonqClosedTabItem
&)) );
3593 connect( m_pUndoManager
, SIGNAL(openClosedWindow(const KonqClosedWindowItem
&)), m_pViewManager
, SLOT(openClosedWindow(const KonqClosedWindowItem
&)) );
3594 connect( m_pUndoManager
, SIGNAL(closedItemsListChanged()), this, SLOT(updateClosedItemsAction()));
3597 m_paSessions
= new KActionMenu( i18n( "Sessions" ), this );
3598 actionCollection()->addAction( "sessions", m_paSessions
);
3599 m_sessionsGroup
= new QActionGroup(m_paSessions
->menu());
3600 connect( m_paSessions
->menu(), SIGNAL(aboutToShow()), this, SLOT(slotSessionsListAboutToShow()) );
3601 connect( m_sessionsGroup
, SIGNAL(triggered(QAction
*)), this, SLOT(slotSessionActivated(QAction
*)) );
3603 m_paBack
= new KToolBarPopupAction( KIcon(backForward
.first
.iconName()), backForward
.first
.text(), this );
3604 actionCollection()->addAction( "go_back", m_paBack
);
3605 m_paBack
->setShortcuts( KStandardShortcut::shortcut(KStandardShortcut::Back
) );
3606 connect( m_paBack
, SIGNAL( triggered( Qt::MouseButtons
, Qt::KeyboardModifiers
) ), this,
3607 SLOT( slotBack(Qt::MouseButtons
, Qt::KeyboardModifiers
) ) );
3608 connect( m_paBack
->menu(), SIGNAL( aboutToShow() ), this, SLOT( slotBackAboutToShow() ) );
3609 connect( m_paBack
->menu(), SIGNAL(triggered(QAction
*)), this, SLOT(slotBackActivated(QAction
*)) );
3611 m_paForward
= new KToolBarPopupAction( KIcon(backForward
.second
.iconName()), backForward
.second
.text(), this );
3612 actionCollection()->addAction( "go_forward", m_paForward
);
3613 m_paForward
->setShortcuts( KStandardShortcut::shortcut(KStandardShortcut::Forward
) );
3614 connect( m_paForward
, SIGNAL( triggered( Qt::MouseButtons
, Qt::KeyboardModifiers
) ), this,
3615 SLOT( slotForward(Qt::MouseButtons
, Qt::KeyboardModifiers
) ) );
3616 connect( m_paForward
->menu(), SIGNAL( aboutToShow() ), this, SLOT( slotForwardAboutToShow() ) );
3617 connect( m_paForward
->menu(), SIGNAL(triggered(QAction
*)), this, SLOT(slotForwardActivated(QAction
*)) );
3619 m_paHome
= actionCollection()->addAction( KStandardAction::Home
);
3620 m_paHome
->setEnabled( true );
3621 connect( m_paHome
, SIGNAL( triggered( Qt::MouseButtons
, Qt::KeyboardModifiers
) ), this,
3622 SLOT( slotHome(Qt::MouseButtons
, Qt::KeyboardModifiers
) ) );
3624 KonqMostOftenURLSAction
*mostOften
= new KonqMostOftenURLSAction( i18nc("@action:inmenu Go", "Most Often Visited"), this );
3625 actionCollection()->addAction( "go_most_often", mostOften
);
3626 connect(mostOften
, SIGNAL(activated(KUrl
)), SLOT(slotOpenURL(KUrl
)));
3628 action
= new KonqHistoryAction(i18nc("@action:inmenu Go", "Recently Visited"), this);
3629 actionCollection()->addAction("history", action
);
3630 connect(action
, SIGNAL(activated(KUrl
)), SLOT(slotOpenURL(KUrl
)));
3632 action
= actionCollection()->addAction("go_history");
3633 action
->setIcon(KIcon("view-history"));
3634 action
->setText(i18nc("@action:inmenu Go", "Show History in Sidebar"));
3635 connect(action
, SIGNAL(triggered()), SLOT(slotGoHistory()));
3639 m_paSaveViewProfile
= actionCollection()->addAction( "saveviewprofile" );
3640 m_paSaveViewProfile
->setText( i18n( "&Save View Profile..." ) );
3641 connect(m_paSaveViewProfile
, SIGNAL(triggered() ), SLOT( slotSaveViewProfile() ));
3643 // This list is just for the call to authorizeControlModule; see slotConfigure for the real code
3644 QStringList configureModules
;
3645 configureModules
<< "khtml_general" << "bookmarks" <<
3646 "filebehavior" << "filetypes" << "kcmtrash" <<
3647 "khtml_appearance" << "khtml_behavior" << "khtml_java_js" <<
3648 "khtml_filter" << "ebrowsing" <<
3649 "kcmhistory" << "cookies" <<
3650 "cache" << "proxy" <<
3651 "crypto" << "useragent" <<
3652 "khtml_plugins" << "kcmkonqyperformance";
3654 if (!KAuthorized::authorizeControlModules(configureModules
).isEmpty())
3655 actionCollection()->addAction( KStandardAction::Preferences
, this, SLOT(slotConfigure()) );
3657 actionCollection()->addAction( KStandardAction::KeyBindings
, guiFactory(), SLOT( configureShortcuts() ) );
3658 actionCollection()->addAction( KStandardAction::ConfigureToolbars
, this, SLOT( slotConfigureToolbars() ) );
3660 m_paConfigureExtensions
= actionCollection()->addAction("options_configure_extensions");
3661 m_paConfigureExtensions
->setText( i18n("Configure Extensions...") );
3662 connect(m_paConfigureExtensions
, SIGNAL(triggered() ), SLOT( slotConfigureExtensions()));
3663 m_paConfigureSpellChecking
= actionCollection()->addAction("configurespellcheck");
3664 m_paConfigureSpellChecking
->setIcon(KIcon("tools-check-spelling"));
3665 m_paConfigureSpellChecking
->setText(i18n("Configure Spell Checking..."));
3666 connect(m_paConfigureSpellChecking
, SIGNAL(triggered()), SLOT( slotConfigureSpellChecking()));
3669 m_paSplitViewHor
= actionCollection()->addAction("splitviewh");
3670 m_paSplitViewHor
->setIcon( KIcon("view-split-left-right") );
3671 m_paSplitViewHor
->setText( i18n( "Split View &Left/Right" ) );
3672 connect(m_paSplitViewHor
, SIGNAL(triggered()), SLOT( slotSplitViewHorizontal() ));
3673 m_paSplitViewHor
->setShortcut(Qt::CTRL
+Qt::SHIFT
+Qt::Key_L
);
3674 m_paSplitViewVer
= actionCollection()->addAction("splitviewv");
3675 m_paSplitViewVer
->setIcon( KIcon("view-split-top-bottom") );
3676 m_paSplitViewVer
->setText( i18n( "Split View &Top/Bottom" ) );
3677 connect(m_paSplitViewVer
, SIGNAL(triggered()), SLOT( slotSplitViewVertical() ));
3678 m_paSplitViewVer
->setShortcut(Qt::CTRL
+Qt::SHIFT
+Qt::Key_T
);
3679 m_paAddTab
= actionCollection()->addAction("newtab");
3680 m_paAddTab
->setIcon( KIcon("tab-new") );
3681 m_paAddTab
->setText( i18n( "&New Tab" ) );
3682 connect(m_paAddTab
, SIGNAL(triggered()), SLOT( slotAddTab() ));
3683 m_paAddTab
->setShortcuts(KShortcut(Qt::CTRL
+Qt::SHIFT
+Qt::Key_N
, Qt::CTRL
+Qt::Key_T
));
3685 m_paDuplicateTab
= actionCollection()->addAction("duplicatecurrenttab");
3686 m_paDuplicateTab
->setIcon( KIcon("tab-duplicate") );
3687 m_paDuplicateTab
->setText( i18n( "&Duplicate Current Tab" ) );
3688 connect(m_paDuplicateTab
, SIGNAL(triggered()), SLOT( slotDuplicateTab() ));
3689 m_paDuplicateTab
->setShortcut(Qt::CTRL
+Qt::SHIFT
+Qt::Key_D
);
3690 m_paBreakOffTab
= actionCollection()->addAction("breakoffcurrenttab");
3691 m_paBreakOffTab
->setIcon( KIcon("tab-detach") );
3692 m_paBreakOffTab
->setText( i18n( "Detach Current Tab" ) );
3693 connect(m_paBreakOffTab
, SIGNAL(triggered()), SLOT( slotBreakOffTab() ));
3694 m_paBreakOffTab
->setShortcut(Qt::CTRL
+Qt::SHIFT
+Qt::Key_B
);
3695 m_paRemoveView
= actionCollection()->addAction("removeview");
3696 m_paRemoveView
->setIcon( KIcon("view-close") );
3697 m_paRemoveView
->setText( i18n( "&Close Active View" ) );
3698 connect(m_paRemoveView
, SIGNAL(triggered()), SLOT( slotRemoveView() ));
3699 m_paRemoveView
->setShortcut(Qt::CTRL
+Qt::SHIFT
+Qt::Key_R
);
3700 m_paRemoveTab
= actionCollection()->addAction("removecurrenttab");
3701 m_paRemoveTab
->setIcon( KIcon("tab-close") );
3702 m_paRemoveTab
->setText( i18n( "Close Current Tab" ) );
3703 connect(m_paRemoveTab
, SIGNAL(triggered()), SLOT( slotRemoveTab() ));
3704 m_paRemoveTab
->setShortcut(Qt::CTRL
+Qt::Key_W
);
3705 m_paRemoveTab
->setAutoRepeat(false);
3706 m_paRemoveOtherTabs
= actionCollection()->addAction("removeothertabs");
3707 m_paRemoveOtherTabs
->setIcon( KIcon("tab-close-other") );
3708 m_paRemoveOtherTabs
->setText( i18n( "Close &Other Tabs" ) );
3709 connect(m_paRemoveOtherTabs
, SIGNAL(triggered()), SLOT( slotRemoveOtherTabs() ));
3711 m_paActivateNextTab
= actionCollection()->addAction("activatenexttab");
3712 m_paActivateNextTab
->setText( i18n( "Activate Next Tab" ) );
3713 connect(m_paActivateNextTab
, SIGNAL(triggered()), SLOT( slotActivateNextTab() ));
3714 m_paActivateNextTab
->setShortcuts(QApplication::isRightToLeft() ? KStandardShortcut::tabPrev() : KStandardShortcut::tabNext());
3715 m_paActivatePrevTab
= actionCollection()->addAction("activateprevtab");
3716 m_paActivatePrevTab
->setText( i18n( "Activate Previous Tab" ) );
3717 connect(m_paActivatePrevTab
, SIGNAL(triggered()), SLOT( slotActivatePrevTab() ));
3718 m_paActivatePrevTab
->setShortcuts(QApplication::isRightToLeft() ? KStandardShortcut::tabNext() : KStandardShortcut::tabPrev());
3721 for (int i
=1;i
<13;i
++) {
3722 actionname
.sprintf("activate_tab_%02d", i
);
3723 QAction
*action
= actionCollection()->addAction( actionname
);
3724 action
->setText( i18n("Activate Tab %1", i
) );
3725 connect(action
, SIGNAL(triggered()), SLOT(slotActivateTab()));
3728 m_paMoveTabLeft
= actionCollection()->addAction("tab_move_left");
3729 m_paMoveTabLeft
->setText( i18n("Move Tab Left") );
3730 m_paMoveTabLeft
->setIcon( KIcon("tab-move-left") );
3731 connect(m_paMoveTabLeft
, SIGNAL(triggered()), SLOT( slotMoveTabLeft()));
3732 m_paMoveTabLeft
->setShortcut(Qt::CTRL
+Qt::SHIFT
+Qt::Key_Left
);
3733 m_paMoveTabRight
= actionCollection()->addAction("tab_move_right");
3734 m_paMoveTabRight
->setText( i18n("Move Tab Right") );
3735 m_paMoveTabRight
->setIcon( KIcon("tab-move-right") );
3736 connect(m_paMoveTabRight
, SIGNAL(triggered()), SLOT( slotMoveTabRight()));
3737 m_paMoveTabRight
->setShortcut(Qt::CTRL
+Qt::SHIFT
+Qt::Key_Right
);
3740 action
= actionCollection()->addAction("dumpdebuginfo");
3741 action
->setIcon( KIcon("view-dump-debug-info") );
3742 action
->setText( i18n( "Dump Debug Info" ) );
3743 connect(action
, SIGNAL(triggered()), SLOT( slotDumpDebugInfo() ));
3746 m_paSaveRemoveViewProfile
= actionCollection()->addAction("saveremoveviewprofile" );
3747 m_paSaveRemoveViewProfile
->setText( i18n( "C&onfigure View Profiles..." ) );
3748 connect(m_paSaveRemoveViewProfile
, SIGNAL(triggered() ), m_pViewManager
, SLOT( slotProfileDlg() ));
3749 m_pamLoadViewProfile
= new KActionMenu( i18n( "Load &View Profile" ), this );
3750 actionCollection()->addAction( "loadviewprofile", m_pamLoadViewProfile
);
3752 m_pViewManager
->setProfiles( m_pamLoadViewProfile
);
3754 m_ptaFullScreen
= KStandardAction::fullScreen( 0, 0, this, this );
3755 actionCollection()->addAction( m_ptaFullScreen
->objectName(), m_ptaFullScreen
);
3756 KShortcut fullScreenShortcut
= m_ptaFullScreen
->shortcut();
3757 fullScreenShortcut
.setAlternate( Qt::Key_F11
);
3758 m_ptaFullScreen
->setShortcut( fullScreenShortcut
);
3759 connect( m_ptaFullScreen
, SIGNAL( toggled( bool )), this, SLOT( slotUpdateFullScreen( bool )));
3761 KShortcut reloadShortcut
= KStandardShortcut::shortcut(KStandardShortcut::Reload
);
3762 reloadShortcut
.setAlternate(Qt::CTRL
+ Qt::Key_R
);
3763 m_paReload
= actionCollection()->addAction("reload");
3764 m_paReload
->setIcon( KIcon("view-refresh") );
3765 m_paReload
->setText( i18n( "&Reload" ) );
3766 connect(m_paReload
, SIGNAL(triggered()), SLOT( slotReload() ));
3767 m_paReload
->setShortcuts(reloadShortcut
);
3768 m_paReloadAllTabs
= actionCollection()->addAction("reload_all_tabs");
3769 m_paReloadAllTabs
->setIcon( KIcon("view-refresh-all") );
3770 m_paReloadAllTabs
->setText( i18n( "&Reload All Tabs" ) );
3771 connect(m_paReloadAllTabs
, SIGNAL(triggered()), SLOT( slotReloadAllTabs() ));
3772 m_paReloadAllTabs
->setShortcut(Qt::SHIFT
+Qt::Key_F5
);
3773 // "Forced"/ "Hard" reload action - re-downloads all e.g. images even if a cached
3774 // version already exists.
3775 m_paForceReload
= actionCollection()->addAction("hard_reload");
3776 // TODO - request new icon? (view-refresh will do for the time being)
3777 m_paForceReload
->setIcon( KIcon("view-refresh") );
3778 m_paForceReload
->setText( i18n( "&Force Reload" ) );
3779 connect(m_paForceReload
, SIGNAL(triggered()), SLOT( slotForceReload()));
3780 m_paForceReload
->setShortcuts(KShortcut(Qt::CTRL
+Qt::Key_F5
, Qt::CTRL
+Qt::SHIFT
+Qt::Key_R
));
3782 m_paUndo
= KStandardAction::undo( m_pUndoManager
, SLOT( undo() ), this );
3783 actionCollection()->addAction( "undo", m_paUndo
);
3784 connect( m_pUndoManager
, SIGNAL( undoTextChanged(QString
) ),
3785 this, SLOT( slotUndoTextChanged(QString
) ) );
3787 // Those are connected to the browserextension directly
3788 m_paCut
= KStandardAction::cut( 0, 0, this );
3789 actionCollection()->addAction( "cut", m_paCut
);
3790 KShortcut
cutShortCut( m_paCut
->shortcut() );
3791 cutShortCut
.remove( Qt::SHIFT
+ Qt::Key_Delete
); // used for deleting files
3792 m_paCut
->setShortcuts( cutShortCut
);
3794 m_paCopy
= KStandardAction::copy( 0, 0, this );
3795 actionCollection()->addAction( "copy", m_paCopy
);
3796 m_paPaste
= KStandardAction::paste( 0, 0, this );
3797 actionCollection()->addAction( "paste", m_paPaste
);
3798 m_paStop
= actionCollection()->addAction("stop");
3799 m_paStop
->setIcon( KIcon("process-stop") );
3800 m_paStop
->setText( i18n( "&Stop" ) );
3801 connect(m_paStop
, SIGNAL(triggered()), SLOT( slotStop() ));
3802 m_paStop
->setShortcut(Qt::Key_Escape
);
3804 m_paAnimatedLogo
= new KAnimatedButton( this );
3805 m_paAnimatedLogo
->setAutoRaise(true);
3806 m_paAnimatedLogo
->setFocusPolicy(Qt::NoFocus
);
3807 m_paAnimatedLogo
->setToolButtonStyle(Qt::ToolButtonIconOnly
);
3808 setAnimatedLogoSize();
3809 m_paAnimatedLogo
->setIcons("process-working-kde");
3810 menuBar()->setCornerWidget(m_paAnimatedLogo
);
3813 m_locationLabel
= new KonqDraggableLabel( this, i18n("L&ocation: ") );
3814 KAction
*locationAction
= new KAction( this );
3815 actionCollection()->addAction( "location_label", locationAction
);
3816 locationAction
->setText( i18n("L&ocation: ") );
3817 connect(locationAction
, SIGNAL(triggered()), SLOT( slotLocationLabelActivated() ));
3818 locationAction
->setDefaultWidget(m_locationLabel
);
3819 m_locationLabel
->setBuddy( m_combo
);
3821 KAction
*comboAction
= new KAction( this );
3822 actionCollection()->addAction( "toolbar_url_combo", comboAction
);
3823 comboAction
->setText( i18n( "Location Bar" ) );
3824 comboAction
->setShortcut(Qt::Key_F6
);
3825 connect(comboAction
, SIGNAL(triggered()), SLOT( slotLocationLabelActivated() ));
3826 comboAction
->setDefaultWidget(m_combo
);
3827 comboAction
->setShortcutConfigurable( false );
3829 m_combo
->setWhatsThis( i18n( "<html>Location Bar<br /><br />Enter a web address or search term.</html>" ) );
3831 KAction
*clearLocation
= actionCollection()->addAction("clear_location");
3832 clearLocation
->setIcon( KIcon(QApplication::isRightToLeft() ? "edit-clear-locationbar-rtl" : "edit-clear-locationbar-ltr") );
3833 clearLocation
->setText( i18n( "Clear Location Bar" ) );
3834 clearLocation
->setShortcut(Qt::CTRL
+Qt::Key_L
);
3835 connect( clearLocation
, SIGNAL( triggered() ),
3836 SLOT( slotClearLocationBar() ) );
3837 clearLocation
->setWhatsThis( i18n( "<html>Clear Location bar<br /><br />"
3838 "Clears the contents of the location bar.</html>" ) );
3841 m_pamBookmarks
= new KBookmarkActionMenu(s_bookmarkManager
->root(),
3842 i18n( "&Bookmarks" ), this);
3843 actionCollection()->addAction( "bookmarks", m_pamBookmarks
);
3845 // The actual menu needs a different action collection, so that the bookmarks
3846 // don't appear in kedittoolbar
3847 m_bookmarksActionCollection
= new KActionCollection( static_cast<QWidget
*>( this ) );
3849 m_pBookmarkMenu
= new KonqBookmarkMenu( s_bookmarkManager
, m_pBookmarksOwner
, m_pamBookmarks
, m_bookmarksActionCollection
);
3851 QAction
*addBookmark
= actionCollection()->action("add_bookmark");
3853 addBookmark
->setText(i18n("Bookmark This Location"));
3855 m_paShowMenuBar
= KStandardAction::showMenubar( this, SLOT( slotShowMenuBar() ), this );
3856 actionCollection()->addAction( KStandardAction::name(KStandardAction::ShowMenubar
), m_paShowMenuBar
);
3858 action
= actionCollection()->addAction( "konqintro" );
3859 action
->setText( i18n( "Kon&queror Introduction" ) );
3860 connect(action
, SIGNAL(triggered() ), SLOT( slotIntro() ));
3862 QAction
*goUrl
= actionCollection()->addAction("go_url");
3863 goUrl
->setIcon( KIcon("go-jump-locationbar") );
3864 goUrl
->setText( i18n( "Go" ) );
3865 connect(goUrl
, SIGNAL(triggered()), SLOT( goURL() ));
3866 goUrl
->setWhatsThis( i18n( "<html>Go<br /><br />"
3867 "Goes to the page that has been entered into the location bar.</html>" ) );
3869 enableAllActions( false );
3872 m_paUp
->setWhatsThis( i18n( "<html>Enter the parent folder<br /><br />"
3873 "For instance, if the current location is file:/home/%1 clicking this "
3874 "button will take you to file:/home.</html>" , KUser().loginName() ) );
3875 m_paUp
->setToolTip( i18n( "Enter the parent folder" ) );
3877 m_paBack
->setWhatsThis( i18n( "Move backwards one step in the browsing history" ) );
3878 m_paBack
->setToolTip( i18n( "Move backwards one step in the browsing history" ) );
3880 m_paForward
->setWhatsThis( i18n( "Move forward one step in the browsing history" ) );
3881 m_paForward
->setToolTip( i18n( "Move forward one step in the browsing history" ) );
3884 m_paClosedItems
->setWhatsThis( i18n( "Move backwards one step in the closed tabs history" ) );
3885 m_paClosedItems
->setToolTip( i18n( "Move backwards one step in the closed tabs history" ) );
3888 m_paReload
->setWhatsThis( i18n( "<html>Reload the currently displayed document<br /><br />"
3889 "This may, for example, be needed to refresh web pages that have been "
3890 "modified since they were loaded, in order to make the changes visible.</html>" ) );
3891 m_paReload
->setToolTip( i18n( "Reload the currently displayed document" ) );
3893 m_paReloadAllTabs
->setWhatsThis( i18n( "<html>Reload all currently displayed documents in tabs<br /><br />"
3894 "This may, for example, be needed to refresh web pages that have been "
3895 "modified since they were loaded, in order to make the changes visible.</html>" ) );
3896 m_paReloadAllTabs
->setToolTip( i18n( "Reload all currently displayed document in tabs" ) );
3898 m_paStop
->setWhatsThis( i18n( "<html>Stop loading the document<br /><br />"
3899 "All network transfers will be stopped and Konqueror will display the content "
3900 "that has been received so far.</html>" ) );
3902 m_paForceReload
->setWhatsThis( i18n( "<html>Reload the currently displayed document<br /><br />"
3903 "This may, for example, be needed to refresh web pages that have been "
3904 "modified since they were loaded, in order to make the changes visible. Any images on the page are downloaded again, even if cached copies exist.</html>" ) );
3906 m_paForceReload
->setToolTip( i18n( "Force a reload of the currently displayed document and any contained images" ) );
3909 m_paStop
->setToolTip( i18n( "Stop loading the document" ) );
3911 m_paCut
->setWhatsThis( i18n( "<html>Cut the currently selected text or item(s) and move it "
3912 "to the system clipboard<br /><br />"
3913 "This makes it available to the <b>Paste</b> command in Konqueror "
3914 "and other KDE applications.</html>" ) );
3915 m_paCut
->setToolTip( i18n( "Move the selected text or item(s) to the clipboard" ) );
3917 m_paCopy
->setWhatsThis( i18n( "<html>Copy the currently selected text or item(s) to the "
3918 "system clipboard<br /><br />"
3919 "This makes it available to the <b>Paste</b> command in Konqueror "
3920 "and other KDE applications.</html>" ) );
3921 m_paCopy
->setToolTip( i18n( "Copy the selected text or item(s) to the clipboard" ) );
3923 m_paPaste
->setWhatsThis( i18n( "<html>Paste the previously cut or copied clipboard "
3924 "contents<br /><br />"
3925 "This also works for text copied or cut from other KDE applications.</html>" ) );
3926 m_paPaste
->setToolTip( i18n( "Paste the clipboard contents" ) );
3928 m_paPrint
->setWhatsThis( i18n( "<html>Print the currently displayed document<br /><br />"
3929 "You will be presented with a dialog where you can set various "
3930 "options, such as the number of copies to print and which printer "
3931 "to use.<br /><br />"
3932 "This dialog also provides access to special KDE printing "
3933 "services such as creating a PDF file from the current document.</html>" ) );
3934 m_paPrint
->setToolTip( i18n( "Print the current document" ) );
3938 // Please proof-read those (David)
3940 m_ptaUseHTML
->setToolTip( i18n("If present, open index.html when entering a folder.") );
3941 m_paLockView
->setToolTip( i18n("A locked view cannot change folders. Use in combination with 'link view' to explore many files from one folder") );
3942 m_paLinkView
->setToolTip( i18n("Sets the view as 'linked'. A linked view follows folder changes made in other linked views.") );
3945 void KonqExtendedBookmarkOwner::openBookmark(const KBookmark
& bm
, Qt::MouseButtons mb
, Qt::KeyboardModifiers km
)
3947 kDebug(1202) << bm
.url() << km
<< mb
;
3949 const QString url
= bm
.url().url();
3951 KonqOpenURLRequest req
;
3952 req
.browserArgs
.setNewTab(true);
3953 req
.newTabInFront
= KonqSettings::newTabsInFront();
3954 req
.forceAutoEmbed
= true;
3956 if (km
& Qt::ShiftModifier
) {
3957 req
.newTabInFront
= !req
.newTabInFront
;
3960 if( km
& Qt::ControlModifier
) { // Ctrl Left/MMB
3961 m_pKonqMainWindow
->openFilteredUrl( url
, req
);
3962 } else if( mb
& Qt::MidButton
) {
3963 if(KonqSettings::mmbOpensTab()) {
3964 m_pKonqMainWindow
->openFilteredUrl( url
, req
);
3966 KUrl finalURL
= KonqMisc::konqFilteredURL( m_pKonqMainWindow
, url
);
3967 KonqMisc::createNewWindow( finalURL
);
3971 m_pKonqMainWindow
->openFilteredUrl( url
, false );
3975 void KonqMainWindow::slotMoveTabLeft()
3977 if ( QApplication::isRightToLeft() )
3978 m_pViewManager
->moveTabForward();
3980 m_pViewManager
->moveTabBackward();
3982 updateViewActions();
3985 void KonqMainWindow::slotMoveTabRight()
3987 if ( QApplication::isRightToLeft() )
3988 m_pViewManager
->moveTabBackward();
3990 m_pViewManager
->moveTabForward();
3992 updateViewActions();
3995 void KonqMainWindow::updateHistoryActions()
3999 m_paBack
->setEnabled( m_currentView
->canGoBack() );
4000 m_paForward
->setEnabled( m_currentView
->canGoForward() );
4004 void KonqMainWindow::updateToolBarActions( bool pendingAction
/*=false*/)
4006 // Enables/disables actions that depend on the current view & url (mostly toolbar)
4007 // Up, back, forward, the edit extension, stop button, wheel
4008 setUpEnabled( m_currentView
->url() );
4009 m_paBack
->setEnabled( m_currentView
->canGoBack() );
4010 m_paForward
->setEnabled( m_currentView
->canGoForward() );
4012 if ( m_currentView
->isLoading() )
4014 startAnimation(); // takes care of m_paStop
4018 m_paAnimatedLogo
->stop();
4019 m_paStop
->setEnabled( pendingAction
); //enable/disable based on any pending actions...
4022 if ( m_currentView
&& m_currentView
->url().isLocalFile() &&
4023 !m_currentView
->isLockedViewMode() ) {
4024 if (m_currentView
->showsDirectory())
4025 m_ptaUseHTML
->setEnabled( true );
4026 else if ( m_currentView
->serviceTypes().contains("text/html") ) {
4027 // Currently viewing an index.html file via this feature (i.e. url points to a dir)
4028 QString locPath
= KUrl( m_currentView
->locationBarURL() ).path();
4029 m_ptaUseHTML
->setEnabled( QFileInfo( locPath
).isDir() );
4031 m_ptaUseHTML
->setEnabled( false );
4035 m_ptaUseHTML
->setEnabled( false );
4039 void KonqMainWindow::updateViewActions()
4041 // Update actions that depend on the current view and its mode, or on the number of views etc.
4043 // Don't do things in this method that depend on m_currentView->url().
4044 // When going 'back' in history this will be called before opening the url.
4045 // Use updateToolBarActions instead.
4047 bool enable
= false;
4049 if ( m_currentView
&& m_currentView
->part() )
4051 // Avoid qWarning from QObject::property if it doesn't exist
4052 if ( m_currentView
->part()->metaObject()->indexOfProperty( "supportsUndo" ) != -1 )
4054 QVariant prop
= m_currentView
->part()->property( "supportsUndo" );
4055 if ( prop
.isValid() && prop
.toBool() )
4060 m_pUndoManager
->updateSupportsFileUndo(enable
);
4062 // slotUndoAvailable( m_pUndoManager->undoAvailable() );
4064 m_paLockView
->setEnabled( true );
4065 m_paLockView
->setChecked( m_currentView
&& m_currentView
->isLockedLocation() );
4067 // Can remove view if we'll still have a main view after that
4068 m_paRemoveView
->setEnabled( mainViewsCount() > 1 ||
4069 ( m_currentView
&& m_currentView
->isToggleView() ) );
4071 if ( !currentView() || !currentView()->frame())
4073 m_paAddTab
->setEnabled( false );
4074 m_paDuplicateTab
->setEnabled( false );
4075 m_paRemoveTab
->setEnabled( false );
4076 m_paRemoveOtherTabs
->setEnabled( false );
4077 m_paBreakOffTab
->setEnabled( false );
4078 m_paActivateNextTab
->setEnabled( false );
4079 m_paActivatePrevTab
->setEnabled( false );
4080 m_paMoveTabLeft
->setEnabled( false );
4081 m_paMoveTabRight
->setEnabled( false );
4083 m_paAddTab
->setEnabled( true );
4084 m_paDuplicateTab
->setEnabled( true );
4085 KonqFrameTabs
* tabContainer
= m_pViewManager
->tabContainer();
4086 bool state
= (tabContainer
->count()>1);
4087 m_paRemoveTab
->setEnabled( state
);
4088 m_paRemoveOtherTabs
->setEnabled( state
);
4089 m_paBreakOffTab
->setEnabled( state
);
4090 m_paActivateNextTab
->setEnabled( state
);
4091 m_paActivatePrevTab
->setEnabled( state
);
4093 QList
<KonqFrameBase
*> childFrameList
= tabContainer
->childFrameList();
4094 Q_ASSERT( !childFrameList
.isEmpty() );
4095 m_paMoveTabLeft
->setEnabled( currentView() ? currentView()->frame()!=
4096 (QApplication::isRightToLeft() ? childFrameList
.last() : childFrameList
.first()) : false );
4097 m_paMoveTabRight
->setEnabled( currentView() ? currentView()->frame()!=
4098 (QApplication::isRightToLeft() ? childFrameList
.first() : childFrameList
.last()) : false );
4101 // Can split a view if it's not a toggle view (because a toggle view can be here only once)
4102 bool isNotToggle
= m_currentView
&& !m_currentView
->isToggleView();
4103 m_paSplitViewHor
->setEnabled( isNotToggle
);
4104 m_paSplitViewVer
->setEnabled( isNotToggle
);
4106 m_paLinkView
->setChecked( m_currentView
&& m_currentView
->isLinkedView() );
4109 if ( m_currentView
&& m_currentView
->part() &&
4110 ::qobject_cast
<KonqDirPart
*>( m_currentView
->part() ) )
4112 KonqDirPart
* dirPart
= static_cast<KonqDirPart
*>(m_currentView
->part());
4113 m_paFindFiles
->setEnabled( dirPart
->findPart() == 0 );
4115 // Create the copy/move options if not already done
4116 // TODO: move that stuff to dolphin(part)
4117 if ( !m_paCopyFiles
)
4119 // F5 is the default key binding for Reload.... a la Windows.
4120 // mc users want F5 for Copy and F6 for move, but I can't make that default.
4123 m_paCopyFiles
= actionCollection()->addAction( "copyfiles" );
4124 m_paCopyFiles
->setText( i18n("Copy &Files...") );
4125 connect(m_paCopyFiles
, SIGNAL(triggered() ), SLOT( slotCopyFiles() ));
4126 m_paCopyFiles
->setShortcut(Qt::Key_F7
);
4127 m_paMoveFiles
= actionCollection()->addAction( "movefiles" );
4128 m_paMoveFiles
->setText( i18n("M&ove Files...") );
4129 connect(m_paMoveFiles
, SIGNAL(triggered() ), SLOT( slotMoveFiles() ));
4130 m_paMoveFiles
->setShortcut(Qt::Key_F8
);
4132 QList
<QAction
*> lst
;
4133 lst
.append( m_paCopyFiles
);
4134 lst
.append( m_paMoveFiles
);
4135 m_paCopyFiles
->setEnabled( false );
4136 m_paMoveFiles
->setEnabled( false );
4137 plugActionList( "operations", lst
);
4142 m_paFindFiles
->setEnabled( false );
4146 unplugActionList( "operations" );
4147 delete m_paCopyFiles
;
4149 delete m_paMoveFiles
;
4156 QString
KonqMainWindow::findIndexFile( const QString
&dir
)
4160 QString f
= d
.filePath( QLatin1String ( "index.html" ) );
4161 if ( QFile::exists( f
) )
4164 f
= d
.filePath( QLatin1String ( "index.htm" ) );
4165 if ( QFile::exists( f
) )
4168 f
= d
.filePath( QLatin1String( "index.HTML" ) );
4169 if ( QFile::exists( f
) )
4175 void KonqMainWindow::connectExtension( KParts::BrowserExtension
*ext
)
4177 KParts::BrowserExtension::ActionSlotMap
* actionSlotMap
= KParts::BrowserExtension::actionSlotMapPtr();
4178 KParts::BrowserExtension::ActionSlotMap::ConstIterator it
= actionSlotMap
->constBegin();
4179 KParts::BrowserExtension::ActionSlotMap::ConstIterator itEnd
= actionSlotMap
->constEnd();
4181 for ( ; it
!= itEnd
; ++it
)
4183 QAction
* act
= actionCollection()->action( it
.key().data() );
4184 //kDebug(1202) << it.key();
4187 // Does the extension have a slot with the name of this action ?
4188 if ( ext
->metaObject()->indexOfSlot( it
.key()+"()" ) != -1 )
4190 connect( act
, SIGNAL( triggered() ), ext
, it
.value() /* SLOT(slot name) */ );
4191 act
->setEnabled( ext
->isActionEnabled( it
.key() ) );
4192 const QString text
= ext
->actionText( it
.key() );
4193 if ( !text
.isEmpty() )
4194 act
->setText( text
);
4195 // TODO how to re-set the original action text, when switching to a part that didn't call setAction?
4196 // Can't test with Paste...
4198 act
->setEnabled(false);
4200 } else kError(1202) << "Error in BrowserExtension::actionSlotMap(), unknown action : " << it
.key();
4205 void KonqMainWindow::disconnectExtension( KParts::BrowserExtension
*ext
)
4207 KParts::BrowserExtension::ActionSlotMap
* actionSlotMap
= KParts::BrowserExtension::actionSlotMapPtr();
4208 KParts::BrowserExtension::ActionSlotMap::ConstIterator it
= actionSlotMap
->constBegin();
4209 KParts::BrowserExtension::ActionSlotMap::ConstIterator itEnd
= actionSlotMap
->constEnd();
4211 for ( ; it
!= itEnd
; ++it
)
4213 QAction
* act
= actionCollection()->action( it
.key().data() );
4214 //kDebug(1202) << it.key();
4215 if ( act
&& ext
->metaObject()->indexOfSlot( it
.key()+"()" ) != -1 )
4217 //kDebug(1202) << act << act->name();
4218 act
->disconnect( ext
);
4223 void KonqMainWindow::enableAction( const char * name
, bool enabled
)
4225 QAction
* act
= actionCollection()->action( name
);
4227 kWarning(1202) << "Unknown action " << name
<< " - can't enable" ;
4230 if ( m_bLocationBarConnected
&& (
4231 act
==m_paCopy
|| act
==m_paCut
|| act
==m_paPaste
) )
4232 // Don't change action state while the location bar has focus.
4234 //kDebug(1202) << name << enabled;
4235 act
->setEnabled( enabled
);
4238 // Update "copy files" and "move files" accordingly
4239 if (m_paCopyFiles
&& !strcmp( name
, "copy" ))
4241 m_paCopyFiles
->setEnabled( enabled
);
4243 else if (m_paMoveFiles
&& !strcmp( name
, "cut" ))
4245 m_paMoveFiles
->setEnabled( enabled
);
4249 void KonqMainWindow::setActionText(const char * name
, const QString
& text
)
4251 QAction
* act
= actionCollection()->action(name
);
4253 kWarning(1202) << "Unknown action " << name
<< "- can't enable" ;
4255 //kDebug(1202) << name << " text=" << text;
4260 void KonqMainWindow::setProfileConfig(const KConfigGroup
& cfg
)
4262 // Read toolbar settings and window size from profile, and autosave into that profile from now on
4263 setAutoSaveSettings(cfg
);
4264 currentProfileChanged();
4267 void KonqMainWindow::currentProfileChanged()
4269 const bool enabled
= !m_pViewManager
->currentProfile().isEmpty();
4270 m_paSaveViewProfile
->setEnabled(enabled
);
4271 m_paSaveViewProfile
->setText(enabled
? i18n("&Save View Profile \"%1\"...", m_pViewManager
->currentProfileText())
4272 : i18n("&Save View Profile..."));
4275 void KonqMainWindow::enableAllActions( bool enable
)
4277 //kDebug(1202) << enable;
4278 KParts::BrowserExtension::ActionSlotMap
* actionSlotMap
= KParts::BrowserExtension::actionSlotMapPtr();
4280 const QList
<QAction
*> actions
= actionCollection()->actions();
4281 QList
<QAction
*>::ConstIterator it
= actions
.constBegin();
4282 QList
<QAction
*>::ConstIterator end
= actions
.constEnd();
4283 for (; it
!= end
; ++it
)
4286 if ( !act
->objectName().startsWith("options_configure") /* do not touch the configureblah actions */
4287 && ( !enable
|| !actionSlotMap
->contains( act
->objectName().toLatin1() ) ) ) /* don't enable BE actions */
4288 act
->setEnabled( enable
);
4290 // This method is called with enable=false on startup, and
4291 // then only once with enable=true when the first view is setup.
4292 // So the code below is where actions that should initially be disabled are disabled.
4295 setUpEnabled( m_currentView
? m_currentView
->url() : KUrl() );
4296 // we surely don't have any history buffers at this time
4297 m_paBack
->setEnabled( false );
4298 m_paForward
->setEnabled( false );
4300 // Load profile submenu
4301 m_pViewManager
->profileListDirty( false );
4303 currentProfileChanged();
4305 updateViewActions(); // undo, lock, link and other view-dependent actions
4306 updateClosedItemsAction();
4308 m_paStop
->setEnabled( m_currentView
&& m_currentView
->isLoading() );
4310 if (m_toggleViewGUIClient
)
4312 QList
<QAction
*> actions
= m_toggleViewGUIClient
->actions();
4313 for (int i
= 0; i
< actions
.size(); ++i
) {
4314 actions
.at(i
)->setEnabled( true );
4319 actionCollection()->action( "quit" )->setEnabled( true );
4322 void KonqMainWindow::disableActionsNoView()
4324 // No view -> there are some things we can't do
4325 m_paUp
->setEnabled( false );
4326 m_paReload
->setEnabled( false );
4327 m_paReloadAllTabs
->setEnabled( false );
4328 m_paBack
->setEnabled( false );
4329 m_paForward
->setEnabled( false );
4330 m_ptaUseHTML
->setEnabled( false );
4331 m_paLockView
->setEnabled( false );
4332 m_paLockView
->setChecked( false );
4333 m_paSplitViewVer
->setEnabled( false );
4334 m_paSplitViewHor
->setEnabled( false );
4335 m_paRemoveView
->setEnabled( false );
4336 m_paLinkView
->setEnabled( false );
4337 if (m_toggleViewGUIClient
)
4339 QList
<QAction
*> actions
= m_toggleViewGUIClient
->actions();
4340 for (int i
= 0; i
< actions
.size(); ++i
) {
4341 actions
.at(i
)->setEnabled( false );
4344 // There are things we can do, though : bookmarks, view profile, location bar, new window,
4346 m_paHome
->setEnabled( true );
4347 m_pamBookmarks
->setEnabled( true );
4348 static const char* const s_enActions
[] = { "new_window", "duplicate_window", "open_location",
4349 "toolbar_url_combo", "clear_location", "animated_logo",
4350 "konqintro", "go_most_often", "go_applications",
4351 "go_trash", "go_settings", "go_network_folders", "go_autostart",
4352 "go_url", "go_media", "go_history", "options_configure_extensions", 0 };
4353 for ( int i
= 0 ; s_enActions
[i
] ; ++i
)
4355 QAction
* act
= action(s_enActions
[i
]);
4357 act
->setEnabled( true );
4359 m_pamLoadViewProfile
->setEnabled( true );
4360 m_paSaveViewProfile
->setEnabled( true );
4361 m_paSaveRemoveViewProfile
->setEnabled( true );
4362 m_combo
->clearTemporary();
4365 void KonqMainWindow::setCaption( const QString
&caption
)
4367 // KParts sends us empty captions when activating a brand new part
4368 // We can't change it there (in case of apps removing all parts altogether)
4369 // but here we never do that.
4370 if (!caption
.isEmpty() && m_currentView
) {
4371 //kDebug(1202) << caption;
4373 // Keep an unmodified copy of the caption (before KComponentData::makeStdCaption is applied)
4374 m_currentView
->setCaption(caption
);
4375 KParts::MainWindow::setCaption(m_currentView
->caption());
4379 void KonqMainWindow::showEvent(QShowEvent
*event
)
4381 // We need to check if our toolbars are shown/hidden here, and set
4382 // our menu items accordingly. We can't do it in the constructor because
4383 // view profiles store toolbar info, and that info is read after
4385 m_paShowMenuBar
->setChecked( !menuBar()->isHidden() );
4386 updateBookmarkBar(); // hide if empty
4388 // Call parent method
4389 KParts::MainWindow::showEvent(event
);
4392 QString
KonqExtendedBookmarkOwner::currentUrl() const
4394 return m_pKonqMainWindow
->currentView()->url().url();
4397 QString
KonqMainWindow::currentProfile() const
4399 return m_pViewManager
->currentProfile();
4402 QString
KonqMainWindow::currentURL() const
4404 if ( !m_currentView
)
4406 QString url
= m_currentView
->url().prettyUrl();
4408 #if 0 // do we want this?
4409 // Add the name filter (*.txt) at the end of the URL again
4410 if ( m_currentView
->part() ) {
4411 const QString nameFilter
= m_currentView
->nameFilter();
4412 if (!nameFilter
.isEmpty()) {
4413 if (!url
.endsWith('/'))
4422 bool KonqExtendedBookmarkOwner::supportsTabs() const
4427 QList
<QPair
<QString
, QString
> > KonqExtendedBookmarkOwner::currentBookmarkList() const
4429 QList
<QPair
<QString
, QString
> > list
;
4430 KonqFrameTabs
* tabContainer
= m_pKonqMainWindow
->viewManager()->tabContainer();
4432 foreach ( KonqFrameBase
* frame
, tabContainer
->childFrameList() )
4434 if ( !frame
|| !frame
->activeChildView() )
4436 if( frame
->activeChildView()->locationBarURL().isEmpty() )
4438 list
<< qMakePair( frame
->activeChildView()->caption(),
4439 frame
->activeChildView()->url().url() );
4444 QString
KonqExtendedBookmarkOwner::currentTitle() const
4446 return m_pKonqMainWindow
->currentTitle();
4449 void KonqExtendedBookmarkOwner::openInNewTab(const KBookmark
&bm
)
4451 bool newTabsInFront
= KonqSettings::newTabsInFront();
4452 if (QApplication::keyboardModifiers() & Qt::ShiftModifier
)
4453 newTabsInFront
= !newTabsInFront
;
4455 KonqOpenURLRequest req
;
4456 req
.browserArgs
.setNewTab(true);
4457 req
.newTabInFront
= newTabsInFront
;
4458 req
.openAfterCurrentPage
= false;
4459 req
.forceAutoEmbed
= true;
4461 m_pKonqMainWindow
->openUrl( 0, bm
.url(), QString(), req
);
4464 void KonqExtendedBookmarkOwner::openFolderinTabs(const KBookmarkGroup
&grp
)
4466 bool newTabsInFront
= KonqSettings::newTabsInFront();
4467 if (QApplication::keyboardModifiers() & Qt::ShiftModifier
)
4468 newTabsInFront
= !newTabsInFront
;
4469 KonqOpenURLRequest req
;
4470 req
.browserArgs
.setNewTab(true);
4471 req
.newTabInFront
= false;
4472 req
.openAfterCurrentPage
= false;
4473 req
.forceAutoEmbed
= true;
4475 const QList
<KUrl
> list
= grp
.groupUrlList();
4479 if (list
.size() > 20) {
4480 if(KMessageBox::questionYesNo(m_pKonqMainWindow
,
4481 i18n("You have requested to open more than 20 bookmarks in tabs. "
4482 "This might take a while. Continue?"),
4483 i18n("Open bookmarks folder in new tabs")) != KMessageBox::Yes
)
4487 QList
<KUrl
>::ConstIterator it
= list
.constBegin();
4488 QList
<KUrl
>::ConstIterator end
= list
.constEnd();
4490 for (; it
!= end
; ++it
)
4492 m_pKonqMainWindow
->openUrl( 0, *it
, QString(), req
);
4494 if ( newTabsInFront
)
4496 req
.newTabInFront
= true;
4498 m_pKonqMainWindow
->openUrl( 0, *end
, QString(), req
);
4501 void KonqExtendedBookmarkOwner::openInNewWindow(const KBookmark
&bm
)
4503 KonqMisc::createNewWindow( bm
.url(), KParts::OpenUrlArguments() );
4506 QString
KonqMainWindow::currentTitle() const
4508 return m_currentView
? m_currentView
->caption() : QString();
4511 void KonqMainWindow::slotPopupMenu( const QPoint
&global
, const KUrl
&url
, mode_t mode
, const KParts::OpenUrlArguments
&args
, const KParts::BrowserArguments
& browserArgs
, KParts::BrowserExtension::PopupFlags flags
, const KParts::BrowserExtension::ActionGroupMap
& actionGroups
)
4513 KFileItem
item( url
, args
.mimeType(), mode
);
4514 KFileItemList items
;
4515 items
.append( item
);
4516 slotPopupMenu( global
, items
, args
, browserArgs
, flags
, actionGroups
);
4519 void KonqMainWindow::slotPopupMenu( const QPoint
&global
, const KFileItemList
&items
, const KParts::OpenUrlArguments
&args
, const KParts::BrowserArguments
& browserArgs
, KParts::BrowserExtension::PopupFlags itemFlags
, const KParts::BrowserExtension::ActionGroupMap
& _actionGroups
)
4521 KParts::BrowserExtension::ActionGroupMap actionGroups
= _actionGroups
;
4523 KonqView
* m_oldView
= m_currentView
;
4524 KonqView
* currentView
= childView( static_cast<KParts::ReadOnlyPart
*>( sender()->parent() ) );
4526 //kDebug() << "m_oldView=" << m_oldView << "new currentView=" << currentView << "passive:" << currentView->isPassiveMode();
4528 if ( (m_oldView
!= currentView
) && currentView
->isPassiveMode() )
4530 // Make this view active only temporarily (because it's passive)
4531 m_currentView
= currentView
;
4533 if ( m_oldView
&& m_oldView
->browserExtension() )
4534 disconnectExtension( m_oldView
->browserExtension() );
4535 if ( m_currentView
->browserExtension() )
4536 connectExtension( m_currentView
->browserExtension() );
4538 // Note that if m_oldView!=currentView and currentView isn't passive,
4539 // then the KParts mechanism has already noticed the click in it,
4540 // but KonqViewManager delays the GUI-rebuilding with a single-shot timer.
4541 // Right after the popup shows up, currentView _will_ be m_currentView.
4543 //kDebug(1202) << "current view=" << m_currentView << m_currentView->part()->metaObject()->className();
4545 // This action collection is used to pass actions to KonqPopupMenu.
4546 // It has to be a KActionCollection instead of a KActionPtrList because we need
4547 // the actionStatusText signal...
4548 KActionCollection
popupMenuCollection( (QWidget
*)0 );
4550 // m_paBack is a submenu, for the toolbar & edit menu "back",
4551 // but in the RMB we want a simple one-click back instead.
4552 KAction
* simpleBack
= KStandardAction::back( this, SLOT(slotBack()), &popupMenuCollection
);
4553 simpleBack
->setEnabled( m_paBack
->isEnabled() );
4554 popupMenuCollection
.addAction( "go_back", simpleBack
);
4556 KAction
* simpleForward
= KStandardAction::forward( this, SLOT(slotForward()), &popupMenuCollection
);
4557 simpleForward
->setEnabled( m_paForward
->isEnabled() );
4558 popupMenuCollection
.addAction( "go_forward", simpleForward
);
4560 popupMenuCollection
.addAction( "go_up", m_paUp
);
4561 popupMenuCollection
.addAction( "reload", m_paReload
);
4562 popupMenuCollection
.addAction( "closeditems", m_paClosedItems
);
4565 popupMenuCollection
.addAction( "find", m_paFindFiles
);
4568 popupMenuCollection
.addAction( "undo", m_paUndo
);
4569 popupMenuCollection
.addAction( "cut", m_paCut
);
4570 popupMenuCollection
.addAction( "copy", m_paCopy
);
4571 popupMenuCollection
.addAction( "paste", m_paPaste
);
4573 // The pasteto action is used when clicking on a dir, to paste into it.
4574 KAction
*actPaste
= KStandardAction::paste( this, SLOT( slotPopupPasteTo() ), this );
4575 actPaste
->setEnabled( m_paPaste
->isEnabled() );
4576 popupMenuCollection
.addAction( "pasteto", actPaste
);
4578 prepareForPopupMenu(items
, args
, browserArgs
);
4580 bool sReading
= false;
4581 if (!m_popupUrl
.isEmpty()) {
4582 sReading
= KProtocolManager::supportsReading(m_popupUrl
);
4585 // Don't set the view URL for a toggle view.
4586 // (This is a bit of a hack for the directory tree....)
4587 // ## should use the new currentView->isHierarchicalView() instead?
4588 // Would this be correct for the konqlistview tree view?
4589 KUrl viewURL
= currentView
->isToggleView() ? KUrl() : currentView
->url();
4591 bool openedForViewURL
= false;
4592 //bool dirsSelected = false;
4593 bool devicesFile
= false;
4595 if ( items
.count() == 1 )
4597 const KUrl firstURL
= items
.first().url();
4598 if ( !viewURL
.isEmpty() )
4600 //firstURL.cleanPath();
4601 openedForViewURL
= firstURL
.equals( viewURL
, KUrl::CompareWithoutTrailingSlash
);
4603 devicesFile
= firstURL
.protocol().indexOf("device", 0, Qt::CaseInsensitive
) == 0;
4604 //dirsSelected = S_ISDIR( items.first()->mode() );
4606 //kDebug(1202) << "viewURL=" << viewURL;
4610 bool isIntoTrash
= url
.protocol() == "trash" || url
.url().startsWith( "system:/trash" );
4611 const bool doTabHandling
= !openedForViewURL
&& !isIntoTrash
&& sReading
;
4612 const bool showEmbeddingServices
= items
.count() == 1 && !m_popupMimeType
.isEmpty() &&
4613 !isIntoTrash
&& !devicesFile
&&
4614 (itemFlags
& KParts::BrowserExtension::ShowTextSelectionItems
) == 0;
4616 KService::List embeddingServices
;
4617 if ( showEmbeddingServices
) {
4618 const QString currentServiceName
= currentView
->service()->desktopEntryName();
4620 // List of services for the "Preview In" submenu.
4621 embeddingServices
= KMimeTypeTrader::self()->query(
4623 "KParts/ReadOnlyPart",
4624 // Obey "HideFromMenus". It defaults to false so we want "absent or true"
4625 // (wow, testing for 'true' if absent doesn't work, so order matters)
4626 "(not exist [X-KDE-BrowserView-HideFromMenus] or not [X-KDE-BrowserView-HideFromMenus]) "
4627 "and DesktopEntryName != '"+currentServiceName
+"' "
4628 // I had an old local dirtree.desktop without lib, no need for invalid entries
4629 "and exist [Library]");
4632 PopupMenuGUIClient
*konqyMenuClient
= new PopupMenuGUIClient( embeddingServices
,
4634 !menuBar()->isVisible() ? m_paShowMenuBar
: 0,
4635 fullScreenMode() ? m_ptaFullScreen
: 0
4637 qRegisterMetaType
<KService::Ptr
>("KService::Ptr");
4638 connect(konqyMenuClient
, SIGNAL(openEmbedded(KService::Ptr
)),
4639 this, SLOT(slotOpenEmbedded(KService::Ptr
)), Qt::QueuedConnection
);
4642 // Those actions go into the PopupMenuGUIClient, since that's the one defining them.
4643 QList
<QAction
*> tabHandlingActions
;
4646 if (browserArgs
.forcesNewWindow()) {
4647 QAction
* act
= konqyMenuClient
->actionCollection()->addAction( "sameview" );
4648 act
->setText( i18n( "Open in T&his Window" ) );
4649 act
->setToolTip( i18n( "Open the document in current window" ) );
4650 connect(act
, SIGNAL(triggered() ), SLOT( slotPopupThisWindow() ));
4651 tabHandlingActions
.append(act
);
4653 QAction
* actNewWindow
= konqyMenuClient
->actionCollection()->addAction( "newview" );
4654 actNewWindow
->setIcon( KIcon("window-new") );
4655 actNewWindow
->setText( i18n( "Open in New &Window" ) );
4656 actNewWindow
->setToolTip( i18n( "Open the document in a new window" ) );
4657 connect(actNewWindow
, SIGNAL(triggered()), SLOT( slotPopupNewWindow() ));
4658 tabHandlingActions
.append(actNewWindow
);
4660 QAction
* actNewTab
= konqyMenuClient
->actionCollection()->addAction( "openintab" );
4661 actNewTab
->setIcon( KIcon("tab-new") );
4662 actNewTab
->setText( i18n( "Open in &New Tab" ) );
4663 connect(actNewTab
, SIGNAL(triggered()), SLOT( slotPopupNewTab() ));
4664 actNewTab
->setToolTip( i18n( "Open the document in a new tab" ) );
4665 tabHandlingActions
.append(actNewTab
);
4667 QAction
* separator
= new QAction(konqyMenuClient
->actionCollection());
4668 separator
->setSeparator(true);
4669 tabHandlingActions
.append(separator
);
4672 if (currentView
->isHierarchicalView())
4673 itemFlags
|= KParts::BrowserExtension::ShowCreateDirectory
;
4675 KonqPopupMenu::Flags kpf
= 0;
4678 actionGroups
.insert("tabhandling", tabHandlingActions
);
4679 //if (kpf & KonqPopupMenu::IsLink)
4680 // actionGroups.insert("linkactions", linkActions);
4681 // TODO actionGroups.insert("partactions", partActions);
4683 QPointer
<KonqPopupMenu
> pPopupMenu
= new KonqPopupMenu(
4686 popupMenuCollection
,
4690 // This parent ensures that if the part destroys itself (e.g. KHTML redirection),
4691 // it will close the popupmenu
4692 currentView
->part()->widget(),
4696 if ( openedForViewURL
&& !viewURL
.isLocalFile() )
4697 pPopupMenu
->setURLTitle( currentView
->caption() );
4699 QPointer
<KParts::BrowserExtension
> be
= ::qobject_cast
<KParts::BrowserExtension
*>(sender());
4702 QObject::connect( this, SIGNAL(popupItemsDisturbed()), pPopupMenu
, SLOT(close()) );
4703 QObject::connect( be
, SIGNAL(itemsRemoved(const KFileItemList
&)),
4704 this, SLOT(slotItemsRemoved(const KFileItemList
&)) );
4708 QPointer
<QObject
> guard( this ); // #149736, window could be deleted inside popupmenu event loop
4709 pPopupMenu
->exec( global
);
4713 // We're sort of misusing KActionCollection here, but we need it for the actionStatusText signal...
4714 // Anyway. If the action belonged to the view, and the view got deleted, we don't want ~KActionCollection
4715 // to iterate over those deleted actions
4716 /*KActionPtrList lst = popupMenuCollection.actions();
4717 KActionPtrList::iterator it = lst.begin();
4718 for ( ; it != lst.end() ; ++it )
4719 popupMenuCollection.take( *it );*/
4721 if ( guard
.isNull() ) // the placement of this test is very important, double-check #149736 if moving stuff around
4725 QObject::disconnect( be
, SIGNAL(itemsRemoved(const KFileItemList
&)),
4726 this, SLOT(slotItemsRemoved(const KFileItemList
&)) );
4729 delete konqyMenuClient
;
4730 m_popupItems
.clear();
4732 // Deleted by konqyMenuClient's actioncollection
4734 //delete actNewWindow;
4738 // Restore current view if current is passive
4739 if ( (m_oldView
!= currentView
) && (currentView
== m_currentView
) && currentView
->isPassiveMode() )
4741 //kDebug() << "restoring active view" << m_oldView;
4742 if ( m_currentView
->browserExtension() )
4743 disconnectExtension( m_currentView
->browserExtension() );
4746 if ( m_oldView
->browserExtension() )
4748 connectExtension( m_oldView
->browserExtension() );
4749 m_currentView
= m_oldView
;
4751 // Special case: RMB + renaming in sidebar; setFocus would abort editing.
4752 QWidget
* fw
= focusWidget();
4753 if ( !fw
|| !::qobject_cast
<QLineEdit
*>( fw
) )
4754 m_oldView
->part()->widget()->setFocus();
4759 void KonqMainWindow::prepareForPopupMenu(const KFileItemList
&items
, const KParts::OpenUrlArguments
&args
, const KParts::BrowserArguments
& browserArgs
)
4761 if (!items
.isEmpty()) {
4762 m_popupUrl
= items
.first().url();
4763 m_popupMimeType
= items
.first().mimetype();
4767 m_popupUrl
= KUrl();
4768 m_popupMimeType
.clear();
4770 // We will need these if we call the newTab slot
4771 m_popupItems
= items
;
4772 m_popupUrlArgs
= args
;
4773 m_popupUrlArgs
.setMimeType( QString() ); // Reset so that Open in New Window/Tab does mimetype detection
4774 m_popupUrlBrowserArgs
= browserArgs
;
4777 void KonqMainWindow::slotItemsRemoved(const KFileItemList
&items
)
4779 QListIterator
<KFileItem
> it(items
);
4780 while (it
.hasNext()) {
4781 if (m_popupItems
.contains(it
.next())) {
4782 emit
popupItemsDisturbed();
4788 Q_DECLARE_METATYPE(KService::Ptr
)
4789 void KonqMainWindow::slotOpenEmbedded(KService::Ptr service
)
4791 m_currentView
->stop();
4792 m_currentView
->setLocationBarURL(m_popupUrl
);
4793 m_currentView
->setTypedURL(QString());
4794 if ( m_currentView
->changePart( m_popupMimeType
,
4795 service
->desktopEntryName(), true ) )
4796 m_currentView
->openUrl( m_popupUrl
, m_popupUrl
.pathOrUrl() );
4799 void KonqMainWindow::slotDatabaseChanged()
4801 if ( KSycoca::isChanged("mimetypes") )
4803 MapViews::ConstIterator it
= m_mapViews
.constBegin();
4804 MapViews::ConstIterator end
= m_mapViews
.constEnd();
4805 for (; it
!= end
; ++it
)
4806 (*it
)->callExtensionMethod( "refreshMimeTypes" );
4810 void KonqMainWindow::slotPopupPasteTo()
4812 if ( !m_currentView
|| m_popupUrl
.isEmpty() )
4814 m_currentView
->callExtensionURLMethod( "pasteTo", m_popupUrl
);
4817 void KonqMainWindow::slotReconfigure()
4819 reparseConfiguration();
4822 void KonqMainWindow::reparseConfiguration()
4826 KonqSettings::self()->readConfig();
4827 m_pViewManager
->applyConfiguration();
4829 m_bHTMLAllowed
= KonqSettings::htmlAllowed();
4832 m_combo
->setFont( KGlobalSettings::generalFont() );
4834 MapViews::ConstIterator it
= m_mapViews
.constBegin();
4835 MapViews::ConstIterator end
= m_mapViews
.constEnd();
4836 for (; it
!= end
; ++it
)
4837 (*it
)->reparseConfiguration();
4840 void KonqMainWindow::saveProperties( KConfigGroup
& config
)
4842 // Ensure no crash if the sessionmanager timer fires before the ctor is done
4843 // This can happen via ToggleViewGUIClient -> KServiceTypeTrader::query
4844 // -> KSycoca running kbuildsycoca -> nested event loop.
4845 if (m_fullyConstructed
) {
4846 KonqFrameBase::Options flags
= KonqFrameBase::saveHistoryItems
;
4847 m_pViewManager
->saveViewProfileToGroup(config
, flags
);
4851 void KonqMainWindow::readProperties( const KConfigGroup
& configGroup
)
4853 // ######### THIS CANNOT WORK. It's too late to change the xmlfile, the GUI has been built already!
4854 // We need to delay doing setXMLFile+createGUI until we know which profile we are going to use, then...
4855 // TODO: Big refactoring needed for this feature. On the other hand, all default profiles shipped with
4856 // konqueror use konqueror.rc again, so the need for this is almost zero now.
4857 const QString xmluiFile
= configGroup
.readEntry("XMLUIFile","konqueror.rc");
4858 setXMLFile( KonqViewManager::normalizedXMLFileName(xmluiFile
) );
4860 m_pViewManager
->loadViewProfileFromGroup( configGroup
, QString() /*no profile name*/ );
4861 // read window settings
4862 applyMainWindowSettings( configGroup
, true );
4865 void KonqMainWindow::setInitialFrameName( const QString
&name
)
4867 m_initialFrameName
= name
;
4870 void KonqMainWindow::updateOpenWithActions()
4872 unplugActionList( "openwithbase" );
4873 unplugActionList( "openwith" );
4875 qDeleteAll(m_openWithActions
);
4876 m_openWithActions
.clear();
4878 delete m_openWithMenu
;
4881 if (!KAuthorized::authorizeKAction("openwith"))
4884 m_openWithMenu
= new KActionMenu( i18n("&Open With"), this );
4886 const KService::List
& services
= m_currentView
->appServiceOffers();
4887 KService::List::ConstIterator it
= services
.constBegin();
4888 const KService::List::ConstIterator end
= services
.constEnd();
4890 const int baseOpenWithItems
= qMax(KonqSettings::openWithItems(), 0);
4893 for (; it
!= end
; ++it
, ++idxService
)
4897 if (idxService
< baseOpenWithItems
)
4898 action
= new QAction(i18n("Open with %1", (*it
)->name()), this);
4900 action
= new QAction((*it
)->name(), this);
4901 action
->setIcon( KIcon( (*it
)->icon() ) );
4903 connect( action
, SIGNAL( triggered() ),
4904 this, SLOT( slotOpenWith() ) );
4906 actionCollection()->addAction((*it
)->desktopEntryName(), action
);
4907 if (idxService
< baseOpenWithItems
)
4908 m_openWithActions
.append(action
);
4910 m_openWithMenu
->addAction(action
);
4913 if ( services
.count() > 0 )
4915 plugActionList("openwithbase", m_openWithActions
);
4916 QList
<QAction
*> openWithActionsMenu
;
4917 if (idxService
> baseOpenWithItems
)
4919 openWithActionsMenu
.append(m_openWithMenu
);
4921 QAction
*sep
= new QAction( this );
4922 sep
->setSeparator( true );
4923 openWithActionsMenu
.append(sep
);
4924 plugActionList("openwith", openWithActionsMenu
);
4928 void KonqMainWindow::updateViewModeActions()
4930 unplugViewModeActions();
4931 Q_FOREACH( QAction
* action
, m_viewModesGroup
->actions() ) {
4932 Q_FOREACH( QWidget
*w
, action
->associatedWidgets() )
4933 w
->removeAction( action
);
4937 delete m_viewModeMenu
;
4940 const KService::List services
= m_currentView
->partServiceOffers();
4941 if ( services
.count() <= 1 )
4944 m_viewModeMenu
= new KActionMenu( i18nc("@action:inmenu View", "&View Mode"), this );
4945 //actionCollection()->addAction( "viewModeMenu", m_viewModeMenu );
4947 KService::List::ConstIterator it
= services
.constBegin();
4948 const KService::List::ConstIterator end
= services
.constEnd();
4949 for (; it
!= end
; ++it
) {
4950 const KService::Ptr service
= *it
;
4951 const QVariant prop
= service
->property( "X-KDE-BrowserView-Toggable" );
4952 if (prop
.isValid() && prop
.toBool()) // No toggable views in view mode
4955 const QString desktopEntryName
= service
->desktopEntryName();
4956 bool bIsCurrentView
= desktopEntryName
== m_currentView
->service()->desktopEntryName();
4958 const QList
<KServiceAction
> actions
= service
->actions();
4959 if (!actions
.isEmpty()) {
4961 // The service provides several view modes, like DolphinPart
4962 // -> create one action per view mode
4963 Q_FOREACH(const KServiceAction
& serviceAction
, actions
) {
4964 // Create a KToggleAction for each view mode, and plug it into the menu
4965 KToggleAction
* action
= new KToggleAction(KIcon(serviceAction
.icon()), serviceAction
.text(), this);
4966 //actionCollection()->addAction(desktopEntryName /*not unique!*/, action);
4967 action
->setObjectName(desktopEntryName
);
4968 action
->setData(QVariant(serviceAction
.name()));
4969 action
->setActionGroup(m_viewModesGroup
);
4970 m_viewModeMenu
->menu()->addAction(action
);
4971 if (bIsCurrentView
&& m_currentView
->internalViewMode() == serviceAction
.name()) {
4972 action
->setChecked(true);
4977 // The service only provides one view mode (common case)
4979 QString serviceText
= service
->genericName();
4980 if (serviceText
.isEmpty())
4981 serviceText
= service
->name();
4983 // Create a KToggleAction for this view mode, and plug it into the menu
4984 KToggleAction
* action
= new KToggleAction(KIcon(service
->icon()), serviceText
, this);
4985 actionCollection()->addAction(desktopEntryName
, action
);
4986 action
->setObjectName(desktopEntryName
);
4987 action
->setActionGroup(m_viewModesGroup
);
4988 m_viewModeMenu
->menu()->addAction(action
);
4990 action
->setChecked(bIsCurrentView
);
4994 // No view mode for actions toggable views
4995 // (The other way would be to enforce a better servicetype for them, than Browser/View)
4996 if (!m_currentView
->isToggleView()
4997 /* already tested: && services.count() > 1 */
4998 && m_viewModeMenu
) {
4999 plugViewModeActions();
5003 void KonqMainWindow::slotInternalViewModeChanged()
5005 KParts::ReadOnlyPart
*part
= static_cast<KParts::ReadOnlyPart
*>(sender());
5006 KonqView
* view
= m_mapViews
.value(part
);
5008 const QString actionName
= view
->service()->desktopEntryName();
5009 const QString actionData
= view
->internalViewMode();
5010 Q_FOREACH(QAction
* action
, m_viewModesGroup
->actions()) {
5011 if (action
->objectName() == actionName
&&
5012 action
->data().toString() == actionData
) {
5013 action
->setChecked(true);
5020 void KonqMainWindow::plugViewModeActions()
5022 QList
<QAction
*> lst
;
5023 lst
.append( m_viewModeMenu
);
5024 plugActionList( "viewmode", lst
);
5027 void KonqMainWindow::unplugViewModeActions()
5029 unplugActionList( "viewmode" );
5032 void KonqMainWindow::updateBookmarkBar()
5034 KToolBar
* bar
= qFindChild
<KToolBar
*>(this, "bookmarkToolBar");
5036 if (m_paBookmarkBar
&& bar
->actions().isEmpty() )
5041 void KonqMainWindow::closeEvent( QCloseEvent
*e
)
5043 // This breaks session management (the window is withdrawn in kwin)
5044 // so let's do this only when closed by the user.
5045 KonquerorApplication
* konqApp
= qobject_cast
<KonquerorApplication
*>(qApp
);
5047 // konqApp is 0 in unit tests
5048 if (konqApp
&& konqApp
->closedByUser()) {
5049 KonqFrameTabs
* tabContainer
= m_pViewManager
->tabContainer();
5050 if ( tabContainer
->count() > 1 )
5052 KSharedConfig::Ptr config
= KGlobal::config();
5053 KConfigGroup
cs( config
, QLatin1String("Notification Messages") );
5055 if ( !cs
.hasKey( "MultipleTabConfirm" ) )
5058 KMessageBox::warningYesNoCancel(
5060 i18n("You have multiple tabs open in this window, "
5061 "are you sure you want to quit?"),
5062 i18n("Confirmation"),
5063 KStandardGuiItem::quit(),
5064 KGuiItem(i18n( "C&lose Current Tab" ), "tab-close"),
5065 KStandardGuiItem::cancel(),
5066 "MultipleTabConfirm"
5069 case KMessageBox::Yes
:
5071 case KMessageBox::No
:
5078 case KMessageBox::Cancel
:
5087 KonqView
*originalView
= m_currentView
;
5088 MapViews::ConstIterator it
= m_mapViews
.constBegin();
5089 MapViews::ConstIterator end
= m_mapViews
.constEnd();
5090 for (; it
!= end
; ++it
) {
5091 KonqView
*view
= it
.value();
5092 if (view
&& view
->part() && (view
->part()->metaObject()->indexOfProperty("modified") != -1) ) {
5093 QVariant prop
= view
->part()->property("modified");
5094 if (prop
.isValid() && prop
.toBool()) {
5095 m_pViewManager
->showTab( view
);
5096 const QString question
= m_pViewManager
->isTabBarVisible()
5097 ? i18n("This tab contains changes that have not been submitted.\nClosing the window will discard these changes.")
5098 : i18n("This page contains changes that have not been submitted.\nClosing the window will discard these changes.");
5099 if ( KMessageBox::warningContinueCancel( this, question
,
5100 i18n("Discard Changes?"), KGuiItem(i18n("&Discard Changes"),"application-exit"), KStandardGuiItem::cancel(), "discardchangesclose") != KMessageBox::Continue
)
5103 m_pViewManager
->showTab( originalView
);
5110 if (settingsDirty() && autoSaveSettings())
5111 saveAutoSaveSettings();
5113 addClosedWindowToUndoList();
5118 // We're going to close - tell the parts
5119 MapViews::ConstIterator it
= m_mapViews
.constBegin();
5120 MapViews::ConstIterator end
= m_mapViews
.constEnd();
5121 for (; it
!= end
; ++it
)
5123 if ( (*it
)->part() && (*it
)->part()->widget() )
5124 QApplication::sendEvent( (*it
)->part()->widget(), e
);
5126 KParts::MainWindow::closeEvent( e
);
5127 if( isPreloaded() && !kapp
->sessionSaving())
5128 { // queryExit() refused closing, hide instead
5133 void KonqMainWindow::addClosedWindowToUndoList()
5137 // 1. We get the current title
5138 int numTabs
= m_pViewManager
->tabContainer()->childFrameList().count();
5139 QString
title( i18n("no name") );
5142 title
= m_currentView
->caption();
5144 // 2. Create the KonqClosedWindowItem and save its config
5145 KonqClosedWindowItem
* closedWindowItem
= new KonqClosedWindowItem(title
, m_pUndoManager
->newCommandSerialNumber(), numTabs
);
5146 saveProperties( closedWindowItem
->configGroup() );
5148 // 3. Add the KonqClosedWindowItem to the undo list
5149 m_paClosedItems
->setEnabled(true);
5150 m_pUndoManager
->addClosedWindowItem( closedWindowItem
);
5152 kDebug(1202) << "done";
5155 bool KonqMainWindow::queryExit()
5157 if( kapp
&& kapp
->sessionSaving()) // *sigh*
5159 return !stayPreloaded();
5162 void KonqMainWindow::updateWindowIcon()
5164 const QString url
= m_combo
->currentText();
5165 // TODO (kfm-devel email 13/09/2008) should we use a profile-defined icon instead of a url-dependent window icon?
5166 const QPixmap pix
= KonqPixmapProvider::self()->pixmapFor( url
);
5167 KParts::MainWindow::setWindowIcon( pix
);
5170 if (!url
.isEmpty()) {
5171 big
= KonqPixmapProvider::self()->pixmapFor( url
, KIconLoader::SizeMedium
);
5174 KWindowSystem::setIcons( winId(), big
, pix
);
5177 void KonqMainWindow::slotIntro()
5179 openUrl( 0, KUrl("about:") );
5182 void KonqMainWindow::goURL()
5184 QLineEdit
*lineEdit
= m_combo
->lineEdit();
5188 QKeyEvent
event( QEvent::KeyPress
, Qt::Key_Return
, Qt::NoModifier
, QChar('\n') );
5189 QApplication::sendEvent( lineEdit
, &event
);
5193 * Adds the URL of a KonqView to the closed tabs list.
5194 * This slot gets called each time a View is closed.
5196 void KonqMainWindow::slotAddClosedUrl(KonqFrameBase
*tab
)
5199 QString
title( i18n("no name") ), url("about:blank");
5201 // Did the tab contain a single frame, or a splitter?
5202 KonqFrame
* frame
= dynamic_cast<KonqFrame
*>(tab
);
5204 KonqFrameContainer
* frameContainer
= dynamic_cast<KonqFrameContainer
*>(tab
);
5205 if (frameContainer
->activeChildView())
5206 frame
= frameContainer
->activeChildView()->frame();
5209 KParts::ReadOnlyPart
* part
= frame
? frame
->part() : 0;
5211 url
= part
->url().url();
5213 title
= frame
->title().trimmed();
5214 if (title
.isEmpty())
5216 title
= KStringHandler::csqueeze( title
, 50 );
5218 // Now we get the position of the tab
5219 const int index
= m_pViewManager
->tabContainer()->childFrameList().indexOf(tab
);
5221 KonqClosedTabItem
* closedTabItem
= new KonqClosedTabItem(url
, title
, index
, m_pUndoManager
->newCommandSerialNumber());
5223 QString prefix
= KonqFrameBase::frameTypeToString( tab
->frameType() ) + QString::number(0);
5224 closedTabItem
->configGroup().writeEntry( "RootItem", prefix
);
5225 prefix
.append( QLatin1Char( '_' ) );
5226 KonqFrameBase::Options flags
= KonqFrameBase::saveHistoryItems
;
5227 tab
->saveConfig( closedTabItem
->configGroup(), prefix
, flags
, 0L, 0, 1);
5229 m_paClosedItems
->setEnabled(true);
5230 m_pUndoManager
->addClosedTabItem( closedTabItem
);
5232 kDebug(1202) << "done";
5235 void KonqMainWindow::slotLocationLabelActivated()
5238 m_combo
->lineEdit()->selectAll();
5241 void KonqMainWindow::slotOpenURL( const KUrl
& url
)
5246 bool KonqMainWindow::sidebarVisible() const
5248 QAction
*a
= m_toggleViewGUIClient
->action("konq_sidebartng");
5249 return (a
&& static_cast<KToggleAction
*>(a
)->isChecked());
5252 bool KonqMainWindow::fullScreenMode() const
5254 return m_ptaFullScreen
->isChecked();
5257 void KonqMainWindow::slotAddWebSideBar(const KUrl
& url
, const QString
& name
)
5259 if (url
.url().isEmpty() && name
.isEmpty())
5262 kDebug(1202) << "Requested to add URL" << url
<< " [" << name
<< "] to the sidebar!";
5264 QAction
*a
= m_toggleViewGUIClient
->action("konq_sidebartng");
5266 KMessageBox::sorry(0, i18n("Your sidebar is not functional or unavailable. A new entry cannot be added."), i18n("Web Sidebar"));
5270 int rc
= KMessageBox::questionYesNo(0,
5271 i18n("Add new web extension \"%1\" to your sidebar?",
5272 name
.isEmpty() ? name
: url
.prettyUrl()),
5273 i18n("Web Sidebar"),KGuiItem(i18n("Add")),KGuiItem(i18n("Do Not Add")));
5275 if (rc
== KMessageBox::Yes
) {
5277 if (!static_cast<KToggleAction
*>(a
)->isChecked()) {
5281 // Tell it to add a new panel
5282 MapViews::ConstIterator it
;
5283 for (it
= viewMap().constBegin(); it
!= viewMap().constEnd(); ++it
) {
5284 KonqView
*view
= it
.value();
5286 KService::Ptr svc
= view
->service();
5287 if (svc
->desktopEntryName() == "konq_sidebartng") {
5288 emit view
->browserExtension()->addWebSideBar(url
, name
);
5296 void KonqMainWindow::bookmarksIntoCompletion( const KBookmarkGroup
& group
)
5298 static const QString
& http
= KGlobal::staticQString( "http" );
5299 static const QString
& ftp
= KGlobal::staticQString( "ftp" );
5301 if ( group
.isNull() )
5304 for ( KBookmark bm
= group
.first();
5305 !bm
.isNull(); bm
= group
.next(bm
) ) {
5306 if ( bm
.isGroup() ) {
5307 bookmarksIntoCompletion( bm
.toGroup() );
5311 KUrl url
= bm
.url();
5312 if ( !url
.isValid() )
5315 QString u
= url
.prettyUrl();
5316 s_pCompletion
->addItem( u
);
5318 if ( url
.isLocalFile() )
5319 s_pCompletion
->addItem( url
.path() );
5320 else if ( url
.protocol() == http
)
5321 s_pCompletion
->addItem( u
.mid( 7 ));
5322 else if ( url
.protocol() == ftp
&&
5323 url
.host().startsWith( ftp
) )
5324 s_pCompletion
->addItem( u
.mid( 6 ) );
5329 // the smart popup completion code , <l.lunak@kde.org>
5332 // prepend http://www. or http:// if there's no protocol in 's'
5333 // used only when there are no completion matches
5334 static QString
hp_tryPrepend( const QString
& s
)
5336 if( s
.isEmpty() || s
[ 0 ] == '/' )
5339 pos
< s
.length() - 2; // 4 = ://x
5342 if( s
[ pos
] == ':' && s
[ pos
+ 1 ] == '/' && s
[ pos
+ 2 ] == '/' )
5344 if( !s
[ pos
].isLetter() )
5347 return ( s
.startsWith( "www." ) ? "http://" : "http://www." ) + s
;
5351 static void hp_removeDupe( KCompletionMatches
& l
, const QString
& dupe
,
5352 KCompletionMatches::Iterator it_orig
)
5354 KCompletionMatches::Iterator it
= it_orig
+ 1;
5355 while (it
!= l
.end()) {
5356 if( (*it
).value() == dupe
) {
5357 (*it_orig
).first
= qMax( (*it_orig
).first
, (*it
).key());
5365 // remove duplicates like 'http://www.kde.org' and 'http://www.kde.org/'
5366 // (i.e. the trailing slash)
5367 // some duplicates are also created by prepending protocols
5368 static void hp_removeDuplicates( KCompletionMatches
& l
)
5370 QString http
= "http://";
5371 QString ftp
= "ftp://ftp.";
5372 QString file
= "file:";
5373 QString file2
= "file://";
5374 l
.removeDuplicates();
5375 for( KCompletionMatches::Iterator it
= l
.begin();
5378 QString str
= (*it
).value();
5379 if( str
.startsWith( http
)) {
5380 if( str
.indexOf( '/', 7 ) < 0 ) { // http://something<noslash>
5381 hp_removeDupe( l
, str
+ '/', it
);
5382 hp_removeDupe( l
, str
.mid( 7 ) + '/', it
);
5383 } else if( str
[ str
.length() - 1 ] == '/' ) {
5384 hp_removeDupe( l
, str
.left( str
.length() - 1 ), it
);
5385 hp_removeDupe( l
, str
.left( str
.length() - 1 ).mid( 7 ), it
);
5387 hp_removeDupe( l
, str
.mid( 7 ), it
);
5389 else if( str
.startsWith( ftp
)) // ftp://ftp.
5390 hp_removeDupe( l
, str
.mid( 6 ), it
); // remove dupes without ftp://
5391 else if( str
.startsWith( file2
))
5392 hp_removeDupe( l
, str
.mid( 7 ), it
); // remove dupes without file://
5393 else if( str
.startsWith( file
))
5394 hp_removeDupe( l
, str
.mid( 5 ), it
); // remove dupes without file:
5398 static void hp_removeCommonPrefix( KCompletionMatches
& l
, const QString
& prefix
)
5400 for( KCompletionMatches::Iterator it
= l
.begin();
5403 if( (*it
).value().startsWith( prefix
)) {
5411 // don't include common prefixes like 'http://', i.e. when s == 'h', include
5412 // http://hotmail.com but don't include everything just starting with 'http://'
5413 static void hp_checkCommonPrefixes( KCompletionMatches
& matches
, const QString
& s
)
5415 static const char* const prefixes
[] = {
5426 for( const char* const *pos
= prefixes
;
5429 QString prefix
= *pos
;
5430 if( prefix
.startsWith( s
)) {
5431 hp_removeCommonPrefix( matches
, prefix
);
5436 QStringList
KonqMainWindow::historyPopupCompletionItems( const QString
& s
)
5438 const QString http
= "http://";
5439 const QString https
= "https://";
5440 const QString www
= "http://www.";
5441 const QString wwws
= "https://www.";
5442 const QString ftp
= "ftp://";
5443 const QString ftpftp
= "ftp://ftp.";
5444 const QString file
= "file:"; // without /, because people enter /usr etc.
5445 const QString file2
= "file://";
5447 return QStringList();
5448 KCompletionMatches matches
= s_pCompletion
->allWeightedMatches( s
);
5449 hp_checkCommonPrefixes( matches
, s
);
5450 bool checkDuplicates
= false;
5451 if ( !s
.startsWith( ftp
) ) {
5452 matches
+= s_pCompletion
->allWeightedMatches( ftp
+ s
);
5453 if( QString( "ftp." ).startsWith( s
))
5454 hp_removeCommonPrefix( matches
, ftpftp
);
5455 checkDuplicates
= true;
5457 if ( !s
.startsWith( https
) ) {
5458 matches
+= s_pCompletion
->allWeightedMatches( https
+ s
);
5459 if( QString( "www." ).startsWith( s
))
5460 hp_removeCommonPrefix( matches
, wwws
);
5461 checkDuplicates
= true;
5463 if ( !s
.startsWith( http
)) {
5464 matches
+= s_pCompletion
->allWeightedMatches( http
+ s
);
5465 if( QString( "www." ).startsWith( s
))
5466 hp_removeCommonPrefix( matches
, www
);
5467 checkDuplicates
= true;
5469 if ( !s
.startsWith( www
) ) {
5470 matches
+= s_pCompletion
->allWeightedMatches( www
+ s
);
5471 checkDuplicates
= true;
5473 if ( !s
.startsWith( wwws
) ) {
5474 matches
+= s_pCompletion
->allWeightedMatches( wwws
+ s
);
5475 checkDuplicates
= true;
5477 if ( !s
.startsWith( ftpftp
) ) {
5478 matches
+= s_pCompletion
->allWeightedMatches( ftpftp
+ s
);
5479 checkDuplicates
= true;
5481 if ( !s
.startsWith( file
) ) {
5482 matches
+= s_pCompletion
->allWeightedMatches( file
+ s
);
5483 checkDuplicates
= true;
5485 if ( !s
.startsWith( file2
) ) {
5486 matches
+= s_pCompletion
->allWeightedMatches( file2
+ s
);
5487 checkDuplicates
= true;
5489 if( checkDuplicates
)
5490 hp_removeDuplicates( matches
);
5491 QStringList items
= matches
.list();
5492 if( items
.count() == 0
5493 && !s
.contains( ':' ) && !s
.isEmpty() && s
[ 0 ] != '/' )
5495 QString pre
= hp_tryPrepend( s
);
5503 void KonqMainWindow::dumpViewList()
5505 kDebug(1202) << m_mapViews
.count() << "views:";
5507 MapViews::Iterator end
= m_mapViews
.end();
5508 for (MapViews::Iterator it
= m_mapViews
.begin(); it
!= end
; ++it
) {
5509 KonqView
* view
= it
.value();
5510 kDebug(1202) << view
<< view
->part();
5515 // KonqFrameContainerBase implementation BEGIN
5517 void KonqMainWindow::insertChildFrame( KonqFrameBase
* frame
, int /*index*/ )
5519 m_pChildFrame
= frame
;
5520 m_pActiveChild
= frame
;
5521 frame
->setParentContainer(this);
5522 if ( centralWidget() && centralWidget() != frame
->asQWidget() ) {
5523 centralWidget()->setParent( 0 ); // workaround Qt-4.1.2 crash (reported)
5524 setCentralWidget( 0 );
5526 setCentralWidget( frame
->asQWidget() );
5529 void KonqMainWindow::childFrameRemoved(KonqFrameBase
* frame
)
5531 Q_ASSERT(frame
== m_pChildFrame
);
5537 void KonqMainWindow::saveConfig( KConfigGroup
& config
, const QString
&prefix
, const KonqFrameBase::Options
&options
, KonqFrameBase
* docContainer
, int id
, int depth
) { if( m_pChildFrame
) m_pChildFrame
->saveConfig( config
, prefix
, options
, docContainer
, id
, depth
); }
5539 void KonqMainWindow::copyHistory( KonqFrameBase
*other
) { if( m_pChildFrame
) m_pChildFrame
->copyHistory( other
); }
5541 void KonqMainWindow::setTitle( const QString
&/*title*/ , QWidget
* /*sender*/) { return; }
5542 void KonqMainWindow::setTabIcon( const KUrl
&/*url*/, QWidget
* /*sender*/ ) { return; }
5544 QWidget
* KonqMainWindow::asQWidget() { return this; }
5546 KonqFrameBase::FrameType
KonqMainWindow::frameType() const { return KonqFrameBase::MainWindow
; }
5548 KonqFrameBase
* KonqMainWindow::childFrame()const { return m_pChildFrame
; }
5550 void KonqMainWindow::setActiveChild( KonqFrameBase
* /*activeChild*/ ) { return; }
5552 bool KonqMainWindow::isMimeTypeAssociatedWithSelf( const QString
&mimeType
)
5554 return isMimeTypeAssociatedWithSelf( mimeType
, KMimeTypeTrader::self()->preferredService( mimeType
, "Application" ) );
5557 bool KonqMainWindow::isMimeTypeAssociatedWithSelf( const QString
&/*mimeType*/, const KService::Ptr
&offer
)
5559 // Prevention against user stupidity : if the associated app for this mimetype
5560 // is konqueror/kfmclient, then we'll loop forever. So we have to
5561 // 1) force embedding first, if that works we're ok
5562 // 2) check what KRun is going to do before calling it.
5563 return ( offer
&& ( offer
->desktopEntryName() == "konqueror" ||
5564 offer
->exec().trimmed().startsWith( "kfmclient" ) ) );
5567 bool KonqMainWindow::refuseExecutingKonqueror(const QString
& mimeType
)
5569 if ( activeViewsNotLockedCount() > 0 ) { // if I lock the only view, then there's no error: open links in a new window
5570 KMessageBox::error( this, i18n("There appears to be a configuration error. You have associated Konqueror with %1, but it cannot handle this file type.", mimeType
));
5571 return true; // we refuse indeed
5573 return false; // no error
5576 // KonqFrameContainerBase implementation END
5578 void KonqMainWindow::setPreloadedFlag( bool preloaded
)
5580 if( s_preloaded
== preloaded
)
5582 s_preloaded
= preloaded
;
5585 kapp
->disableSessionManagement(); // don't restore preloaded konqy's
5586 KonqSessionManager::self()->disableAutosave(); // don't save sessions
5587 return; // was registered before calling this
5589 delete s_preloadedWindow
; // preloaded state was abandoned without reusing the window
5590 s_preloadedWindow
= NULL
;
5591 kapp
->enableSessionManagement(); // enable SM again
5592 KonqSessionManager::self()->enableAutosave(); // enable session saving again
5593 QDBusInterface
ref( "org.kde.kded", "/modules/konqy_preloader", "org.kde.konqueror.Preloader", QDBusConnection::sessionBus() );
5594 ref
.call( "unregisterPreloadedKonqy", QDBusConnection::sessionBus().baseService() );
5597 void KonqMainWindow::setPreloadedWindow( KonqMainWindow
* window
)
5599 s_preloadedWindow
= window
;
5600 if( window
== NULL
)
5602 window
->viewManager()->clear();
5603 KIO::Scheduler::unregisterWindow( window
);
5606 // used by preloading - this KonqMainWindow will be reused, reset everything
5607 // that won't be reset by loading a profile
5608 void KonqMainWindow::resetWindow()
5612 // empty append to get current X timestamp
5614 XChangeProperty( QX11Info::display(), tmp_widget
.winId(), XA_WM_CLASS
, XA_STRING
, 8,
5615 PropModeAppend
, (unsigned char*) &data
, 0 );
5617 XWindowEvent( QX11Info::display(), tmp_widget
.winId(), PropertyChangeMask
, &ev
);
5618 long x_time
= ev
.xproperty
.time
;
5619 // bad hack - without updating the _KDE_NET_WM_USER_CREATION_TIME property,
5620 // KWin will apply don't_steal_focus to this window, and will not make it active
5621 // (shows mainly with 'konqueror --preload')
5622 static Atom atom
= XInternAtom( QX11Info::display(), "_KDE_NET_WM_USER_CREATION_TIME", False
);
5623 XChangeProperty( QX11Info::display(), winId(), atom
, XA_CARDINAL
, 32,
5624 PropModeReplace
, (unsigned char *) &x_time
, 1);
5625 // reset also user time, so that this window won't have _NET_WM_USER_TIME set
5626 QX11Info::setAppUserTime(CurrentTime
);
5628 static Atom atom3
= XInternAtom( QX11Info::display(), "_NET_WM_USER_TIME", False
);
5629 XDeleteProperty( QX11Info::display(), winId(), atom3
);
5631 // Qt remembers the iconic state if the window was withdrawn while on another virtual desktop
5632 setWindowState( windowState() & ~Qt::WindowMinimized
);
5633 ignoreInitialGeometry();
5636 bool KonqMainWindow::event( QEvent
* e
)
5638 if( e
->type() == QEvent::DeferredDelete
)
5640 // since the preloading code tries to reuse KonqMainWindow,
5641 // the last window shouldn't be really deleted, but only hidden
5642 // deleting WDestructiveClose windows is done using deleteLater(),
5643 // so catch QEvent::DeferredDelete and check if this window should stay
5644 if( stayPreloaded())
5646 setAttribute(Qt::WA_DeleteOnClose
); // was reset before deleteLater()
5647 return true; // no deleting
5650 } else if ( e
->type() == QEvent::StatusTip
) {
5651 if (m_currentView
&& m_currentView
->frame()->statusbar()) {
5652 KonqFrameStatusBar
*statusBar
= m_currentView
->frame()->statusbar();
5653 statusBar
->message(static_cast<QStatusTipEvent
*>(e
)->tip());
5657 if ( KonqFileSelectionEvent::test( e
) ||
5658 KonqFileMouseOverEvent::test( e
) )
5660 // Forward the event to all views
5661 MapViews::ConstIterator it
= m_mapViews
.constBegin();
5662 MapViews::ConstIterator end
= m_mapViews
.constEnd();
5663 for (; it
!= end
; ++it
)
5664 QApplication::sendEvent( (*it
)->part(), e
);
5667 if ( KParts::OpenUrlEvent::test( e
) )
5669 KParts::OpenUrlEvent
* ev
= static_cast<KParts::OpenUrlEvent
*>(e
);
5671 // Forward the event to all views
5672 MapViews::ConstIterator it
= m_mapViews
.constBegin();
5673 MapViews::ConstIterator end
= m_mapViews
.constEnd();
5674 for (; it
!= end
; ++it
)
5676 // Don't resend to sender
5677 if (it
.key() != ev
->part())
5679 //kDebug(1202) << "Sending event to view" << it.key()->metaObject()->className();
5680 QApplication::sendEvent( it
.key(), e
);
5684 return KParts::MainWindow::event( e
);
5687 bool KonqMainWindow::stayPreloaded()
5691 if( mainWindowList()->count() > 1 )
5693 // not running in full KDE environment?
5694 if( getenv( "KDE_FULL_SESSION" ) == NULL
|| getenv( "KDE_FULL_SESSION" )[ 0 ] == '\0' )
5696 // not the same user like the one running the session (most likely we're run via sudo or something)
5697 if( getenv( "KDE_SESSION_UID" ) != NULL
&& uid_t( atoi( getenv( "KDE_SESSION_UID" ))) != getuid())
5699 if( KonqSettings::maxPreloadCount() == 0 )
5701 viewManager()->clear(); // reduce resource usage before checking it
5702 if( !checkPreloadResourceUsage())
5704 QDBusInterface
ref( "org.kde.kded", "/modules/konqy_preloader", "org.kde.konqueror.Preloader", QDBusConnection::sessionBus() );
5706 QDBusReply
<bool> retVal
= ref
.call( QDBus::Block
, "registerPreloadedKonqy", QDBusConnection::sessionBus().baseService(), info
.screen());
5711 KonqMainWindow::setPreloadedFlag( true );
5712 kDebug(1202) << "Konqy kept for preloading:" << QDBusConnection::sessionBus().baseService();
5713 KonqMainWindow::setPreloadedWindow( this );
5720 // try to avoid staying running when leaking too much memory
5721 // this is checked by using mallinfo() and comparing
5722 // memory usage during konqy startup and now, if the difference
5723 // is too large -> leaks -> quit
5724 // also, if this process is running for too long, or has been
5725 // already reused too many times -> quit, just in case
5726 bool KonqMainWindow::checkPreloadResourceUsage()
5730 isatty( STDIN_FILENO
) ||
5732 isatty( STDOUT_FILENO
) || isatty( STDERR_FILENO
))
5734 kDebug(1202) << "Running from tty, not keeping for preloading";
5738 int usage
= current_memory_usage( &limit
);
5739 kDebug(1202) << "Memory usage increase: " << ( usage
- s_initialMemoryUsage
)
5740 << " (" << usage
<< "/" << s_initialMemoryUsage
<< "), increase limit: " << limit
;
5741 int max_allowed_usage
= s_initialMemoryUsage
+ limit
;
5742 if( usage
> max_allowed_usage
) // too much memory used?
5744 kDebug(1202) << "Not keeping for preloading due to high memory usage";
5747 // working memory usage test ( usage != 0 ) makes others less strict
5748 if( ++s_preloadUsageCount
> ( usage
!= 0 ? 100 : 10 )) // reused too many times?
5750 kDebug(1202) << "Not keeping for preloading due to high usage count";
5753 if( time( NULL
) > s_startupTime
+ 60 * 60 * ( usage
!= 0 ? 4 : 1 )) // running for too long?
5755 kDebug(1202) << "Not keeping for preloading due to long usage time";
5761 static int current_memory_usage( int* limit
)
5763 #ifdef __linux__ //krazy:exclude=cpp
5764 // Check whole memory usage - VmSize
5765 QFile
f( QString::fromLatin1( "/proc/%1/statm" ).arg(getpid()) );
5766 if( f
.open( QIODevice::ReadOnly
))
5768 QByteArray buffer
; buffer
.resize( 100 );
5769 const int bytes
= f
.readLine( buffer
.data(), buffer
.size()-1 );
5772 QString line
= QString::fromLatin1( buffer
).trimmed();
5773 const int usage
= line
.section( ' ', 0, 0 ).toInt();
5776 int pagesize
= sysconf (_SC_PAGE_SIZE
);
5780 *limit
= 16 * 1024 * 1024;
5781 return usage
* pagesize
;
5785 kWarning() << "Couldn't read VmSize from /proc/*/statm." ;
5787 // Check malloc() usage - very imprecise, but better than nothing.
5789 #if defined(KDE_MALLINFO_STDLIB) || defined(KDE_MALLINFO_MALLOC)
5790 struct mallinfo m
= mallinfo();
5791 #ifdef KDE_MALLINFO_FIELD_hblkhd
5792 usage_sum
+= m
.hblkhd
;
5794 #ifdef KDE_MALLINFO_FIELD_uordblks
5795 usage_sum
+= m
.uordblks
;
5797 #ifdef KDE_MALLINFO_FIELD_usmblks
5798 usage_sum
+= m
.usmblks
;
5800 // unlike /proc , this doesn't include things like size of dlopened modules,
5801 // and also doesn't include malloc overhead
5803 *limit
= 6 * 1024 * 1024;
5808 void KonqMainWindow::slotUndoTextChanged( const QString
& newText
)
5810 m_paUndo
->setText(newText
);
5813 // outlined because of QPointer and gcc3
5814 KonqView
* KonqMainWindow::currentView() const
5816 return m_currentView
;
5819 bool KonqMainWindow::accept( KonqFrameVisitor
* visitor
)
5821 if ( !visitor
->visit( this ) )
5823 if ( m_pChildFrame
&& !m_pChildFrame
->accept( visitor
) )
5825 if ( !visitor
->endVisit( this ) )
5830 bool KonqMainWindow::hasViewWithMimeType(const QString
& mimeType
) const
5832 MapViews::const_iterator it
= m_mapViews
.constBegin();
5833 const MapViews::const_iterator end
= m_mapViews
.constEnd();
5834 for (; it
!= end
; ++it
) {
5835 if ((*it
)->supportsMimeType(mimeType
)) {
5836 //kDebug(1202) << *it << "supports" << mimeType << "!";
5843 void KonqMainWindow::applyWindowSizeFromProfile(const KConfigGroup
& profileGroup
)
5845 // KMainWindow::restoreWindowSize is protected so this logic can't move to KonqViewManager
5846 const QSize size
= KonqViewManager::readDefaultSize(profileGroup
, this); // example: "Width=80%"
5849 restoreWindowSize(profileGroup
); // example: "Width 1400=1120"
5852 #include "konqmainwindow.moc"