/* This file is part of the KDE project Copyright (C) 1998, 1999 Simon Hausmann Copyright (C) 2000 Carsten Pfeiffer Copyright (C) 2000-2005 David Faure This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "konq_mainwindow.h" #include "konq_guiclients.h" #include "KonqMainWindowIface.h" #include "konq_view.h" #include "konq_run.h" #include "konq_misc.h" #include "konq_viewmgr.h" #include "konq_frame.h" #include "konq_tabs.h" #include "konq_events.h" #include "konq_actions.h" #include "konq_settingsxt.h" #include "konq_extensionmanager.h" #include "delayedinitializer.h" #include #include #include #include #include #include #include // we define STRICT_ANSI to get rid of some warnings in glibc #ifndef __STRICT_ANSI__ #define __STRICT_ANSI__ #define _WE_DEFINED_IT_ #endif #include #ifdef _WE_DEFINED_IT_ #undef __STRICT_ANSI__ #undef _WE_DEFINED_IT_ #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "konq_main.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef KDE_MALLINFO_STDLIB #include #endif #ifdef KDE_MALLINFO_MALLOC #include #endif #include #include #include #include template class TQPtrList; template class TQPtrList; TQPtrList *KonqMainWindow::s_lstViews = 0; KConfig * KonqMainWindow::s_comboConfig = 0; KCompletion * KonqMainWindow::s_pCompletion = 0; TQFile * KonqMainWindow::s_crashlog_file = 0; bool KonqMainWindow::s_preloaded = false; KonqMainWindow* KonqMainWindow::s_preloadedWindow = 0; int KonqMainWindow::s_initialMemoryUsage = -1; time_t KonqMainWindow::s_startupTime; int KonqMainWindow::s_preloadUsageCount; KonqOpenURLRequest KonqOpenURLRequest::null; static int current_memory_usage( int* limit = NULL ); #include "konq_mainwindow_p.h" KonqExtendedBookmarkOwner::KonqExtendedBookmarkOwner(KonqMainWindow *w) { m_pKonqMainWindow = w; } KonqMainWindow::KonqMainWindow( const KURL &initialURL, bool openInitialURL, const char *name, const TQString& xmluiFile) : KParts::MainWindow( NoDCOPObject, 0L, name, WDestructiveClose | WStyle_ContextHelp | Qt::WGroupLeader ) { setPreloadedFlag( false ); if ( !s_lstViews ) s_lstViews = new TQPtrList; s_lstViews->append( this ); m_urlCompletionStarted = false; m_currentView = 0L; m_pChildFrame = 0L; m_pActiveChild = 0L; m_pWorkingTab = 0L; m_initialKonqRun = 0L; m_pBookmarkMenu = 0L; m_dcopObject = new KonqMainWindowIface( this ); m_combo = 0L; m_bURLEnterLock = false; m_bLocationBarConnected = false; m_paBookmarkBar = 0L; m_pURLCompletion = 0L; m_goBuffer = 0; m_configureDialog = 0L; m_bViewModeToggled = false; m_prevMenuBarVisible = true; m_pViewManager = new KonqViewManager( this ); m_toggleViewGUIClient = new ToggleViewGUIClient( this ); m_openWithActions.setAutoDelete( true ); m_viewModeActions.setAutoDelete( true ); m_toolBarViewModeActions.setAutoDelete( true ); m_viewModeMenu = 0; m_paCopyFiles = 0; m_paMoveFiles = 0; m_paDelete = 0; m_paNewDir = 0; m_bookmarkBarActionCollection = 0L; KonqExtendedBookmarkOwner *extOwner = new KonqExtendedBookmarkOwner( this ); m_pBookmarksOwner = extOwner; connect( extOwner, TQT_SIGNAL( signalFillBookmarksList(KExtendedBookmarkOwner::QStringPairList &) ), extOwner, TQT_SLOT( slotFillBookmarksList(KExtendedBookmarkOwner::QStringPairList &) ) ); // init history-manager, load history, get completion object if ( !s_pCompletion ) { KonqHistoryManager *mgr = new KonqHistoryManager( kapp, "history mgr" ); s_pCompletion = mgr->completionObject(); // setup the completion object before createGUI(), so that the combo // picks up the correct mode from the HistoryManager (in slotComboPlugged) int mode = KonqSettings::settingsCompletionMode(); s_pCompletion->setCompletionMode( (KGlobalSettings::Completion) mode ); } connect(KParts::HistoryProvider::self(), TQT_SIGNAL(cleared()), TQT_SLOT(slotClearComboHistory())); KonqPixmapProvider *prov = KonqPixmapProvider::self(); if ( !s_comboConfig ) { s_comboConfig = new KConfig( "konq_history", false, false ); KonqCombo::setConfig( s_comboConfig ); s_comboConfig->setGroup( "Location Bar" ); prov->load( s_comboConfig, "ComboIconCache" ); } connect( prov, TQT_SIGNAL( changed() ), TQT_SLOT( slotIconsChanged() ) ); initCombo(); initActions(); setInstance( KGlobal::instance() ); connect( KSycoca::self(), TQT_SIGNAL( databaseChanged() ), this, TQT_SLOT( slotDatabaseChanged() ) ); connect( kapp, TQT_SIGNAL( kdisplayFontChanged()), TQT_SLOT(slotReconfigure())); //load the xmlui file specified in the profile or the default konqueror.rc setXMLFile( xmluiFile ); setStandardToolBarMenuEnabled( true ); createGUI( 0L ); connect(toolBarMenuAction(),TQT_SIGNAL(activated()),this,TQT_SLOT(slotForceSaveMainWindowSettings()) ); if ( !m_toggleViewGUIClient->empty() ) plugActionList( TQString::tqfromLatin1( "toggleview" ), m_toggleViewGUIClient->actions() ); else { delete m_toggleViewGUIClient; m_toggleViewGUIClient = 0; } // Those menus are created by konqueror.rc so their address will never change TQPopupMenu *popup = static_cast(factory()->container("edit",this)); if (popup) KAcceleratorManager::manage(popup); popup = static_cast(factory()->container("tools",this)); if (popup) KAcceleratorManager::manage(popup); m_bSaveViewPropertiesLocally = KonqSettings::saveViewPropertiesLocally(); m_bHTMLAllowed = KonqSettings::htmlAllowed(); m_ptaUseHTML->setChecked( m_bHTMLAllowed ); m_paSaveViewPropertiesLocally->setChecked( m_bSaveViewPropertiesLocally ); KonqUndoManager::incRef(); connect( KonqUndoManager::self(), TQT_SIGNAL( undoAvailable( bool ) ), this, TQT_SLOT( slotUndoAvailable( bool ) ) ); m_bNeedApplyKonqMainWindowSettings = true; if ( !initialURL.isEmpty() ) { openFilteredURL( initialURL.url() ); } else if ( openInitialURL ) { KURL homeURL; homeURL.setPath( TQDir::homeDirPath() ); openURL( 0L, homeURL ); } else // silent m_bNeedApplyKonqMainWindowSettings = false; // Read basic main-view settings, and set to autosave setAutoSaveSettings( "KonqMainWindow", false ); if ( !initialGeometrySet() ) resize( 700, 480 ); //kdDebug(1202) << "KonqMainWindow::KonqMainWindow " << this << " done" << endl; if( s_initialMemoryUsage == -1 ) { s_initialMemoryUsage = current_memory_usage(); s_startupTime = time( NULL ); s_preloadUsageCount = 0; } } KonqMainWindow::~KonqMainWindow() { kdDebug(1202) << "KonqMainWindow::~KonqMainWindow " << this << endl; delete m_pViewManager; if ( s_lstViews ) { s_lstViews->removeRef( this ); if ( s_lstViews->count() == 0 ) { delete s_lstViews; s_lstViews = 0; } } disconnectActionCollection( actionCollection() ); saveToolBarServicesMap(); // createShellGUI( false ); delete m_pBookmarkMenu; delete m_paBookmarkBar; delete m_pBookmarksOwner; delete m_pURLCompletion; m_viewModeActions.clear(); KonqUndoManager::decRef(); if ( s_lstViews == 0 ) { delete KonqPixmapProvider::self(); delete s_comboConfig; s_comboConfig = 0L; } delete m_configureDialog; m_configureDialog = 0L; delete m_dcopObject; m_dcopObject = 0L; delete m_combo; m_combo = 0L; delete m_locationLabel; m_locationLabel = 0L; kdDebug(1202) << "KonqMainWindow::~KonqMainWindow " << this << " done" << endl; } TQWidget * KonqMainWindow::createContainer( TQWidget *parent, int index, const TQDomElement &element, int &id ) { static TQString nameBookmarkBar = TQString::tqfromLatin1( "bookmarkToolBar" ); static TQString tagToolBar = TQString::tqfromLatin1( "ToolBar" ); TQWidget *res = KParts::MainWindow::createContainer( parent, index, element, id ); if ( res && (element.tagName() == tagToolBar) && (element.attribute( "name" ) == nameBookmarkBar) ) { assert( res->inherits( "KToolBar" ) ); if (!kapp->authorizeKAction("bookmarks")) { delete res; return 0; } if ( !m_bookmarkBarActionCollection ) { // The actual menu needs a different action collection, so that the bookmarks // don't appear in kedittoolbar m_bookmarkBarActionCollection = new KActionCollection( this ); m_bookmarkBarActionCollection->setHighlightingEnabled( true ); connectActionCollection( m_bookmarkBarActionCollection ); DelayedInitializer *initializer = new DelayedInitializer( TQEvent::Show, res ); connect( initializer, TQT_SIGNAL( initialize() ), this, TQT_SLOT(initBookmarkBar()) ); } } return res; } void KonqMainWindow::initBookmarkBar() { KToolBar * bar = static_cast( child( "bookmarkToolBar", "KToolBar" ) ); if (!bar) return; delete m_paBookmarkBar; m_paBookmarkBar = new KBookmarkBar( KonqBookmarkManager::self(), m_pBookmarksOwner, bar, m_bookmarkBarActionCollection, this ); connect( m_paBookmarkBar, TQT_SIGNAL( aboutToShowContextMenu(const KBookmark &, TQPopupMenu*) ), this, TQT_SLOT( slotFillContextMenu(const KBookmark &, TQPopupMenu*) )); connect( m_paBookmarkBar, TQT_SIGNAL( openBookmark(const TQString &, Qt::ButtonState) ), this, TQT_SLOT( slotOpenBookmarkURL(const TQString &, Qt::ButtonState) )); // hide if empty if (bar->count() == 0 ) bar->hide(); } void KonqMainWindow::removeContainer( TQWidget *container, TQWidget *parent, TQDomElement &element, int id ) { static TQString nameBookmarkBar = TQString::tqfromLatin1( "bookmarkToolBar" ); static TQString tagToolBar = TQString::tqfromLatin1( "ToolBar" ); if ( element.tagName() == tagToolBar && element.attribute( "name" ) == nameBookmarkBar ) { assert( container->inherits( "KToolBar" ) ); if (m_paBookmarkBar) m_paBookmarkBar->clear(); } KParts::MainWindow::removeContainer( container, parent, element, id ); } // Detect a name filter (e.g. *.txt) in the url. // Note that KShortURIFilter does the same, but we have no way of getting it from there // // Note: this removes the filter from the URL. static TQString detectNameFilter( KURL & url ) { if ( !KProtocolInfo::supportsListing(url) ) return TQString::null; // Look for wildcard selection TQString nameFilter; TQString path = url.path(); int lastSlash = path.findRev( '/' ); if ( lastSlash > -1 ) { if ( !url.query().isEmpty() && lastSlash == (int)path.length()-1 ) { // In /tmp/?foo, foo isn't a query path += url.query(); // includes the '?' url.setQuery( TQString::null ); } const TQString fileName = path.mid( lastSlash + 1 ); if ( fileName.find( '*' ) != -1 || fileName.find( '[' ) != -1 || fileName.find( '?' ) != -1 ) { // Check that a file or dir with all the special chars in the filename doesn't exist if ( url.isLocalFile() ? !TQFile::exists( path ) : !KIO::NetAccess::exists( url, false, 0 ) ) { nameFilter = fileName; url.setFileName( TQString::null ); kdDebug(1202) << "Found wildcard. nameFilter=" << nameFilter << " New url=" << url << endl; } } } return nameFilter; } void KonqMainWindow::openFilteredURL( const TQString & url, KonqOpenURLRequest & req ) { // Filter URL to build a correct one if (m_currentDir.isEmpty() && m_currentView) m_currentDir = m_currentView->url().path(1); KURL filteredURL ( KonqMisc::konqFilteredURL( this, url, m_currentDir ) ); kdDebug(1202) << "url " << url << " filtered into " << filteredURL.prettyURL() << endl; if ( filteredURL.isEmpty() ) // initially empty, or error (e.g. ~unknown_user) return; m_currentDir = TQString::null; openURL( 0L, filteredURL, TQString::null, req ); // #4070: Give focus to view after URL was entered manually // Note: we do it here if the view mode (i.e. part) wasn't changed // If it is changed, then it's done in KonqView::changeViewMode if ( m_currentView && m_currentView->part() ) m_currentView->part()->widget()->setFocus(); } void KonqMainWindow::openFilteredURL( const TQString & _url, bool inNewTab, bool tempFile ) { KonqOpenURLRequest req( _url ); req.newTab = inNewTab; req.newTabInFront = true; req.tempFile = tempFile; openFilteredURL( _url, req ); } void KonqMainWindow::openURL( KonqView *_view, const KURL &_url, const TQString &_serviceType, KonqOpenURLRequest& req, bool trustedSource ) { #ifndef NDEBUG // needed for req.debug() kdDebug(1202) << "KonqMainWindow::openURL : url = '" << _url << "' " << "serviceType='" << _serviceType << "' req=" << req.debug() << " view=" << _view << endl; #endif KURL url( _url ); if (url.url().startsWith("$(")) { // check for environment variables and make necessary translations TQString aValue = url.url(); int nDollarPos = aValue.find( '$' ); while( nDollarPos != -1 && nDollarPos+1 < static_cast(aValue.length())) { // there is at least one $ if( (aValue)[nDollarPos+1] == '(' ) { uint nEndPos = nDollarPos+1; // the next character is no $ while ( (nEndPos <= aValue.length()) && (aValue[nEndPos]!=')') ) nEndPos++; nEndPos++; TQString cmd = aValue.mid( nDollarPos+2, nEndPos-nDollarPos-3 ); TQString result; FILE *fs = popen(TQFile::encodeName(cmd).data(), "r"); if (fs) { { TQTextStream ts(fs, IO_ReadOnly); result = ts.read().stripWhiteSpace(); } pclose(fs); } aValue.tqreplace( nDollarPos, nEndPos-nDollarPos, result ); } else if( (aValue)[nDollarPos+1] != '$' ) { uint nEndPos = nDollarPos+1; // the next character is no $ TQString aVarName; if (aValue[nEndPos]=='{') { while ( (nEndPos <= aValue.length()) && (aValue[nEndPos]!='}') ) nEndPos++; nEndPos++; aVarName = aValue.mid( nDollarPos+2, nEndPos-nDollarPos-3 ); } else { while ( nEndPos <= aValue.length() && (aValue[nEndPos].isNumber() || aValue[nEndPos].isLetter() || aValue[nEndPos]=='_' ) ) nEndPos++; aVarName = aValue.mid( nDollarPos+1, nEndPos-nDollarPos-1 ); } const char* pEnv = 0; if (!aVarName.isEmpty()) pEnv = getenv( aVarName.ascii() ); if( pEnv ) { // !!! Sergey A. Sukiyazov !!! // A environment variables may contain values in 8bit // locale cpecified encoding or in UTF8 encoding. aValue.tqreplace( nDollarPos, nEndPos-nDollarPos, KStringHandler::from8Bit( pEnv ) ); } else aValue.remove( nDollarPos, nEndPos-nDollarPos ); } else { // remove one of the dollar signs aValue.remove( nDollarPos, 1 ); nDollarPos++; } nDollarPos = aValue.find( '$', nDollarPos ); } url = KURL(aValue); } TQString serviceType( _serviceType ); if ( url.url() == "about:blank" ) { serviceType = "text/html"; } else if ( !url.isValid() ) { KMessageBox::error(0, i18n("Malformed URL\n%1").arg(url.url())); return; } else if ( !KProtocolInfo::isKnownProtocol( url ) && url.protocol() != "about" ) { KMessageBox::error(0, i18n("Protocol not supported\n%1").arg(url.protocol())); return; } TQString nameFilter = detectNameFilter( url ); if ( !nameFilter.isEmpty() ) { req.nameFilter = nameFilter; url.setFileName( TQString::null ); } KonqView *view = _view; // When clicking a 'follow active' view (e.g. view is the sidebar), // open the URL in the active view if ( view && view->isFollowActive() ) view = m_currentView; if ( !view && !req.newTab ) view = m_currentView; /* Note, this can be 0L, e.g. on startup */ else if ( !view && req.newTab ) { view = m_pViewManager->addTab(TQString::null, TQString::null, false, req.openAfterCurrentPage); if (view) { view->setCaption( _url.host() ); view->setLocationBarURL( _url ); if ( !req.args.frameName.isEmpty() ) view->setViewName( req.args.frameName ); // #44961 if ( req.newTabInFront ) m_pViewManager->showTab( view ); updateViewActions(); //A new tab created -- we may need to enable the "remove tab" button (#56318) } else req.newTab = false; } const TQString oldLocationBarURL = m_combo->currentText(); if ( view ) { if ( view == m_currentView ) { //will do all the stuff below plus GUI stuff abortLoading(); } else { view->stop(); // Don't change location bar if not current view } } // Fast mode for local files: do the stat ourselves instead of letting KRun do it. if ( serviceType.isEmpty() && url.isLocalFile() ) { TQCString _path( TQFile::encodeName(url.path())); KDE_struct_stat buff; if ( KDE_stat( _path.data(), &buff ) != -1 ) serviceType = KMimeType::findByURL( url, buff.st_mode )->name(); } kdDebug(1202) << "trying openView for " << url << " (serviceType " << serviceType << ")" << endl; if ( ( !serviceType.isEmpty() && serviceType != "application/octet-stream") || url.url().startsWith("about:konqueror") || url.url() == "about:plugins" ) { KService::Ptr offer = KServiceTypeProfile::preferredService(serviceType, "Application"); // If the associated app is konqueror itself, then make sure we try to embed before bailing out. if ( isMimeTypeAssociatedWithSelf( serviceType, offer ) ) req.forceAutoEmbed = true; // Built-in view ? if ( !openView( serviceType, url, view /* can be 0L */, req ) ) { //kdDebug(1202) << "KonqMainWindow::openURL : openView returned false" << endl; // Are we following another view ? Then forget about this URL. Otherwise fire app. if ( !req.followMode ) { //kdDebug(1202) << "KonqMainWindow::openURL : we were not following. Fire app." << endl; // We know the servicetype, let's try its preferred service if ( isMimeTypeAssociatedWithSelf( serviceType, offer ) ) { KMessageBox::error( this, i18n("There appears to be a configuration error. You have associated Konqueror with %1, but it cannot handle this file type.").arg(serviceType)); return; } if ( !url.isLocalFile() && KonqRun::isTextExecutable( serviceType ) ) serviceType = "text/plain"; // view, don't execute // Remote URL: save or open ? TQString protClass = KProtocolInfo::protocolClass(url.protocol()); bool open = url.isLocalFile() || protClass==":local"; if ( !open ) { KParts::BrowserRun::AskSaveResult res = KonqRun::askSave( url, offer, serviceType ); if ( res == KParts::BrowserRun::Save ) KParts::BrowserRun::simpleSave( url, TQString::null, this ); open = ( res == KParts::BrowserRun::Open ); } if ( open ) { KURL::List lst; lst.append(url); //kdDebug(1202) << "Got offer " << (offer ? offer->name().latin1() : "0") << endl; if ( ( trustedSource || KonqRun::allowExecution( serviceType, url ) ) && ( KonqRun::isExecutable( serviceType ) || !offer || !KRun::run( *offer, lst ) ) ) { setLocationBarURL( oldLocationBarURL ); // Revert to previous locationbar URL (void)new KRun( url, this ); } } } } } else // no known serviceType, use KonqRun { if ( ( !view || view->url().isEmpty() ) && !req.newTab ) // startup with argument { // Show it for now in the location bar, but we'll need to store it in the view // later on (can't do it yet since either view == 0 or updateHistoryEntry will be called). kdDebug(1202) << "setLocationBarURL (startup) : url = " << url << endl; setLocationBarURL( url ); } kdDebug(1202) << "Creating new konqrun for " << url << " req.typedURL=" << req.typedURL << endl; KonqRun * run = new KonqRun( this, view /* can be 0L */, url, req, trustedSource ); // Never start in external browser run->setEnableExternalBrowser(false); if ( view ) view->setRun( run ); else if ( !req.newTab ) { // there can be only one :) (when not a new tab) delete m_initialKonqRun; m_initialKonqRun = run; } if ( view == m_currentView ) startAnimation(); connect( run, TQT_SIGNAL( finished() ), this, TQT_SLOT( slotRunFinished() ) ); } } bool KonqMainWindow::openView( TQString serviceType, const KURL &_url, KonqView *childView, KonqOpenURLRequest& req ) { // Second argument is referring URL if ( !kapp->authorizeURLAction("open", childView ? childView->url() : KURL(), _url) ) { TQString msg = KIO::buildErrorString(KIO::ERR_ACCESS_DENIED, _url.prettyURL()); KMessageBox::queuedMessageBox( this, KMessageBox::Error, msg ); return true; // Nothing else to do. } if ( KonqRun::isExecutable( serviceType ) ) return false; // execute, don't open // Contract: the caller of this method should ensure the view is stopped first. #ifndef NDEBUG kdDebug(1202) << "KonqMainWindow::openView " << serviceType << " " << _url << " " << childView << " req:" << req.debug() << endl; #endif bool bOthersFollowed = false; if ( childView ) { // If we're not already following another view (and if we are not reloading) if ( !req.followMode && !req.args.reload && !m_pViewManager->isLoadingProfile() ) { // When clicking a 'follow active' view (e.g. childView is the sidebar), // open the URL in the active view // (it won't do anything itself, since it's locked to its location) if ( childView->isFollowActive() && childView != m_currentView ) { abortLoading(); setLocationBarURL( _url ); KonqOpenURLRequest newreq; newreq.followMode = true; newreq.args = req.args; bOthersFollowed = openView( serviceType, _url, m_currentView, newreq ); } // "link views" feature, and "sidebar follows active view" feature bOthersFollowed = makeViewsFollow(_url, req.args, serviceType, childView) || bOthersFollowed; } if ( childView->isLockedLocation() && !req.args.reload /* allow to reload a locked view*/ ) return bOthersFollowed; } TQString indexFile; KURL url( _url ); // Generic mechanism for redirecting to tar:// when clicking on a tar file, // zip:// when clicking on a zip file, etc. // The name of the protocol to redirect to, is read from the mimetype's .desktop file if ( url.isLocalFile() ) { KServiceType::Ptr ptr = KServiceType::serviceType( serviceType ); if ( ptr ) { const TQString protocol = ptr->property("X-KDE-LocalProtocol").toString(); if ( !protocol.isEmpty() && KonqFMSettings::settings()->shouldEmbed( serviceType ) ) { url.setProtocol( protocol ); if ( serviceType == "application/x-webarchive" ) { url.setPath( url.path() + "/index.html" ); serviceType = "text/html"; } else { url.setPath( url.path() + '/' ); serviceType = "inode/directory"; } } } } /////////// // In case we open an index.html, we want the location bar // to still display the original URL (so that 'up' uses that URL, // and since that's what the user entered). // changeViewMode will take care of setting and storing that url. TQString originalURL = url.pathOrURL(); if ( !req.nameFilter.isEmpty() ) // keep filter in location bar { if (!originalURL.endsWith("/")) originalURL += '/'; originalURL += req.nameFilter; } TQString serviceName; // default: none provided if ( url.url().startsWith("about:konqueror") || url.url() == "about:plugins" ) { serviceType = "KonqAboutPage"; // not KParts/ReadOnlyPart, it fills the Location menu ! :) serviceName = "konq_aboutpage"; originalURL = req.typedURL.isEmpty() ? TQString::null : url.url(); // empty if from profile, about:konqueror if the user typed it (not req.typedURL, it could be "about:") } else if ( url.url() == "about:blank" && req.typedURL.isEmpty() ) { originalURL = TQString::null; } // Look for which view mode to use, if a directory - not if view locked if ( ( !childView || (!childView->isLockedViewMode()) ) && serviceType == "inode/directory" ) { // Phew ! // Set view mode if necessary (current view doesn't support directories) if ( !childView || !childView->supportsServiceType( serviceType ) ) serviceName = KonqSettings::mainViewViewMode(); if ( url.isLocalFile() ) // local, we can do better (.directory) { // Read it in the .directory file, default to m_bHTMLAllowed KURL urlDotDir( url ); urlDotDir.addPath(".directory"); bool HTMLAllowed = m_bHTMLAllowed; TQFile f( urlDotDir.path() ); if ( f.open(IO_ReadOnly) ) { f.close(); KSimpleConfig config( urlDotDir.path(), true ); config.setGroup( "URL properties" ); HTMLAllowed = config.readBoolEntry( "HTMLAllowed", m_bHTMLAllowed ); serviceName = config.readEntry( "ViewMode", serviceName ); kdDebug(1202) << "serviceName=" << serviceName << endl; } if ( HTMLAllowed && ( ( indexFile = findIndexFile( url.path() ) ) != TQString::null ) ) { serviceType = "text/html"; url = KURL(); url.setPath( indexFile ); serviceName = TQString::null; // cancel what we just set, this is not a dir finally } // Reflect this setting in the menu m_ptaUseHTML->setChecked( HTMLAllowed ); } } bool ok = true; if ( !childView ) { if (req.newTab) { KonqFrameTabs* tabContainer = 0L; int index = 0; if ( m_pViewManager->docContainer() && m_pViewManager->docContainer()->frameType() == "Tabs") { tabContainer = static_cast(m_pViewManager->docContainer()); index = tabContainer->currentPageIndex(); } childView = m_pViewManager->addTab( serviceType, serviceName, false, req.openAfterCurrentPage ); if (req.newTabInFront && childView) { if ( !tabContainer ) tabContainer = static_cast(m_pViewManager->docContainer()); if ( req.openAfterCurrentPage ) tabContainer->setCurrentPage( index + 1 ); else tabContainer->setCurrentPage( tabContainer->count()-1 ); } } else { // Create a new view // Initialize always uses force auto-embed even if user setting is "separate viewer", // since this window has no view yet - we don't want to keep an empty mainwindow. // This can happen with e.g. application/pdf from a target="_blank" link, or window.open. childView = m_pViewManager->Initialize( serviceType, serviceName ); if ( childView ) { enableAllActions( true ); m_currentView = childView; } } if ( !childView ) return false; // It didn't work out. childView->setViewName( m_initialFrameName.isEmpty() ? req.args.frameName : m_initialFrameName ); m_initialFrameName = TQString::null; } else // We know the child view { if ( !childView->isLockedViewMode() ) { bool forceAutoEmbed = req.forceAutoEmbed || req.newTab || req.userRequestedReload; if ( !req.typedURL.isEmpty() ) // the user _typed_ the URL, he wants it in Konq. forceAutoEmbed = true; if ( url.protocol() == "about" ) forceAutoEmbed = true; // Related to KonqFactory::createView if ( !forceAutoEmbed && !KonqFMSettings::settings()->shouldEmbed( serviceType ) ) { kdDebug(1202) << "openView: KonqFMSettings says: don't embed this servicetype" << endl; ok = false; } // If the protocol doesn't support writing (e.g. HTTP) then we might want to save instead of just embedding. // So (if embedding would succeed, hence the checks above) we ask the user // Otherwise the user will get asked 'open or save' in openURL anyway. if ( ok && !forceAutoEmbed && !KProtocolInfo::supportsWriting( url ) ) { TQString suggestedFilename; KonqRun* run = childView->run(); int attachment = 0; if (run) { suggestedFilename = run->suggestedFilename(); attachment = (run->serverSuggestsSave()) ? KParts::BrowserRun::AttachmentDisposition : KParts::BrowserRun::InlineDisposition; } KParts::BrowserRun::AskSaveResult res = KParts::BrowserRun::askEmbedOrSave( url, serviceType, suggestedFilename, attachment ); if ( res == KParts::BrowserRun::Open ) forceAutoEmbed = true; else if ( res == KParts::BrowserRun::Cancel ) return true; // handled, don't do anything else else { // Save KParts::BrowserRun::simpleSave( url, suggestedFilename, this ); return true; // handled } } if ( ok ) ok = childView->changeViewMode( serviceType, serviceName, forceAutoEmbed ); } } if (ok) { //kdDebug(1202) << "req.nameFilter= " << req.nameFilter << endl; //kdDebug(1202) << "req.typedURL= " << req.typedURL << endl; //kdDebug(1202) << "Browser extension? " << (childView->browserExtension() ? "YES" : "NO") << endl; //kdDebug(1202) << "Referrer: " << req.args.metaData()["referrer"] << endl; childView->setTypedURL( req.typedURL ); if ( childView->browserExtension() ) childView->browserExtension()->setURLArgs( req.args ); if ( childView->part()->inherits("KonqDirPart") ) static_cast(childView->part())->setFilesToSelect( req.filesToSelect ); if ( !url.isEmpty() ) childView->openURL( url, originalURL, req.nameFilter, req.tempFile ); } kdDebug(1202) << "KonqMainWindow::openView ok=" << ok << " bOthersFollowed=" << bOthersFollowed << " returning " << (ok || bOthersFollowed) << endl; return ok || bOthersFollowed; } void KonqMainWindow::slotOpenURLRequest( const KURL &url, const KParts::URLArgs &args ) { kdDebug(1202) << "KonqMainWindow::slotOpenURLRequest frameName=" << args.frameName << endl; KParts::ReadOnlyPart *callingPart = static_cast( sender()->parent() ); TQString frameName = args.frameName; if ( !frameName.isEmpty() ) { static TQString _top = TQString::tqfromLatin1( "_top" ); static TQString _self = TQString::tqfromLatin1( "_self" ); static TQString _parent = TQString::tqfromLatin1( "_parent" ); static TQString _blank = TQString::tqfromLatin1( "_blank" ); if ( frameName.lower() == _blank ) { slotCreateNewWindow( url, args ); return; } if ( frameName.lower() != _top && frameName.lower() != _self && frameName.lower() != _parent ) { KParts::BrowserHostExtension *hostExtension = 0; KonqView *view = childView( callingPart, frameName, &hostExtension, 0 ); if ( !view ) { KonqMainWindow *mainWindow = 0; view = findChildView( callingPart, frameName, &mainWindow, &hostExtension, 0 ); if ( !view || !mainWindow ) { slotCreateNewWindow( url, args ); return; } if ( hostExtension ) hostExtension->openURLInFrame( url, args ); else mainWindow->openURL( view, url, args ); return; } if ( hostExtension ) hostExtension->openURLInFrame( url, args ); else openURL( view, url, args ); return; } } KonqView *view = childView( callingPart ); openURL( view, url, args ); } //Called by slotOpenURLRequest void KonqMainWindow::openURL( KonqView *childView, const KURL &url, const KParts::URLArgs &args ) { kdDebug(1202) << "KonqMainWindow::openURL (from slotOpenURLRequest) url=" << url.prettyURL() << endl; KonqOpenURLRequest req; req.args = args; // Clicking on a link that points to the page itself (e.g. anchor) if ( !args.doPost() && !args.reload && childView && urlcmp( url.url(), childView->url().url(), true, true ) ) { TQString serviceType = args.serviceType; if ( serviceType.isEmpty() ) serviceType = childView->serviceType(); childView->stop(); req.forceAutoEmbed = true; req.openAfterCurrentPage = KonqSettings::openAfterCurrentPage(); openView( serviceType, url, childView, req ); return; } openURL( childView, url, args.serviceType, req, args.trustedSource ); } TQObject *KonqMainWindow::lastFrame( KonqView *view ) { TQObject *nextFrame, *viewFrame; nextFrame = view->frame(); viewFrame = 0; while ( nextFrame != 0 && ! nextFrame->inherits( "QWidgetStack" ) ) { viewFrame = nextFrame; nextFrame = nextFrame->parent(); } return nextFrame ? viewFrame : 0L; } // Linked-views feature, plus "sidebar follows URL opened in the active view" feature bool KonqMainWindow::makeViewsFollow( const KURL & url, const KParts::URLArgs &args, const TQString & serviceType, KonqView * senderView ) { if ( !senderView->isLinkedView() && senderView != m_currentView ) return false; // none of those features apply -> return bool res = false; //kdDebug(1202) << "makeViewsFollow " << senderView->className() << " url=" << url << " serviceType=" << serviceType << endl; KonqOpenURLRequest req; req.followMode = true; req.args = args; // We can't iterate over the map here, and openURL for each, because the map can get modified // (e.g. by part changes). Better copy the views into a list. TQPtrList listViews; MapViews::ConstIterator it = m_mapViews.begin(); MapViews::ConstIterator end = m_mapViews.end(); for (; it != end; ++it ) listViews.append( it.data() ); TQObject *senderFrame = lastFrame( senderView ); for ( KonqView * view = listViews.first() ; view ; view = listViews.next()) { bool followed = false; // Views that should follow this URL as both views are linked if ( (view != senderView) && view->isLinkedView() && senderView->isLinkedView() ) { TQObject *viewFrame = lastFrame( view ); // Only views in the same tab of the sender will follow if ( senderFrame && viewFrame && viewFrame != senderFrame ) continue; kdDebug(1202) << "makeViewsFollow: Sending openURL to view " << view->part()->className() << " url=" << url << endl; // XXX duplicate code from ::openURL if ( view == m_currentView ) { abortLoading(); setLocationBarURL( url ); } else view->stop(); followed = openView( serviceType, url, view, req ); } else { // Make the sidebar follow the URLs opened in the active view if ((view!=senderView) && view->isFollowActive() && senderView == m_currentView) { followed = openView(serviceType, url, view, req); } } // Ignore return value if the view followed but doesn't really // show the file contents. We still want to see that // file, e.g. in a separate viewer. // This happens in views locked to a directory mode, // like sidebar and konsolepart (#52161). bool ignore = view->isLockedViewMode() && view->supportsServiceType("inode/directory"); //kdDebug(1202) << "View " << view->service()->name() // << " supports dirs: " << view->supportsServiceType( "inode/directory" ) // << " is locked-view-mode:" << view->isLockedViewMode() // << " ignore=" << ignore << endl; if ( !ignore ) res = followed || res; } return res; } void KonqMainWindow::abortLoading() { //kdDebug(1202) << "KonqMainWindow::abortLoading()" << endl; if ( m_currentView ) { m_currentView->stop(); // will take care of the statusbar stopAnimation(); } } void KonqMainWindow::slotCreateNewWindow( const KURL &url, const KParts::URLArgs &args ) { kdDebug(1202) << "KonqMainWindow::slotCreateNewWindow url=" << url.prettyURL() << endl; if ( args.newTab() || ( KonqSettings::mmbOpensTab() && (const_cast(&args)->metaData()["forcenewwindow"]).isEmpty()) ) { KonqOpenURLRequest req; req.newTab = true; req.newTabInFront = KonqSettings::newTabsInFront(); req.openAfterCurrentPage = KonqSettings::openAfterCurrentPage(); if (KApplication::keyboardMouseState() & Qt::ShiftButton) req.newTabInFront = !req.newTabInFront; req.args = args; openURL( 0L, url, TQString::null, req ); } else { KonqMisc::createNewWindow( url, args ); } } // This is mostly for the JS window.open call void KonqMainWindow::slotCreateNewWindow( const KURL &url, const KParts::URLArgs &args, const KParts::WindowArgs &windowArgs, KParts::ReadOnlyPart *&part ) { kdDebug(1202) << "KonqMainWindow::slotCreateNewWindow(4 args) url=" << url.prettyURL() << " args.serviceType=" << args.serviceType << " args.frameName=" << args.frameName << endl; part = 0; // Make sure to be initialized in case of failure... KonqMainWindow *mainWindow = 0L; if ( !args.frameName.isEmpty() && args.frameName.lower() != "_blank" ) { KParts::BrowserHostExtension *hostExtension = 0; KParts::ReadOnlyPart *ro_part = 0L; KParts::BrowserExtension *be = ::qt_cast(sender()); if (be) ro_part = ::qt_cast(be->parent()); if ( findChildView( ro_part, args.frameName, &mainWindow, &hostExtension, &part ) ) { // Found a view. If url isn't empty, we should open it - but this never happens currently // findChildView put the resulting part in 'part', so we can just return now //kdDebug() << " frame=" << args.frameName << " -> found part=" << part << " " << part->name() << endl; return; } } if ( KonqSettings::popupsWithinTabs() || ( KonqSettings::mmbOpensTab() && windowArgs.lowerWindow ) ) { bool aftercurrentpage = KonqSettings::openAfterCurrentPage(); bool newtabsinfront = KonqSettings::newTabsInFront(); if ( windowArgs.lowerWindow ) newtabsinfront =! newtabsinfront; KonqView* newView = m_pViewManager->addTab(TQString::null, TQString::null, false, aftercurrentpage); if (newView == 0L) return; if (newtabsinfront) m_pViewManager->showTab( newView ); openURL( newView, url.isEmpty() ? KURL("about:blank") : url, TQString::null); newView->setViewName( args.frameName ); part=newView->part(); return; } mainWindow = new KonqMainWindow( KURL(), false ); mainWindow->setInitialFrameName( args.frameName ); mainWindow->resetAutoSaveSettings(); // Don't autosave KonqOpenURLRequest req; req.args = args; if ( args.serviceType.isEmpty() ) mainWindow->openURL( 0L, url, TQString::null, req ); else if ( !mainWindow->openView( args.serviceType, url, 0L, req ) ) { // we have problems. abort. delete mainWindow; part = 0; return; } KonqView * view = 0L; // cannot use activePart/currentView, because the activation through the partmanager // is delayed by a singleshot timer (see KonqViewManager::setActivePart) if ( mainWindow->viewMap().count() ) { MapViews::ConstIterator it = mainWindow->viewMap().begin(); view = it.data(); part = it.key(); } // activate the view _now_ in order to make the menuBar() hide call work if ( part ) { mainWindow->viewManager()->setActivePart( part, true ); } TQString profileName = TQString::tqfromLatin1( url.isLocalFile() ? "konqueror/profiles/filemanagement" : "konqueror/profiles/webbrowsing" ); KSimpleConfig cfg( locate( "data", profileName ), true ); cfg.setGroup( "Profile" ); if ( windowArgs.x != -1 ) mainWindow->move( windowArgs.x, mainWindow->y() ); if ( windowArgs.y != -1 ) mainWindow->move( mainWindow->x(), windowArgs.y ); TQSize size = KonqViewManager::readConfigSize( cfg, mainWindow ); int width; if ( windowArgs.width != -1 ) width = windowArgs.width; else width = size.isValid() ? size.width() : mainWindow->width(); int height; if ( windowArgs.height != -1 ) height = windowArgs.height; else height = size.isValid() ? size.height() : mainWindow->height(); mainWindow->resize( width, height ); // process the window args if ( !windowArgs.menuBarVisible ) { mainWindow->menuBar()->hide(); mainWindow->m_paShowMenuBar->setChecked( false ); } if ( !windowArgs.toolBarsVisible ) { for ( TQPtrListIterator it( mainWindow->toolBarIterator() ); it.current(); ++it ) { (*it)->hide(); } } if ( view ) { if ( !windowArgs.scrollBarsVisible ) view->disableScrolling(); if ( !windowArgs.statusBarVisible ) view->frame()->statusbar()->hide(); } if ( !windowArgs.resizable ) // ### this doesn't seem to work :-( mainWindow->tqsetSizePolicy( TQSizePolicy( TQSizePolicy::Fixed, TQSizePolicy::Fixed ) ); // Trying to show the window initially behind the current window is a bit tricky, // as this involves the window manager, which may see things differently. // Many WMs raise and activate new windows, which means without WM support this won't work very // well. If the WM has support for _NET_WM_USER_TIME, it will be just set to 0 (=don't focus on show), // and the WM should take care of it itself. bool wm_usertime_support = false; extern Time qt_x_user_time; Time saved_last_input_time = qt_x_user_time; if ( windowArgs.lowerWindow ) { NETRootInfo wm_info( qt_xdisplay(), NET::Supported ); wm_usertime_support = wm_info.isSupported( NET::WM2UserTime ); if( wm_usertime_support ) { // *sigh*, and I thought nobody would need TQWidget::dontFocusOnShow(). // Avoid Qt's support for user time by setting it to 0, and // set the property ourselves. qt_x_user_time = 0; KWin::setUserTime( mainWindow->winId(), 0 ); } // Put below the current window before showing, in case that actually works with the WM. // First do complete lower(), then stackUnder(), because the latter may not work with many WMs. mainWindow->lower(); mainWindow->stackUnder( this ); } mainWindow->show(); if ( windowArgs.lowerWindow ) { qt_x_user_time = saved_last_input_time; if( !wm_usertime_support ) { // No WM support. Let's try ugly tricks. mainWindow->lower(); mainWindow->stackUnder( this ); if( this->isActiveWindow()) this->setActiveWindow(); } } if ( windowArgs.fullscreen ) mainWindow->action( "fullscreen" )->activate(); } void KonqMainWindow::slotNewWindow() { // Use profile from current window, if set TQString profile = m_pViewManager->currentProfile(); if ( profile.isEmpty() ) { if ( m_currentView && m_currentView->url().protocol().startsWith( "http" ) ) profile = TQString::tqfromLatin1("webbrowsing"); else profile = TQString::tqfromLatin1("filemanagement"); } KonqMisc::createBrowserWindowFromProfile( locate( "data", TQString::tqfromLatin1("konqueror/profiles/")+profile ), profile ); } void KonqMainWindow::slotDuplicateWindow() { KTempFile tempFile; tempFile.setAutoDelete( true ); KConfig config( tempFile.name() ); config.setGroup( "View Profile" ); m_pViewManager->saveViewProfile( config, true, true ); KonqMainWindow *mainWindow = new KonqMainWindow( KURL(), false, 0, xmlFile()); mainWindow->viewManager()->loadViewProfile( config, m_pViewManager->currentProfile() ); if (mainWindow->currentView()) { mainWindow->copyHistory( childFrame() ); } mainWindow->activateChild(); mainWindow->show(); #ifndef NDEBUG mainWindow->viewManager()->printFullHierarchy( this ); #endif } void KonqMainWindow::slotSendURL() { KURL::List lst = currentURLs(); TQString body; TQString fileNameList; for ( KURL::List::Iterator it = lst.begin() ; it != lst.end() ; ++it ) { if ( !body.isEmpty() ) body += '\n'; body += (*it).prettyURL(); if ( !fileNameList.isEmpty() ) fileNameList += ", "; fileNameList += (*it).fileName(); } TQString subject; if ( m_currentView && !m_currentView->part()->inherits("KonqDirPart") ) subject = m_currentView->caption(); else subject = fileNameList; kapp->invokeMailer(TQString::null,TQString::null,TQString::null, subject, body); } void KonqMainWindow::slotSendFile() { KURL::List lst = currentURLs(); TQStringList urls; TQString fileNameList; for ( KURL::List::Iterator it = lst.begin() ; it != lst.end() ; ++it ) { if ( !fileNameList.isEmpty() ) fileNameList += ", "; if ( (*it).isLocalFile() && TQFileInfo((*it).path()).isDir() ) { // Create a temp dir, so that we can put the ZIP file in it with a proper name KTempFile zipFile; TQString zipFileName = zipFile.name(); zipFile.unlink(); TQDir().mkdir(zipFileName,true); zipFileName = zipFileName+"/"+(*it).fileName()+".zip"; KZip zip( zipFileName ); if ( !zip.open( IO_WriteOnly ) ) continue; // TODO error message zip.addLocalDirectory( (*it).path(), TQString::null ); zip.close(); fileNameList += (*it).fileName()+".zip"; urls.append( zipFileName ); } else { fileNameList += (*it).fileName(); urls.append( (*it).url() ); } } TQString subject; if ( m_currentView && !m_currentView->part()->inherits("KonqDirPart") ) subject = m_currentView->caption(); else subject = fileNameList; kapp->invokeMailer(TQString::null, TQString::null, TQString::null, subject, TQString::null, //body TQString::null, urls); // attachments } void KonqMainWindow::slotOpenTerminal() { TQString term = KonqSettings::terminalApplication(); TQString dir ( TQDir::homeDirPath() ); //Try to get the directory of the current view if ( m_currentView ) { KURL u( m_currentView->url() ); // If the given directory is not local, it can still be the URL of an // ioslave using UDS_LOCAL_PATH which to be converted first. u = KIO::NetAccess::mostLocalURL(u, this); //If the URL is local after the above conversion, set the directory. if ( u.isLocalFile() ) { TQString mime = m_currentView->serviceType(); if ( KMimeType::mimeType(mime)->is("inode/directory") ) dir = u.path(); else dir = u.directory(); } } KProcess cmd; cmd.setWorkingDirectory(dir); // Compensate for terminal having arguments. TQStringList args = TQStringList::split(' ', term); for ( TQStringList::iterator it = args.begin(); it != args.end(); ++it ) cmd << *it; kdDebug(1202) << "slotOpenTerminal: directory " << dir << ", terminal:" << term << endl; cmd.start(KProcess::DontCare); } void KonqMainWindow::slotOpenLocation() { // Don't pre-fill the url, as it is auto-selected and thus overwrites the // X clipboard, making it impossible to paste in the url you really wanted. // Another example of why the X clipboard sux KURLRequesterDlg dlg( TQString::null, this, 0, true); dlg.setCaption( i18n("Open Location") ); // Set current directory for relative paths. // Testcase: konqueror www.kde.org; Ctrl+O; file in $HOME; would open http://$file TQString currentDir; if (m_currentView && m_currentView->url().isLocalFile()) currentDir = m_currentView->url().path(1); dlg.urlRequester()->completionObject()->setDir( currentDir ); dlg.urlRequester()->setMode( KFile::File | KFile::Directory | KFile::ExistingOnly ); dlg.exec(); const KURL& url = dlg.selectedURL(); if (!url.isEmpty()) openFilteredURL( url.url().stripWhiteSpace() ); } void KonqMainWindow::slotToolFind() { kdDebug(1202) << "KonqMainWindow::slotToolFind sender:" << sender()->className() << endl; if ( m_currentView && m_currentView->part()->inherits("KonqDirPart") ) { KonqDirPart* dirPart = static_cast(m_currentView->part()); if (!m_paFindFiles->isChecked()) { dirPart->slotFindClosed(); return; } KonqViewFactory factory = KonqFactory::createView( "Konqueror/FindPart" ); if ( factory.isNull() ) { KMessageBox::error( this, i18n("Cannot create the find part, check your installation.") ); m_paFindFiles->setChecked(false); return; } KParts::ReadOnlyPart* findPart = factory.create( m_currentView->frame(), "findPartWidget", dirPart, "findPart" ); dirPart->setFindPart( findPart ); m_currentView->frame()->insertTopWidget( findPart->widget() ); findPart->widget()->show(); findPart->widget()->setFocus(); connect( dirPart, TQT_SIGNAL( findClosed(KonqDirPart *) ), this, TQT_SLOT( slotFindClosed(KonqDirPart *) ) ); } else if ( sender()->inherits( "KAction" ) ) // don't go there if called by the singleShot below { KURL url; if ( m_currentView && m_currentView->url().isLocalFile() ) url = m_currentView->locationBarURL(); else url.setPath( TQDir::homeDirPath() ); KonqMainWindow * mw = KonqMisc::createBrowserWindowFromProfile( locate( "data", TQString::tqfromLatin1("konqueror/profiles/filemanagement") ), "filemanagement", url, KParts::URLArgs(), true /* forbid "use html"*/ ); mw->m_paFindFiles->setChecked(true); // Delay it after the openURL call (hacky!) TQTimer::singleShot( 1, mw, TQT_SLOT(slotToolFind())); m_paFindFiles->setChecked(false); } } void KonqMainWindow::slotFindOpen( KonqDirPart * dirPart ) { kdDebug(1202) << "KonqMainWindow::slotFindOpen " << dirPart << endl; Q_ASSERT( m_currentView ); Q_ASSERT( m_currentView->part() == dirPart ); slotToolFind(); // lazy me } void KonqMainWindow::slotFindClosed( KonqDirPart * dirPart ) { kdDebug(1202) << "KonqMainWindow::slotFindClosed " << dirPart << endl; KonqView * dirView = m_mapViews.find( dirPart ).data(); Q_ASSERT(dirView); kdDebug(1202) << "dirView=" << dirView << endl; if ( dirView && dirView == m_currentView ) m_paFindFiles->setEnabled( true ); m_paFindFiles->setChecked(false); } void KonqMainWindow::slotIconsChanged() { //kdDebug(1202) << "KonqMainWindow::slotIconsChanged" << endl; m_combo->updatePixmaps(); m_pViewManager->updatePixmaps(); setIcon( KonqPixmapProvider::self()->pixmapFor( m_combo->currentText() )); } void KonqMainWindow::slotOpenWith() { KURL::List lst; lst.append( m_currentView->url() ); TQString serviceName = sender()->name(); KTrader::OfferList offers = m_currentView->appServiceOffers(); KTrader::OfferList::ConstIterator it = offers.begin(); KTrader::OfferList::ConstIterator end = offers.end(); for (; it != end; ++it ) if ( (*it)->desktopEntryName() == serviceName ) { KRun::run( **it, lst ); return; } } void KonqMainWindow::slotViewModeToggle( bool toggle ) { if ( !toggle ) return; TQString modeName = sender()->name(); if ( m_currentView->service()->desktopEntryName() == modeName ) return; m_bViewModeToggled = true; m_currentView->stop(); m_currentView->lockHistory(); // Save those, because changeViewMode will lose them KURL url = m_currentView->url(); TQString locationBarURL = m_currentView->locationBarURL(); TQStringList filesToSelect; if( m_currentView->part()->inherits( "KonqDirPart" ) ) { KFileItemList fileItemsToSelect = static_cast(m_currentView->part())->selectedFileItems(); KFileItemListIterator it( fileItemsToSelect ); while( it.current() ){ filesToSelect += it.current()->name(); ++it; } } bool bQuickViewModeChange = false; // iterate over all services, update the toolbar service map // and check if we can do a quick property-based viewmode change const KTrader::OfferList offers = m_currentView->partServiceOffers(); KTrader::OfferList::ConstIterator oIt = offers.begin(); KTrader::OfferList::ConstIterator oEnd = offers.end(); const TQString currentServiceKey = viewModeActionKey( m_currentView->service() ); for (; oIt != oEnd; ++oIt ) { KService::Ptr service = *oIt; if ( service->desktopEntryName() == modeName ) { // we changed the viewmode of either iconview or listview // -> update the service in the corresponding map, so that // we can set the correct text, icon, etc. properties to the // KonqViewModeAction when rebuilding the view-mode actions in // updateViewModeActions // (I'm saying iconview/listview here, but theoretically it could be // any view :) const TQString serviceKey = viewModeActionKey( service ); m_viewModeToolBarServices[ serviceKey ] = service; if ( serviceKey == currentServiceKey ) { TQVariant modeProp = service->property( "X-KDE-BrowserView-ModeProperty" ); TQVariant modePropValue = service->property( "X-KDE-BrowserView-ModePropertyValue" ); if ( !modeProp.isValid() || !modePropValue.isValid() ) break; m_currentView->part()->setProperty( modeProp.toString().latin1(), modePropValue ); KService::Ptr oldService = m_currentView->service(); // we aren't going to re-build the viewmode actions but instead of a // quick viewmode change (iconview) -> find the iconview-konqviewmode // action and set new text,icon,etc. properties, to show the new // current viewmode TQPtrListIterator it( m_toolBarViewModeActions ); for (; it.current(); ++it ) if ( TQString::tqfromLatin1( it.current()->name() ) == oldService->desktopEntryName() ) { assert( it.current()->inherits( "KonqViewModeAction" ) ); KonqViewModeAction *action = static_cast( it.current() ); action->setChecked( true ); TQString servicename = service->genericName(); if (servicename.isEmpty()) servicename = service->name(); action->setText( servicename ); action->setIcon( service->icon() ); action->setName( service->desktopEntryName().ascii() ); break; } m_currentView->setService( service ); bQuickViewModeChange = true; break; } } } if ( !bQuickViewModeChange ) { m_currentView->changeViewMode( m_currentView->serviceType(), modeName ); KURL locURL = KURL::fromPathOrURL( locationBarURL ); TQString nameFilter = detectNameFilter( locURL ); if( m_currentView->part()->inherits( "KonqDirPart" ) ) static_cast( m_currentView->part() )->setFilesToSelect( filesToSelect ); m_currentView->openURL( locURL, locationBarURL, nameFilter ); } // Now save this setting, either locally or globally (for directories only) // (We don't have views with viewmodes other than for dirs currently; // once we do, we might want to implement per-mimetype global-saving) if ( m_bSaveViewPropertiesLocally && m_currentView->supportsServiceType( "inode/directory" ) ) { KURL u ( m_currentView->url() ); u.addPath(".directory"); if ( u.isLocalFile() ) { KSimpleConfig config( u.path() ); // if we have no write access, just drop it config.setGroup( "URL properties" ); config.writeEntry( "ViewMode", modeName ); config.sync(); } } else { // We save the global view mode only if the view is a built-in view if ( m_currentView->isBuiltinView() ) { KonqSettings::setMainViewViewMode( modeName ); KonqSettings::writeConfig(); } } } void KonqMainWindow::showHTML( KonqView * _view, bool b, bool _activateView ) { // Save this setting, either locally or globally // This has to be done before calling openView since it relies on it if ( m_bSaveViewPropertiesLocally ) { KURL u ( b ? _view->url() : KURL( _view->url().directory() ) ); u.addPath(".directory"); if ( u.isLocalFile() ) { KSimpleConfig config( u.path() ); // No checks for access config.setGroup( "URL properties" ); config.writeEntry( "HTMLAllowed", b ); config.sync(); } } else { KonqSettings::setHtmlAllowed( b ); KonqSettings::writeConfig(); if ( _activateView ) m_bHTMLAllowed = b; } if ( b && _view->supportsServiceType( "inode/directory" ) ) { _view->lockHistory(); openView( "inode/directory", _view->url(), _view ); } else if ( !b && _view->supportsServiceType( "text/html" ) ) { KURL u( _view->url() ); TQString fileName = u.fileName().lower(); if ( KProtocolInfo::supportsListing( u ) && fileName.startsWith("index.htm") ) { _view->lockHistory(); u.setPath( u.directory() ); openView( "inode/directory", u, _view ); } } } void KonqMainWindow::slotShowHTML() { bool b = !m_currentView->allowHTML(); m_currentView->stop(); m_currentView->setAllowHTML( b ); showHTML( m_currentView, b, true ); //current view m_pViewManager->showHTML(b ); } void KonqMainWindow::setShowHTML( bool b ) { m_bHTMLAllowed = b; if ( m_currentView ) m_currentView->setAllowHTML( b ); m_ptaUseHTML->setChecked( b ); } void KonqMainWindow::slotLockView() { m_currentView->setLockedLocation( m_paLockView->isChecked() ); } void KonqMainWindow::slotStop() { abortLoading(); if ( m_currentView ) { m_currentView->frame()->statusbar()->message( i18n("Canceled.") ); } } void KonqMainWindow::slotLinkView() { // Can't access this action in passive mode anyway assert(!m_currentView->isPassiveMode()); bool mode = !m_currentView->isLinkedView(); if (linkableViewsCount() == 2) { // Exactly two linkable views : link both KonqMainWindow::MapViews::ConstIterator it = viewMap().begin(); if( (*it)->isFollowActive() ) // skip sidebar ++it; (*it)->setLinkedView( mode ); ++it; if( (*it)->isFollowActive() ) // skip sidebar ++it; (*it)->setLinkedView( mode ); } else // Normal case : just this view m_currentView->setLinkedView( mode ); } void KonqMainWindow::slotReload( KonqView* reloadView ) { if ( !reloadView ) reloadView = m_currentView; if ( !reloadView || reloadView->url().isEmpty() ) return; if ( reloadView->part() && (reloadView->part()->tqmetaObject()->findProperty("modified") != -1) ) { TQVariant prop = reloadView->part()->property("modified"); if (prop.isValid() && prop.toBool()) if ( KMessageBox::warningContinueCancel( this, i18n("This page tqcontains changes that have not been submitted.\nReloading the page will discard these changes."), i18n("Discard Changes?"), KGuiItem(i18n("&Discard Changes"),"reload"), "discardchangesreload") != KMessageBox::Continue ) return; } KonqOpenURLRequest req( reloadView->typedURL() ); req.userRequestedReload = true; if ( reloadView->prepareReload( req.args ) ) { reloadView->lockHistory(); // Reuse current servicetype for local files, but not for remote files (it could have changed, e.g. over HTTP) TQString serviceType = reloadView->url().isLocalFile() ? reloadView->serviceType() : TQString::null; openURL( reloadView, reloadView->url(), serviceType, req ); } } void KonqMainWindow::slotReloadStop() { if (m_paReloadStop->icon() == "reload") { slotReload(); toggleReloadStopButton(true); } else { slotStop(); toggleReloadStopButton(false); } } void KonqMainWindow::toggleReloadStopButton(bool isReload) { //m_paStop = new KAction( i18n( "&Stop" ), "stop", Key_Escape, this, TQT_SLOT( slotStop() ), actionCollection(), "stop" ); if (isReload) { m_paReloadStop->setIcon("stop"); m_paReloadStop->setWhatsThis( i18n( "Stop loading the document

" "All network transfers will be stopped and Konqueror will display the content " "that has been received so far." ) ); m_paReloadStop->setToolTip( i18n( "Stop loading the document" ) ); //m_paReloadStop = new KAction( i18n( "&Reload" ), "reload", reloadShortcut, this, TQT_SLOT( slotReloadStop() ), actionCollection(), "reload" ); } else { m_paReloadStop->setIcon("reload"); m_paReloadStop->setWhatsThis( i18n( "Reload the currently displayed document

" "This may, for example, be needed to refresh webpages that have been " "modified since they were loaded, in order to make the changes visible." ) ); m_paReloadStop->setToolTip( i18n( "Reload the currently displayed document" ) ); } } void KonqMainWindow::slotReloadPopup() { if (m_pWorkingTab) slotReload( m_pWorkingTab->activeChildView() ); } void KonqMainWindow::slotHome(KAction::ActivationReason, Qt::ButtonState state) { TQString homeURL = m_pViewManager->profileHomeURL(); if (homeURL.isEmpty()) homeURL = KonqFMSettings::settings()->homeURL(); KonqOpenURLRequest req; req.newTab = true; req.newTabInFront = KonqSettings::newTabsInFront(); if (state & Qt::ShiftButton) req.newTabInFront = !req.newTabInFront; if( state & Qt::ControlButton ) // Ctrl Left/MMB openFilteredURL( homeURL, req); else if( state & Qt::MidButton ) { if(KonqSettings::mmbOpensTab()) openFilteredURL( homeURL, req); else { KURL finalURL = KonqMisc::konqFilteredURL( this, homeURL ); KonqMisc::createNewWindow( finalURL.url() ); } } else openFilteredURL( homeURL, false ); } void KonqMainWindow::slotHome() { slotHome(KAction::UnknownActivation, Qt::LeftButton); } void KonqMainWindow::slotGoSystem() { openURL( 0L, KURL( "system:/" ) ); } void KonqMainWindow::slotGoApplications() { openURL( 0L, KURL( "programs:/" ) ); } void KonqMainWindow::slotGoMedia() { openURL( 0L, KURL( "media:/" ) ); } void KonqMainWindow::slotGoNetworkFolders() { openURL( 0L, KURL( "remote:/" ) ); } void KonqMainWindow::slotGoSettings() { openURL( 0L, KURL( "settings:/" ) ); } void KonqMainWindow::slotGoDirTree() { KURL u; u.setPath( locateLocal( "data", "konqueror/dirtree/" ) ); openURL( 0L, u ); } void KonqMainWindow::slotGoTrash() { openURL( 0L, KURL( "trash:/" ) ); } void KonqMainWindow::slotGoAutostart() { KURL u; u.setPath( KGlobalSettings::autostartPath() ); openURL( 0L, u ); } void KonqMainWindow::slotGoHistory() { KAction *a = m_toggleViewGUIClient->action("konq_sidebartng"); if (!a) { KMessageBox::sorry(0L, i18n("Your sidebar is not functional or unavailable."), i18n("Show History Sidebar")); return; } // Show the sidebar if (!static_cast(a)->isChecked()) { a->activate(); TQTimer::singleShot( 0, this, TQT_SLOT(slotGoHistory())); return; } // Tell it to show the history plugin MapViews::ConstIterator it; for (it = viewMap().begin(); it != viewMap().end(); ++it) { KonqView *view = it.data(); if (view) { KService::Ptr svc = view->service(); if (svc->desktopEntryName() == "konq_sidebartng") { if (!view->part()->openURL("sidebar:history.desktop")) KMessageBox::sorry(0L, i18n("Cannot find running history plugin in your sidebar."), i18n("Show History Sidebar")); break; } } } } TQStringList KonqMainWindow::configModules() const { return m_configureModules; } void KonqMainWindow::slotConfigureExtensions() { KonqExtensionManager extensionManager(0, this, m_currentView ? m_currentView->part() : 0); extensionManager.exec(); } void KonqMainWindow::slotConfigure() { if( !m_configureDialog ) { m_configureDialog = new KCMultiDialog( this, "configureDialog" ); TQStringList modules = configModules(); TQStringList::ConstIterator end( modules.end() ); for( TQStringList::ConstIterator it = modules.begin(); it != end; ++it ) { if ( kapp->authorizeControlModule( *it ) ) { m_configureDialog->addModule( *it ); } } } m_configureDialog->show(); } void KonqMainWindow::slotConfigureSpellChecking() { KApplication::startServiceByDesktopName("spellchecking"); } void KonqMainWindow::slotConfigureToolbars() { if ( autoSaveSettings() ) saveMainWindowSettings( KGlobal::config(), "KonqMainWindow" ); KEditToolbar dlg(factory()); connect(&dlg,TQT_SIGNAL(newToolbarConfig()),this,TQT_SLOT(slotNewToolbarConfig())); connect(&dlg,TQT_SIGNAL(newToolbarConfig()),this,TQT_SLOT(initBookmarkBar())); dlg.exec(); } void KonqMainWindow::slotNewToolbarConfig() // This is called when OK or Apply is clicked { if ( m_toggleViewGUIClient ) plugActionList( TQString::tqfromLatin1( "toggleview" ), m_toggleViewGUIClient->actions() ); if ( m_currentView && m_currentView->appServiceOffers().count() > 0 ) plugActionList( "openwith", m_openWithActions ); plugViewModeActions(); applyMainWindowSettings( KGlobal::config(), "KonqMainWindow" ); } void KonqMainWindow::slotUndoAvailable( bool avail ) { bool enable = false; if ( avail && m_currentView && m_currentView->part() ) { // Avoid qWarning from TQObject::property if it doesn't exist if ( m_currentView->part()->tqmetaObject()->findProperty( "supportsUndo" ) != -1 ) { TQVariant prop = m_currentView->part()->property( "supportsUndo" ); if ( prop.isValid() && prop.toBool() ) enable = true; } } m_paUndo->setEnabled( enable ); } void KonqMainWindow::slotPartChanged( KonqView *childView, KParts::ReadOnlyPart *oldPart, KParts::ReadOnlyPart *newPart ) { kdDebug(1202) << "KonqMainWindow::slotPartChanged" << endl; m_mapViews.remove( oldPart ); m_mapViews.insert( newPart, childView ); // Remove the old part, and add the new part to the manager // Note: this makes the new part active... so it calls slotPartActivated m_pViewManager->tqreplacePart( oldPart, newPart, false ); // Set active immediately m_pViewManager->setActivePart( newPart, true ); viewsChanged(); } void KonqMainWindow::slotRunFinished() { kdDebug(1202) << "KonqMainWindow::slotRunFinished()" << endl; const KonqRun *run = static_cast( sender() ); if ( run == m_initialKonqRun ) m_initialKonqRun = 0L; if ( !run->mailtoURL().isEmpty() ) { kapp->invokeMailer( run->mailtoURL() ); } if ( run->hasError() ) { // we had an error TQByteArray data; TQDataStream s( data, IO_WriteOnly ); s << run->url().prettyURL() << kapp->dcopClient()->defaultObject(); kapp->dcopClient()->send( "konqueror*", "KonquerorIface", "removeFromCombo(TQString,TQCString)", data); } KonqView *childView = run->childView(); // Check if we found a mimetype _and_ we got no error (example: cancel in openwith dialog) if ( run->foundMimeType() && !run->hasError() ) { // We do this here and not in the constructor, because // we are waiting for the first view to be set up before doing this... // Note: this is only used when konqueror is started from command line..... if ( m_bNeedApplyKonqMainWindowSettings ) { m_bNeedApplyKonqMainWindowSettings = false; // only once applyKonqMainWindowSettings(); } return; } if ( childView ) { childView->setLoading( false ); if ( childView == m_currentView ) { stopAnimation(); // Revert to working URL - unless the URL was typed manually kdDebug(1202) << " typed URL = " << run->typedURL() << endl; if ( run->typedURL().isEmpty() && childView->history().current() ) // not typed childView->setLocationBarURL( childView->history().current()->locationBarURL ); } } else // No view, e.g. empty webbrowsing profile stopAnimation(); } void KonqMainWindow::applyKonqMainWindowSettings() { TQStringList toggableViewsShown = KonqSettings::toggableViewsShown(); TQStringList::ConstIterator togIt = toggableViewsShown.begin(); TQStringList::ConstIterator togEnd = toggableViewsShown.end(); for ( ; togIt != togEnd ; ++togIt ) { // Find the action by name // KAction * act = m_toggleViewGUIClient->actionCollection()->action( (*togIt).latin1() ); KAction *act = m_toggleViewGUIClient->action( *togIt ); if ( act ) act->activate(); else kdWarning(1202) << "Unknown toggable view in ToggableViewsShown " << *togIt << endl; } } void KonqMainWindow::slotSetStatusBarText( const TQString & ) { // Reimplemented to disable KParts::MainWindow default behaviour // Does nothing here, see konq_frame.cc } void KonqMainWindow::slotViewCompleted( KonqView * view ) { assert( view ); // Need to update the current working directory // of the completion object every time the user // changes the directory!! (DA) if( m_pURLCompletion ) { KURL u( view->locationBarURL() ); if( u.isLocalFile() ) m_pURLCompletion->setDir( u.path() ); else m_pURLCompletion->setDir( u.url() ); //needs work!! (DA) } } void KonqMainWindow::slotPartActivated( KParts::Part *part ) { kdDebug(1202) << "KonqMainWindow::slotPartActivated " << part << " " << ( part && part->instance() && part->instance()->aboutData() ? part->instance()->aboutData()->appName() : "" ) << endl; KonqView *newView = 0; KonqView *oldView = m_currentView; if ( part ) { newView = m_mapViews.find( static_cast( part ) ).data(); if ( newView->isPassiveMode() ) { // Passive view. Don't connect anything, don't change m_currentView // Another view will become the current view very soon kdDebug(1202) << "KonqMainWindow::slotPartActivated: Passive mode - return" << endl; return; } } KParts::BrowserExtension *ext = 0; if ( oldView ) { ext = oldView->browserExtension(); if ( ext ) { //kdDebug(1202) << "Disconnecting extension for view " << oldView << endl; disconnectExtension( ext ); } if ( oldView->part() ) { KActionCollection *coll = oldView->part()->actionCollection(); if ( coll ) disconnectActionCollection( coll ); } } kdDebug(1202) << "KonqMainWindow::slotPartActivated: New current view " << newView << endl; m_currentView = newView; if ( !part ) { kdDebug(1202) << "KonqMainWindow::slotPartActivated: No part activated - returning" << endl; unplugViewModeActions(); createGUI( 0L ); KParts::MainWindow::setCaption( "" ); KParts::MainWindow::setIcon( kapp->icon()); return; } ext = m_currentView->browserExtension(); if ( ext ) { connectExtension( ext ); } else { kdDebug(1202) << "KonqMainWindow::slotPartActivated: No Browser Extension for the new part" << endl; // Disable all browser-extension actions KParts::BrowserExtension::ActionSlotMap * actionSlotMap = KParts::BrowserExtension::actionSlotMapPtr(); KParts::BrowserExtension::ActionSlotMap::ConstIterator it = actionSlotMap->begin(); KParts::BrowserExtension::ActionSlotMap::ConstIterator itEnd = actionSlotMap->end(); for ( ; it != itEnd ; ++it ) { KAction * act = actionCollection()->action( it.key() ); Q_ASSERT(act); if (act) act->setEnabled( false ); } if ( m_paCopyFiles ) m_paCopyFiles->setEnabled( false ); if ( m_paMoveFiles ) m_paMoveFiles->setEnabled( false ); if ( m_paNewDir ) m_paNewDir->setEnabled( false ); } createGUI( part ); KActionCollection *coll = m_currentView->part()->actionCollection(); if ( coll ) connectActionCollection( coll ); // View-dependent GUI KParts::MainWindow::setCaption( m_currentView->caption() ); m_currentView->frame()->setTitle( m_currentView->caption() , 0L); updateOpenWithActions(); updateLocalPropsActions(); updateViewActions(); // undo, lock, link and other view-dependent actions if ( m_bViewModeToggled ) { // if we just toggled the view mode via the view mode actions, then // we don't need to do all the time-taking stuff below (Simon) const TQString currentServiceDesktopEntryName = m_currentView->service()->desktopEntryName(); TQPtrListIterator it( m_viewModeActions ); for (; it.current(); ++it ) { if ( it.current()->name() == currentServiceDesktopEntryName ) { it.current()->setChecked( true ); break; } } const TQString currentServiceLibrary = viewModeActionKey( m_currentView->service() ); TQPtrListIterator ittb( m_toolBarViewModeActions ); for (; ittb.current(); ++ittb ) { KService::Ptr serv = KService::serviceByDesktopName( ittb.current()->name() ); if ( serv && viewModeActionKey( serv ) == currentServiceLibrary ) { KToggleAction* ta = static_cast( ittb.current() ); ta->setChecked( false ); TQString servicename = m_currentView->service()->genericName(); if (servicename.isEmpty()) servicename = m_currentView->service()->name(); ta->setText( servicename ); ta->setIcon( m_currentView->service()->icon() ); ta->setName( m_currentView->service()->desktopEntryName().ascii() ) ; break; } } } else { updateViewModeActions(); } m_bViewModeToggled = false; m_pMenuNew->setEnabled( m_currentView->supportsServiceType( "inode/directory" ) ); m_currentView->frame()->statusbar()->updateActivetqStatus(); if ( oldView && oldView->frame() ) oldView->frame()->statusbar()->updateActivetqStatus(); //kdDebug(1202) << "KonqMainWindow::slotPartActivated: setting location bar url to " // << m_currentView->locationBarURL() << " m_currentView=" << m_currentView << endl; m_currentView->setLocationBarURL( m_currentView->locationBarURL() ); updateToolBarActions(); m_currentView->setActiveInstance(); } void KonqMainWindow::insertChildView( KonqView *childView ) { kdDebug(1202) << "KonqMainWindow::insertChildView " << childView << endl; m_mapViews.insert( childView->part(), childView ); connect( childView, TQT_SIGNAL( viewCompleted( KonqView * ) ), this, TQT_SLOT( slotViewCompleted( KonqView * ) ) ); if ( !m_pViewManager->isLoadingProfile() ) // see KonqViewManager::loadViewProfile viewCountChanged(); emit viewAdded( childView ); } // Called by KonqViewManager, internal void KonqMainWindow::removeChildView( KonqView *childView ) { kdDebug(1202) << "KonqMainWindow::removeChildView childView " << childView << endl; disconnect( childView, TQT_SIGNAL( viewCompleted( KonqView * ) ), this, TQT_SLOT( slotViewCompleted( KonqView * ) ) ); #ifndef NDEBUG dumpViewList(); #endif MapViews::Iterator it = m_mapViews.begin(); MapViews::Iterator end = m_mapViews.end(); // find it in the map - can't use the key since childView->part() might be 0L kdDebug(1202) << "Searching map" << endl; while ( it != end && it.data() != childView ) ++it; kdDebug(1202) << "Verifying search results" << endl; if ( it == m_mapViews.end() ) { kdWarning(1202) << "KonqMainWindow::removeChildView childView " << childView << " not in map !" << endl; return; } kdDebug(1202) << "Removing view " << childView << endl; m_mapViews.remove( it ); kdDebug(1202) << "View " << childView << " removed from map" << endl; viewCountChanged(); emit viewRemoved( childView ); #ifndef NDEBUG dumpViewList(); #endif // KonqViewManager takes care of m_currentView } void KonqMainWindow::viewCountChanged() { // This is called when the number of views changes. kdDebug(1202) << "KonqMainWindow::viewCountChanged" << endl; int lvc = linkableViewsCount(); m_paLinkView->setEnabled( lvc > 1 ); // Only one view (or one view + sidebar) -> make it/them unlinked if ( lvc == 1 ) { MapViews::Iterator it = m_mapViews.begin(); MapViews::Iterator end = m_mapViews.end(); for (; it != end; ++it ) it.data()->setLinkedView( false ); } viewsChanged(); m_pViewManager->viewCountChanged(); } void KonqMainWindow::viewsChanged() { // This is called when the number of views changes OR when // the type of some view changes. // Nothing here anymore, but don't cleanup, some might come back later. updateViewActions(); // undo, lock, link and other view-dependent actions } KonqView * KonqMainWindow::childView( KParts::ReadOnlyPart *view ) { MapViews::ConstIterator it = m_mapViews.find( view ); if ( it != m_mapViews.end() ) return it.data(); else return 0L; } KonqView * KonqMainWindow::childView( KParts::ReadOnlyPart *callingPart, const TQString &name, KParts::BrowserHostExtension **hostExtension, KParts::ReadOnlyPart **part ) { kdDebug() << "KonqMainWindow::childView this=" << this << " looking for " << name << endl; MapViews::ConstIterator it = m_mapViews.begin(); MapViews::ConstIterator end = m_mapViews.end(); for (; it != end; ++it ) { KonqView* view = it.data(); TQString viewName = view->viewName(); kdDebug() << " - viewName=" << viewName << " " << "frame names:" << view->frameNames().join( "," ) << endl; // First look for a hostextension containing this frame name KParts::BrowserHostExtension *ext = KParts::BrowserHostExtension::childObject( view->part() ); if ( ext ) { ext = ext->tqfindFrameParent(callingPart, name); kdDebug() << "BrowserHostExtension found part " << ext << endl; if (!ext) continue; // Don't use this window } if ( !viewName.isEmpty() && viewName == name ) { kdDebug() << "found existing view by name: " << view << endl; if ( hostExtension ) *hostExtension = 0; if ( part ) *part = view->part(); return view; } // KParts::BrowserHostExtension* ext = KonqView::hostExtension( view->part(), name ); if ( ext ) { TQPtrList frames = ext->frames(); TQPtrListIterator frameIt( frames ); for ( ; frameIt.current() ; ++frameIt ) { if ( frameIt.current()->name() == name ) { kdDebug() << "found a frame of name " << name << " : " << frameIt.current() << endl; if ( hostExtension ) *hostExtension = ext; if ( part ) *part = frameIt.current(); return view; } } } } return 0; } // static KonqView * KonqMainWindow::findChildView( KParts::ReadOnlyPart *callingPart, const TQString &name, KonqMainWindow **mainWindow, KParts::BrowserHostExtension **hostExtension, KParts::ReadOnlyPart **part ) { if ( !s_lstViews ) return 0; TQPtrListIterator it( *s_lstViews ); for (; it.current(); ++it ) { KonqView *res = it.current()->childView( callingPart, name, hostExtension, part ); if ( res ) { if ( mainWindow ) *mainWindow = it.current(); return res; } } return 0; } int KonqMainWindow::activeViewsCount() const { int res = 0; MapViews::ConstIterator it = m_mapViews.begin(); MapViews::ConstIterator end = m_mapViews.end(); for (; it != end; ++it ) if ( !it.data()->isPassiveMode() ) ++res; return res; } int KonqMainWindow::linkableViewsCount() const { int res = 0; MapViews::ConstIterator it = m_mapViews.begin(); MapViews::ConstIterator end = m_mapViews.end(); for (; it != end; ++it ) if ( !it.data()->isFollowActive() ) ++res; return res; } int KonqMainWindow::mainViewsCount() const { int res = 0; MapViews::ConstIterator it = m_mapViews.begin(); MapViews::ConstIterator end = m_mapViews.end(); for (; it != end; ++it ) if ( !it.data()->isPassiveMode() && !it.data()->isToggleView() ) { //kdDebug(1202) << "KonqMainWindow::mainViewsCount " << res << " " << it.data() << " " << it.data()->part()->widget() << endl; ++res; } return res; } KParts::ReadOnlyPart * KonqMainWindow::currentPart() const { /// ### This is currently unused. Check in the final version (!) if still unused. if ( m_currentView ) return m_currentView->part(); else return 0L; } void KonqMainWindow::customEvent( TQCustomEvent *event ) { KParts::MainWindow::customEvent( event ); if ( KonqFileSelectionEvent::test( event ) || KonqFileMouseOverEvent::test( event ) ) { // Forward the event to all views MapViews::ConstIterator it = m_mapViews.begin(); MapViews::ConstIterator end = m_mapViews.end(); for (; it != end; ++it ) TQApplication::sendEvent( (*it)->part(), event ); return; } if ( KParts::OpenURLEvent::test( event ) ) { KParts::OpenURLEvent * ev = static_cast(event); KonqView * senderChildView = childView(ev->part()); // Enable/disable local properties actions if current view if ( senderChildView == m_currentView ) updateLocalPropsActions(); // Forward the event to all views MapViews::ConstIterator it = m_mapViews.begin(); MapViews::ConstIterator end = m_mapViews.end(); for (; it != end; ++it ) { // Don't resend to sender if (it.key() != ev->part()) { //kdDebug(1202) << "Sending event to view " << it.key()->className() << endl; TQApplication::sendEvent( it.key(), event ); } } } } void KonqMainWindow::updateLocalPropsActions() { bool canWrite = false; if ( m_currentView && m_currentView->url().isLocalFile() ) { // Can we write ? TQFileInfo info( m_currentView->url().path() ); canWrite = info.isDir() && info.isWritable(); } m_paSaveViewPropertiesLocally->setEnabled( canWrite ); m_paRemoveLocalProperties->setEnabled( canWrite ); } void KonqMainWindow::slotURLEntered( const TQString &text, int state ) { if ( m_bURLEnterLock || text.isEmpty() ) return; m_bURLEnterLock = true; if (state & ControlButton || state & AltButton) { m_combo->setURL( m_currentView ? m_currentView->url().prettyURL() : TQString::null ); openFilteredURL( text.stripWhiteSpace(), true ); } else openFilteredURL( text.stripWhiteSpace() ); m_bURLEnterLock = false; } void KonqMainWindow::slotFileNewAboutToShow() { // As requested by KNewMenu : m_pMenuNew->slotCheckUpToDate(); // And set the files that the menu apply on : m_pMenuNew->setPopupFiles( KURL( m_currentView->url().url() ) ); } void KonqMainWindow::slotSplitViewHorizontal() { KonqView * newView = m_pViewManager->splitView( Qt::Horizontal ); if (newView == 0L) return; newView->openURL( m_currentView->url(), m_currentView->locationBarURL() ); } void KonqMainWindow::slotSplitViewVertical() { KonqView * newView = m_pViewManager->splitView( Qt::Vertical ); if (newView == 0L) return; newView->openURL( m_currentView->url(), m_currentView->locationBarURL() ); } void KonqMainWindow::slotAddTab() { KonqView* newView = m_pViewManager->addTab(TQString("text/html"), // this is what about:blank will use anyway TQString::null, false, KonqSettings::openAfterCurrentPage()); if (newView == 0L) return; openURL( newView, KURL("about:blank"),TQString::null); m_pViewManager->showTab( newView ); focusLocationBar(); m_pWorkingTab = 0L; } void KonqMainWindow::slotDuplicateTab() { m_pViewManager->duplicateTab( 0, KonqSettings::openAfterCurrentPage() ); } void KonqMainWindow::slotDuplicateTabPopup() { m_pViewManager->duplicateTab( m_pWorkingTab, KonqSettings::openAfterCurrentPage() ); } void KonqMainWindow::slotBreakOffTab() { if (m_currentView && m_currentView->part() && (m_currentView->part()->tqmetaObject()->findProperty("modified") != -1) ) { TQVariant prop = m_currentView->part()->property("modified"); if (prop.isValid() && prop.toBool()) if ( KMessageBox::warningContinueCancel( this, i18n("This tab tqcontains changes that have not been submitted.\nDetaching the tab will discard these changes."), i18n("Discard Changes?"), KGuiItem(i18n("&Discard Changes"),"tab_breakoff"), "discardchangesdetach") != KMessageBox::Continue ) return; } m_pViewManager->breakOffTab(); updateViewActions(); } void KonqMainWindow::slotBreakOffTabPopup() { KonqView* originalView = m_currentView; KonqView *view = m_pWorkingTab->activeChildView(); if (view && view->part() && (view->part()->tqmetaObject()->findProperty("modified") != -1) ) { TQVariant prop = view->part()->property("modified"); if (prop.isValid() && prop.toBool()) { m_pViewManager->showTab( view ); if ( KMessageBox::warningContinueCancel( this, i18n("This tab tqcontains changes that have not been submitted.\nDetaching the tab will discard these changes."), i18n("Discard Changes?"), KGuiItem(i18n("&Discard Changes"),"tab_breakoff"), "discardchangesdetach") != KMessageBox::Continue ) { m_pViewManager->showTab( originalView ); return; } } } m_pViewManager->showTab( originalView ); //Can't do this safely here as the tabbar may disappear and we're //hanging off here. TQTimer::singleShot(0, this, TQT_SLOT( slotBreakOffTabPopupDelayed() ) ); } void KonqMainWindow::slotBreakOffTabPopupDelayed() { m_pViewManager->breakOffTab( m_pWorkingTab ); updateViewActions(); } void KonqMainWindow::slotPopupNewWindow() { kdDebug(1202) << "KonqMainWindow::slotPopupNewWindow()" << endl; KFileItemListIterator it ( popupItems ); for ( ; it.current(); ++it ) { KonqMisc::createNewWindow( (*it)->url(), popupUrlArgs ); } } void KonqMainWindow::slotPopupThisWindow() { kdDebug(1202) << "KonqMainWindow::slotPopupThisWindow()" << endl; openURL( 0L, popupItems.getFirst()->url() ); } void KonqMainWindow::slotPopupNewTab() { bool openAfterCurrentPage = KonqSettings::openAfterCurrentPage(); bool newTabsInFront = KonqSettings::newTabsInFront(); if (KApplication::keyboardMouseState() & Qt::ShiftButton) newTabsInFront = !newTabsInFront; popupNewTab(newTabsInFront, openAfterCurrentPage); } void KonqMainWindow::slotPopupNewTabRight() { bool newTabsInFront = KonqSettings::newTabsInFront(); if (KApplication::keyboardMouseState() & ShiftButton) newTabsInFront = !newTabsInFront; popupNewTab(newTabsInFront, false); } void KonqMainWindow::popupNewTab(bool infront, bool openAfterCurrentPage) { kdDebug(1202) << "KonqMainWindow::popupNewTab()" << endl; KFileItemListIterator it ( popupItems ); KonqOpenURLRequest req; req.newTab = true; req.newTabInFront = false; req.openAfterCurrentPage = openAfterCurrentPage; req.args = popupUrlArgs; for ( ; it.current(); ++it ) { if ( infront && it.atLast() ) { req.newTabInFront = true; } openURL( 0L, (*it)->url(), TQString::null, req ); } } void KonqMainWindow::openMultiURL( KURL::List url ) { KURL::List::ConstIterator it = url.begin(); KURL::List::ConstIterator end = url.end(); for (; it != end; ++it ) { KonqView* newView = m_pViewManager->addTab(); Q_ASSERT( newView ); if (newView == 0L) continue; openURL( newView, *it,TQString::null); m_pViewManager->showTab( newView ); focusLocationBar(); m_pWorkingTab = 0L; } } void KonqMainWindow::slotRemoveView() { if (m_currentView && m_currentView->part() && (m_currentView->part()->tqmetaObject()->findProperty("modified") != -1) ) { TQVariant prop = m_currentView->part()->property("modified"); if (prop.isValid() && prop.toBool()) if ( KMessageBox::warningContinueCancel( this, i18n("This view tqcontains changes that have not been submitted.\nClosing the view will discard these changes."), i18n("Discard Changes?"), KGuiItem(i18n("&Discard Changes"),"view_remove"), "discardchangesclose") != KMessageBox::Continue ) return; } // takes care of choosing the new active view m_pViewManager->removeView( m_currentView ); } void KonqMainWindow::slotRemoveTab() { if (m_currentView && m_currentView->part() && (m_currentView->part()->tqmetaObject()->findProperty("modified") != -1) ) { TQVariant prop = m_currentView->part()->property("modified"); if (prop.isValid() && prop.toBool()) if ( KMessageBox::warningContinueCancel( this, i18n("This tab tqcontains changes that have not been submitted.\nClosing the tab will discard these changes."), i18n("Discard Changes?"), KGuiItem(i18n("&Discard Changes"),"tab_remove"), "discardchangesclose") != KMessageBox::Continue ) return; } m_pViewManager->removeTab(); } void KonqMainWindow::slotRemoveTabPopup() { KonqView *originalView = m_currentView; KonqView *view = m_pWorkingTab->activeChildView(); if (view && view->part() && (view->part()->tqmetaObject()->findProperty("modified") != -1) ) { TQVariant prop = view->part()->property("modified"); if (prop.isValid() && prop.toBool()) { m_pViewManager->showTab( view ); if ( KMessageBox::warningContinueCancel( this, i18n("This tab tqcontains changes that have not been submitted.\nClosing the tab will discard these changes."), i18n("Discard Changes?"), KGuiItem(i18n("&Discard Changes"),"tab_remove"), "discardchangesclose") != KMessageBox::Continue ) { m_pViewManager->showTab( originalView ); return; } } m_pViewManager->showTab( originalView ); } //Can't do immediately - may kill the tabbar, and we're in an event path down from it TQTimer::singleShot( 0, this, TQT_SLOT( slotRemoveTabPopupDelayed() ) ); } void KonqMainWindow::slotRemoveTabPopupDelayed() { m_pViewManager->removeTab( m_pWorkingTab ); } void KonqMainWindow::slotRemoveOtherTabsPopup() { if ( KMessageBox::warningContinueCancel( this, i18n("Do you really want to close all other tabs?"), i18n("Close Other Tabs Confirmation"), KGuiItem(i18n("Close &Other Tabs"),"tab_remove_other"), "CloseOtherTabConfirm") != KMessageBox::Continue ) return; KonqView *originalView = m_currentView; MapViews::ConstIterator it = m_mapViews.begin(); MapViews::ConstIterator end = m_mapViews.end(); for (; it != end; ++it ) { KonqView *view = it.data(); if ( view != originalView && view && view->part() && (view->part()->tqmetaObject()->findProperty("modified") != -1) ) { TQVariant prop = view->part()->property("modified"); if (prop.isValid() && prop.toBool()) { m_pViewManager->showTab( view ); if ( KMessageBox::warningContinueCancel( this, i18n("This tab tqcontains changes that have not been submitted.\nClosing other tabs will discard these changes."), i18n("Discard Changes?"), KGuiItem(i18n("&Discard Changes"),"tab_remove"), "discardchangescloseother") != KMessageBox::Continue ) { m_pViewManager->showTab( originalView ); return; } } } } m_pViewManager->showTab( originalView ); //Can't do immediately - kills the tabbar, and we're in an event path down from it TQTimer::singleShot( 0, this, TQT_SLOT( slotRemoveOtherTabsPopupDelayed() ) ); } void KonqMainWindow::slotRemoveOtherTabsPopupDelayed() { m_pViewManager->removeOtherTabs( m_pWorkingTab ); updateViewActions(); } void KonqMainWindow::slotReloadAllTabs() { KonqView *originalView = m_currentView; MapViews::ConstIterator it = m_mapViews.begin(); MapViews::ConstIterator end = m_mapViews.end(); for (; it != end; ++it ) { KonqView *view = it.data(); if (view && view->part() && (view->part()->tqmetaObject()->findProperty("modified") != -1) ) { TQVariant prop = view->part()->property("modified"); if (prop.isValid() && prop.toBool()) { m_pViewManager->showTab( view ); if ( KMessageBox::warningContinueCancel( this, i18n("This tab tqcontains changes that have not been submitted.\nReloading all tabs will discard these changes."), i18n("Discard Changes?"), KGuiItem(i18n("&Discard Changes"),"reload"), "discardchangesreload") != KMessageBox::Continue ) { m_pViewManager->showTab( originalView ); return; } } } } m_pViewManager->showTab( originalView ); m_pViewManager->reloadAllTabs(); updateViewActions(); } void KonqMainWindow::slotActivateNextTab() { m_pViewManager->activateNextTab(); } void KonqMainWindow::slotActivatePrevTab() { m_pViewManager->activatePrevTab(); } void KonqMainWindow::slotActivateTab() { m_pViewManager->activateTab( TQString( sender()->name() ).right( 2 ).toInt() -1 ); } void KonqMainWindow::slotDumpDebugInfo() { #ifndef NDEBUG dumpViewList(); m_pViewManager->printFullHierarchy( 0L ); #endif } void KonqMainWindow::slotSaveViewPropertiesLocally() { m_bSaveViewPropertiesLocally = !m_bSaveViewPropertiesLocally; // And this is a main-view setting, so save it KonqSettings::setSaveViewPropertiesLocally( m_bSaveViewPropertiesLocally ); KonqSettings::writeConfig(); // Now tell the views MapViews::ConstIterator it = m_mapViews.begin(); MapViews::ConstIterator end = m_mapViews.end(); for (; it != end; ++it ) (*it)->callExtensionBoolMethod( "setSaveViewPropertiesLocally(bool)", m_bSaveViewPropertiesLocally ); } void KonqMainWindow::slotRemoveLocalProperties() { assert( m_currentView ); KURL u ( m_currentView->url() ); u.addPath(".directory"); if ( u.isLocalFile() ) { TQFile f( u.path() ); if ( f.open(IO_ReadWrite) ) { f.close(); KSimpleConfig config( u.path() ); config.deleteGroup( "URL properties" ); // Bye bye config.sync(); // TODO: Notify the view... // Or the hard way: (and hoping it doesn't cache the values!) slotReload(); } else { Q_ASSERT( TQFile::exists(u.path()) ); // The action shouldn't be enabled, otherwise. KMessageBox::sorry( this, i18n("No permissions to write to %1").arg(u.path()) ); } } } bool KonqMainWindow::askForTarget(const TQString& text, KURL& url) { const KURL initialUrl = (viewCount()==2) ? otherView(m_currentView)->url() : m_currentView->url(); TQString label = text.arg( m_currentView->url().pathOrURL() ); KURLRequesterDlg dlg(initialUrl.pathOrURL(), label, this, "urlrequester", true); dlg.setCaption(i18n("Enter Target")); dlg.urlRequester()->setMode( KFile::File | KFile::ExistingOnly | KFile::Directory ); if (dlg.exec()) { url = dlg.selectedURL(); if ( url.isValid() ) return true; else { KMessageBox::error( this, i18n("%1 is not valid").arg(url.url())); return false; } } return false; } void KonqMainWindow::slotRequesterClicked( KURLRequester *req ) { req->fileDialog()->setMode(KFile::Directory|KFile::ExistingOnly); } void KonqMainWindow::slotCopyFiles() { //kdDebug(1202) << "KonqMainWindow::slotCopyFiles()" << endl; KURL dest; if (!askForTarget(i18n("Copy selected files from %1 to:"),dest)) return; KonqOperations::copy(this,KonqOperations::COPY,currentURLs(),dest); } void KonqMainWindow::slotMoveFiles() { //kdDebug(1202) << "KonqMainWindow::slotMoveFiles()" << endl; KURL dest; if (!askForTarget(i18n("Move selected files from %1 to:"),dest)) return; KonqOperations::copy(this,KonqOperations::MOVE,currentURLs(),dest); } void KonqMainWindow::slotNewDir() { Q_ASSERT( m_currentView ); if ( m_currentView ) KonqOperations::newDir(this, m_currentView->url()); } KURL::List KonqMainWindow::currentURLs() const { KURL::List urls; if ( m_currentView ) { urls.append( m_currentView->url() ); if ( m_currentView->part()->inherits("KonqDirPart") ) { KFileItemList tmpList= static_cast(m_currentView->part())->selectedFileItems(); KFileItem *item=tmpList.first(); if (item) // Return list of selected items only if we have a selection { urls.clear(); for (; item!=0; item=tmpList.next()) urls.append(item->url()); } } } return urls; } // Only valid if there are one or two views KonqView * KonqMainWindow::otherView( KonqView * view ) const { assert( viewCount() <= 2 ); MapViews::ConstIterator it = m_mapViews.begin(); if ( (*it) == view ) ++it; if ( it != m_mapViews.end() ) return (*it); return 0L; } void KonqMainWindow::slotSaveViewProfile() { #if 0 if ( m_pViewManager->currentProfile().isEmpty() ) { // The action should be disabled........... kdWarning(1202) << "No known profile. Use the Save Profile dialog box" << endl; } else { m_pViewManager->saveViewProfile( m_pViewManager->currentProfile(), m_pViewManager->currentProfileText(), false /* URLs */, true /* size */ ); } #endif m_pViewManager->showProfileDlg( m_pViewManager->currentProfile() ); } void KonqMainWindow::slotUpAboutToShow() { TQPopupMenu *popup = m_paUp->popupMenu(); popup->clear(); uint i = 0; // Use the location bar URL, because in case we display a index.html // we want to go up from the dir, not from the index.html KURL u( m_currentView->locationBarURL() ); u = u.upURL(); while ( u.hasPath() ) { popup->insertItem( KonqPixmapProvider::self()->pixmapFor( u.url() ), u.pathOrURL() ); if ( u.path() == "/" ) break; if ( ++i > 10 ) break; u = u.upURL(); } } void KonqMainWindow::slotUp(KAction::ActivationReason, Qt::ButtonState state) { m_goState = state; TQTimer::singleShot( 0, this, TQT_SLOT( slotUpDelayed() ) ); } void KonqMainWindow::slotUp() { m_goState = Qt::LeftButton; TQTimer::singleShot( 0, this, TQT_SLOT( slotUpDelayed() ) ); } void KonqMainWindow::slotUpDelayed() { KonqOpenURLRequest req; req.newTab = true; req.openAfterCurrentPage = KonqSettings::openAfterCurrentPage(); req.newTabInFront = KonqSettings::newTabsInFront(); if (m_goState & Qt::ShiftButton) req.newTabInFront = !req.newTabInFront; const TQString& url = m_currentView->upURL().url(); if(m_goState & Qt::ControlButton) openFilteredURL(url, req ); else if(m_goState & Qt::MidButton) { if(KonqSettings::mmbOpensTab()) openFilteredURL( url, req); else KonqMisc::createNewWindow( url ); } else openFilteredURL( url, false ); m_goState = Qt::LeftButton; } void KonqMainWindow::slotUpActivated( int id ) { KURL u( m_currentView->locationBarURL() ); kdDebug(1202) << "slotUpActivated. Start URL is " << u << endl; for ( int i = 0 ; i < m_paUp->popupMenu()->indexOf( id ) + 1 ; i ++ ) u = u.upURL(); openURL( 0L, u ); } void KonqMainWindow::slotGoMenuAboutToShow() { kdDebug(1202) << "KonqMainWindow::slotGoMenuAboutToShow" << endl; if ( m_paHistory && m_currentView ) // (maybe this is before initialisation) m_paHistory->fillGoMenu( m_currentView->history() ); } void KonqMainWindow::slotGoHistoryActivated( int steps ) { slotGoHistoryActivated( steps, Qt::LeftButton ); } void KonqMainWindow::slotGoHistoryActivated( int steps, Qt::ButtonState state ) { kdDebug() <<"slotGoHistoryActivated( "<addTabFromHistory( m_goBuffer, openAfterCurrentPage ); if (newView && inFront) m_pViewManager->showTab( newView ); } else if(m_goState & Qt::MidButton) { if(mmbOpensTab) { KonqView * newView = m_pViewManager->addTabFromHistory( m_goBuffer, openAfterCurrentPage ); if (newView && inFront) m_pViewManager->showTab( newView ); } else KonqMisc::newWindowFromHistory(this->currentView(), m_goBuffer); } else { m_currentView->go( m_goBuffer ); makeViewsFollow(m_currentView->url(), KParts::URLArgs(),m_currentView->serviceType(),m_currentView); } m_goBuffer = 0; m_goState = Qt::LeftButton; } void KonqMainWindow::slotBackAboutToShow() { m_paBack->popupMenu()->clear(); if ( m_currentView ) KonqBidiHistoryAction::fillHistoryPopup( m_currentView->history(), m_paBack->popupMenu(), true, false ); } void KonqMainWindow::slotBack() { slotGoHistoryActivated(-1); } void KonqMainWindow::slotBack(KAction::ActivationReason, Qt::ButtonState state) { slotGoHistoryActivated( -1, state ); } void KonqMainWindow::slotBackActivated( int id ) { slotGoHistoryActivated( -(m_paBack->popupMenu()->indexOf( id ) + 1), m_paBack->popupMenu()->state()); } void KonqMainWindow::slotForwardAboutToShow() { m_paForward->popupMenu()->clear(); if ( m_currentView ) KonqBidiHistoryAction::fillHistoryPopup( m_currentView->history(), m_paForward->popupMenu(), false, true ); } void KonqMainWindow::slotForward() { slotGoHistoryActivated( 1 ); } void KonqMainWindow::slotForward(KAction::ActivationReason, Qt::ButtonState state) { slotGoHistoryActivated( 1, state ); } void KonqMainWindow::slotForwardActivated( int id ) { slotGoHistoryActivated( m_paForward->popupMenu()->indexOf( id ) + 1, m_paForward->popupMenu()->state() ); } void KonqMainWindow::initCombo() { m_combo = new KonqCombo( 0L, "history combo"); m_combo->init( s_pCompletion ); connect( m_combo, TQT_SIGNAL(activated(const TQString&,int)), this, TQT_SLOT(slotURLEntered(const TQString&,int)) ); connect( m_combo, TQT_SIGNAL(showPageSecurity()), this, TQT_SLOT(showPageSecurity()) ); m_pURLCompletion = new KURLCompletion(); m_pURLCompletion->setCompletionMode( s_pCompletion->completionMode() ); // This only turns completion off. ~ is still there in the result // We do want completion of user names, right? //m_pURLCompletion->setReplaceHome( false ); // Leave ~ alone! Will be taken care of by filters!! connect( m_combo, TQT_SIGNAL(completionModeChanged(KGlobalSettings::Completion)), TQT_SLOT( slotCompletionModeChanged( KGlobalSettings::Completion ))); connect( m_combo, TQT_SIGNAL( completion( const TQString& )), TQT_SLOT( slotMakeCompletion( const TQString& ))); connect( m_combo, TQT_SIGNAL( substringCompletion( const TQString& )), TQT_SLOT( slotSubstringcompletion( const TQString& ))); connect( m_combo, TQT_SIGNAL( textRotation( KCompletionBase::KeyBindingType) ), TQT_SLOT( slotRotation( KCompletionBase::KeyBindingType ))); connect( m_combo, TQT_SIGNAL( cleared() ), TQT_SLOT ( slotClearHistory() ) ); connect( m_pURLCompletion, TQT_SIGNAL( match(const TQString&) ), TQT_SLOT( slotMatch(const TQString&) )); m_combo->lineEdit()->installEventFilter(this); static bool bookmarkCompletionInitialized = false; if ( !bookmarkCompletionInitialized ) { bookmarkCompletionInitialized = true; DelayedInitializer *initializer = new DelayedInitializer( TQEvent::KeyPress, m_combo->lineEdit() ); connect( initializer, TQT_SIGNAL( initialize() ), this, TQT_SLOT( bookmarksIntoCompletion() ) ); } } void KonqMainWindow::bookmarksIntoCompletion() { // add all bookmarks to the completion list for easy access bookmarksIntoCompletion( KonqBookmarkManager::self()->root() ); } // the user changed the completion mode in the combo void KonqMainWindow::slotCompletionModeChanged( KGlobalSettings::Completion m ) { s_pCompletion->setCompletionMode( m ); KonqSettings::setSettingsCompletionMode( (int)m_combo->completionMode() ); KonqSettings::writeConfig(); // tell the other windows too (only this instance currently) KonqMainWindow *window = s_lstViews->first(); while ( window ) { if ( window->m_combo ) { window->m_combo->setCompletionMode( m ); window->m_pURLCompletion->setCompletionMode( m ); } window = s_lstViews->next(); } } // at first, try to find a completion in the current view, then use the global // completion (history) void KonqMainWindow::slotMakeCompletion( const TQString& text ) { if( m_pURLCompletion ) { m_urlCompletionStarted = true; // flag for slotMatch() // kdDebug(1202) << "Local Completion object found!" << endl; TQString completion = m_pURLCompletion->makeCompletion( text ); m_currentDir = TQString::null; if ( completion.isNull() && !m_pURLCompletion->isRunning() ) { // No match() signal will come from m_pURLCompletion // ask the global one // tell the static completion object about the current completion mode completion = s_pCompletion->makeCompletion( text ); // some special handling necessary for CompletionPopup if ( m_combo->completionMode() == KGlobalSettings::CompletionPopup || m_combo->completionMode() == KGlobalSettings::CompletionPopupAuto ) m_combo->setCompletedItems( historyPopupCompletionItems( text ) ); else if ( !completion.isNull() ) m_combo->setCompletedText( completion ); } else { // To be continued in slotMatch()... if( !m_pURLCompletion->dir().isEmpty() ) m_currentDir = m_pURLCompletion->dir(); } } // kdDebug(1202) << "Current dir: " << m_currentDir << " Current text: " << text << endl; } void KonqMainWindow::slotSubstringcompletion( const TQString& text ) { bool filesFirst = currentURL().startsWith( "/" ) || currentURL().startsWith( "file:/" ); TQStringList items; if ( filesFirst && m_pURLCompletion ) items = m_pURLCompletion->substringCompletion( text ); items += s_pCompletion->substringCompletion( text ); if ( !filesFirst && m_pURLCompletion ) items += m_pURLCompletion->substringCompletion( text ); m_combo->setCompletedItems( items ); } void KonqMainWindow::slotRotation( KCompletionBase::KeyBindingType type ) { // Tell slotMatch() to do nothing m_urlCompletionStarted = false; bool prev = (type == KCompletionBase::PrevCompletionMatch); if ( prev || type == KCompletionBase::NextCompletionMatch ) { TQString completion = prev ? m_pURLCompletion->previousMatch() : m_pURLCompletion->nextMatch(); if( completion.isNull() ) { // try the history KCompletion object completion = prev ? s_pCompletion->previousMatch() : s_pCompletion->nextMatch(); } if ( completion.isEmpty() || completion == m_combo->currentText() ) return; m_combo->setCompletedText( completion ); } } // Handle match() from m_pURLCompletion void KonqMainWindow::slotMatch( const TQString &match ) { if ( match.isEmpty() ) // this case is handled directly return; // Check flag to avoid match() raised by rotation if ( m_urlCompletionStarted ) { m_urlCompletionStarted = false; // some special handling necessary for CompletionPopup if ( m_combo->completionMode() == KGlobalSettings::CompletionPopup || m_combo->completionMode() == KGlobalSettings::CompletionPopupAuto ) { TQStringList items = m_pURLCompletion->allMatches(); items += historyPopupCompletionItems( m_combo->currentText() ); // items.sort(); // should we? m_combo->setCompletedItems( items ); } else if ( !match.isNull() ) m_combo->setCompletedText( match ); } } void KonqMainWindow::slotCtrlTabPressed() { KonqView * view = m_pViewManager->chooseNextView( m_currentView ); if ( view ) m_pViewManager->setActivePart( view->part() ); } void KonqMainWindow::slotClearHistory() { KonqHistoryManager::kself()->emitClear(); } void KonqMainWindow::slotClearComboHistory() { if (m_combo && m_combo->count()) m_combo->clearHistory(); } bool KonqMainWindow::eventFilter(TQObject*obj,TQEvent *ev) { if ( ( ev->type()==TQEvent::FocusIn || ev->type()==TQEvent::FocusOut ) && m_combo && m_combo->lineEdit() == obj ) { //kdDebug(1202) << "KonqMainWindow::eventFilter " << obj << " " << obj->className() << " " << obj->name() << endl; TQFocusEvent * focusEv = static_cast(ev); if (focusEv->reason() == TQFocusEvent::Popup) { return KParts::MainWindow::eventFilter( obj, ev ); } KParts::BrowserExtension * ext = 0; if ( m_currentView ) ext = m_currentView->browserExtension(); TQStrList slotNames; if (ext) slotNames = ext->tqmetaObject()->slotNames(); //for ( char * s = slotNames.first() ; s ; s = slotNames.next() ) //{ // kdDebug(1202) << "slotNames=" << s << endl; //} if (ev->type()==TQEvent::FocusIn) { //kdDebug(1202) << "ComboBox got the focus..." << endl; if (m_bLocationBarConnected) { //kdDebug(1202) << "Was already connected..." << endl; return KParts::MainWindow::eventFilter( obj, ev ); } m_bLocationBarConnected = true; // Workaround for Qt issue: usually, TQLineEdit reacts on Ctrl-D, // but the duplicate_window action also has Ctrl-D as accel and // prevents the lineedit from getting this event. IMHO the accel // should be disabled in favor of the focus-widget. KAction *duplicate = actionCollection()->action("duplicate_window"); if ( duplicate->shortcut() == TQKeySequence(CTRL+Key_D) ) duplicate->setEnabled( false ); if (slotNames.tqcontains("cut()")) disconnect( m_paCut, TQT_SIGNAL( activated() ), ext, TQT_SLOT( cut() ) ); if (slotNames.tqcontains("copy()")) disconnect( m_paCopy, TQT_SIGNAL( activated() ), ext, TQT_SLOT( copy() ) ); if (slotNames.tqcontains("paste()")) disconnect( m_paPaste, TQT_SIGNAL( activated() ), ext, TQT_SLOT( paste() ) ); if (slotNames.tqcontains("del()")) disconnect( m_paDelete, TQT_SIGNAL( activated() ), ext, TQT_SLOT( del() ) ); disconnect( m_paTrash, TQT_SIGNAL( activated( KAction::ActivationReason, Qt::ButtonState ) ), this, TQT_SLOT( slotTrashActivated( KAction::ActivationReason, Qt::ButtonState ) ) ); connect( m_paCut, TQT_SIGNAL( activated() ), m_combo->lineEdit(), TQT_SLOT( cut() ) ); connect( m_paCopy, TQT_SIGNAL( activated() ), m_combo->lineEdit(), TQT_SLOT( copy() ) ); connect( m_paPaste, TQT_SIGNAL( activated() ), m_combo->lineEdit(), TQT_SLOT( paste() ) ); connect( TQApplication::clipboard(), TQT_SIGNAL(dataChanged()), this, TQT_SLOT(slotClipboardDataChanged()) ); connect( m_combo->lineEdit(), TQT_SIGNAL(textChanged(const TQString &)), this, TQT_SLOT(slotCheckComboSelection()) ); connect( m_combo->lineEdit(), TQT_SIGNAL(selectionChanged()), this, TQT_SLOT(slotCheckComboSelection()) ); m_paTrash->setEnabled(false); m_paDelete->setEnabled(false); slotClipboardDataChanged(); } else if ( ev->type()==TQEvent::FocusOut) { //kdDebug(1202) << "ComboBox lost focus..." << endl; if (!m_bLocationBarConnected) { //kdDebug(1202) << "Was already disconnected..." << endl; return KParts::MainWindow::eventFilter( obj, ev ); } m_bLocationBarConnected = false; // see above in FocusIn for explanation // we use new_window as reference, as it's always in the same state // as duplicate_window KAction *duplicate = actionCollection()->action("duplicate_window"); if ( duplicate->shortcut() == TQKeySequence(CTRL+Key_D) ) duplicate->setEnabled( actionCollection()->action("new_window")->isEnabled() ); if (slotNames.tqcontains("cut()")) connect( m_paCut, TQT_SIGNAL( activated() ), ext, TQT_SLOT( cut() ) ); if (slotNames.tqcontains("copy()")) connect( m_paCopy, TQT_SIGNAL( activated() ), ext, TQT_SLOT( copy() ) ); if (slotNames.tqcontains("paste()")) connect( m_paPaste, TQT_SIGNAL( activated() ), ext, TQT_SLOT( paste() ) ); if (slotNames.tqcontains("del()")) connect( m_paDelete, TQT_SIGNAL( activated() ), ext, TQT_SLOT( del() ) ); connect( m_paTrash, TQT_SIGNAL( activated( KAction::ActivationReason, Qt::ButtonState ) ), this, TQT_SLOT( slotTrashActivated( KAction::ActivationReason, Qt::ButtonState ) ) ); disconnect( m_paCut, TQT_SIGNAL( activated() ), m_combo->lineEdit(), TQT_SLOT( cut() ) ); disconnect( m_paCopy, TQT_SIGNAL( activated() ), m_combo->lineEdit(), TQT_SLOT( copy() ) ); disconnect( m_paPaste, TQT_SIGNAL( activated() ), m_combo->lineEdit(), TQT_SLOT( paste() ) ); disconnect( TQApplication::clipboard(), TQT_SIGNAL(dataChanged()), this, TQT_SLOT(slotClipboardDataChanged()) ); disconnect( m_combo->lineEdit(), TQT_SIGNAL(textChanged(const TQString &)), this, TQT_SLOT(slotCheckComboSelection()) ); disconnect( m_combo->lineEdit(), TQT_SIGNAL(selectionChanged()), this, TQT_SLOT(slotCheckComboSelection()) ); if ( ext ) { m_paCut->setEnabled( ext->isActionEnabled( "cut" ) ); m_paCopy->setEnabled( ext->isActionEnabled( "copy" ) ); m_paPaste->setEnabled( ext->isActionEnabled( "paste" ) ); m_paDelete->setEnabled( ext->isActionEnabled( "delete" ) ); m_paTrash->setEnabled( ext->isActionEnabled( "trash" ) ); } else { m_paCut->setEnabled( false ); m_paCopy->setEnabled( false ); m_paPaste->setEnabled( false ); m_paDelete->setEnabled( false ); m_paTrash->setEnabled( false ); } } } return KParts::MainWindow::eventFilter( obj, ev ); } void KonqMainWindow::slotClipboardDataChanged() { //kdDebug(1202) << "KonqMainWindow::slotClipboardDataChanged()" << endl; TQMimeSource *data = TQApplication::clipboard()->data(); m_paPaste->setEnabled( data->provides( "text/plain" ) ); slotCheckComboSelection(); } void KonqMainWindow::slotCheckComboSelection() { //kdDebug(1202) << "m_combo->lineEdit()->hasMarkedText() : " << hasSelection << endl; bool hasSelection = m_combo->lineEdit()->hasSelectedText(); m_paCopy->setEnabled( hasSelection ); m_paCut->setEnabled( hasSelection ); } void KonqMainWindow::slotClearLocationBar( KAction::ActivationReason, Qt::ButtonState state ) { kdDebug(1202) << "slotClearLocationBar" << endl; slotStop(); m_combo->clearTemporary(); focusLocationBar(); if ( state & Qt::MidButton ) m_combo->setURL( TQApplication::clipboard()->text( QClipboard::Selection ) ); } void KonqMainWindow::slotForceSaveMainWindowSettings() { // kdDebug(1202)<<"slotForceSaveMainWindowSettings()"<sync(); } } void KonqMainWindow::slotShowMenuBar() { if (menuBar()->isVisible()) menuBar()->hide(); else menuBar()->show(); slotForceSaveMainWindowSettings(); } void KonqMainWindow::slotUpdateFullScreen( bool set ) { if( set ) { showFullScreen(); // Create toolbar button for exiting from full-screen mode // ...but only if there isn't one already... bool haveFullScreenButton = false; //Walk over the toolbars and check whether there is a show fullscreen button in any of them TQPtrListIterator barIt = toolBarIterator(); for (; barIt.current(); ++barIt ) { //Are we plugged here, in a visible toolbar? if (barIt.current()->isVisible() && action( "fullscreen" )->isPlugged(barIt.current())) { haveFullScreenButton = true; break; } } if (!haveFullScreenButton) { TQPtrList lst; lst.append( m_ptaFullScreen ); plugActionList( "fullscreen", lst ); } m_prevMenuBarVisible = menuBar()->isVisible(); menuBar()->hide(); m_paShowMenuBar->setChecked( false ); // Qt bug, the flags are lost. They know about it. // happens only with the hackish non-_NET_WM_STATE_FULLSCREEN way setWFlags( WDestructiveClose ); // Qt bug (see below) setAcceptDrops( FALSE ); topData()->dnd = 0; setAcceptDrops( TRUE ); } else { #if QT_VERSION >= 0x030300 setWindowState( windowState() & ~WindowFullScreen ); #else if( isMaximized()) { showNormal(); showMaximized(); // showNormal() would reset maximize state } else showNormal(); #endif unplugActionList( "fullscreen" ); if (m_prevMenuBarVisible) { menuBar()->show(); m_paShowMenuBar->setChecked( true ); } // Qt bug, the flags aren't restored. They know about it. setWFlags( WType_TopLevel | WDestructiveClose ); // Other Qt bug setAcceptDrops( FALSE ); topData()->dnd = 0; setAcceptDrops( TRUE ); } } void KonqMainWindow::setLocationBarURL( const KURL &url ) { setLocationBarURL( url.pathOrURL() ); } void KonqMainWindow::setLocationBarURL( const TQString &url ) { kdDebug(1202) << "KonqMainWindow::setLocationBarURL: url = " << url << endl; m_combo->setURL( url ); setIcon( KonqPixmapProvider::self()->pixmapFor( url ) ); } void KonqMainWindow::setPageSecurity( PageSecurity pageSecurity ) { m_combo->setPageSecurity( pageSecurity ); } void KonqMainWindow::showPageSecurity() { if ( m_currentView && m_currentView->part() ) { KAction *act = m_currentView->part()->action( "security" ); if ( act ) act->activate(); } } // called via DCOP from KonquerorIface void KonqMainWindow::comboAction( int action, const TQString& url, const TQCString& objId ) { if (!s_lstViews) // this happens in "konqueror --silent" return; KonqCombo *combo = 0L; KonqMainWindow *window = s_lstViews->first(); while ( window ) { if ( window->m_combo ) { combo = window->m_combo; switch ( action ) { case ComboAdd: combo->insertPermanent( url ); break; case ComboClear: combo->clearHistory(); break; case ComboRemove: combo->removeURL( url ); break; default: break; } } window = s_lstViews->next(); } // only one instance should save... if ( combo && objId == kapp->dcopClient()->defaultObject() ) combo->saveItems(); } TQString KonqMainWindow::locationBarURL() const { return m_combo->currentText(); } void KonqMainWindow::focusLocationBar() { if ( m_combo->isVisible() || !isVisible() ) m_combo->setFocus(); } void KonqMainWindow::startAnimation() { //kdDebug(1202) << "KonqMainWindow::startAnimation" << endl; m_paAnimatedLogo->start(); m_paStop->setEnabled( true ); toggleReloadStopButton( true ); } void KonqMainWindow::stopAnimation() { //kdDebug(1202) << "KonqMainWindow::stopAnimation" << endl; m_paAnimatedLogo->stop(); m_paStop->setEnabled( false ); toggleReloadStopButton( false ); } void KonqMainWindow::setUpEnabled( const KURL &url ) { //kdDebug(1202) << "KonqMainWindow::setUpEnabled(" << url << ")" << endl; //kdDebug(1202) << "hasPath=" << url.hasPath() << endl; bool bHasUpURL = false; bHasUpURL = ( ( url.hasPath() && url.path() != "/" && ( url.path()[0]=='/' ) ) || !url.query().isEmpty() /*e.g. lists.kde.org*/ ); if ( !bHasUpURL ) bHasUpURL = url.hasSubURL(); m_paUp->setEnabled( bHasUpURL ); } void KonqMainWindow::initActions() { actionCollection()->setHighlightingEnabled( true ); connectActionCollection( actionCollection() ); // Note about this method : don't call setEnabled() on any of the actions. // They are all disabled then re-enabled with enableAllActions // If any one needs to be initially disabled, put that code in enableAllActions // File menu m_pMenuNew = new KNewMenu ( actionCollection(), this, "new_menu" ); TQObject::connect( m_pMenuNew->popupMenu(), TQT_SIGNAL(aboutToShow()), this, TQT_SLOT(slotFileNewAboutToShow()) ); (void) new KAction( i18n( "&Edit File Type..." ), 0, actionCollection(), "editMimeType" ); (void) new KAction( i18n( "Properties" ), ALT+Key_Return, actionCollection(), "properties" ); (void) new KAction( i18n( "New &Window" ), "window_new", KStdAccel::shortcut(KStdAccel::New), this, TQT_SLOT( slotNewWindow() ), actionCollection(), "new_window" ); (void) new KAction( i18n( "&Duplicate Window" ), "window_duplicate", CTRL+Key_D, this, TQT_SLOT( slotDuplicateWindow() ), actionCollection(), "duplicate_window" ); (void) new KAction( i18n( "Send &Link Address..." ), "mail_generic", 0, this, TQT_SLOT( slotSendURL() ), actionCollection(), "sendURL" ); (void) new KAction( i18n( "S&end File..." ), "mail_generic", 0, this, TQT_SLOT( slotSendFile() ), actionCollection(), "sendPage" ); if (kapp->authorize("shell_access")) { (void) new KAction( i18n( "Open &Terminal" ), "openterm", Key_F4, this, TQT_SLOT( slotOpenTerminal() ), actionCollection(), "open_terminal" ); } (void) new KAction( i18n( "&Open Location..." ), "fileopen", KStdAccel::shortcut(KStdAccel::Open), this, TQT_SLOT( slotOpenLocation() ), actionCollection(), "open_location" ); m_paFindFiles = new KToggleAction( i18n( "&Find File..." ), "filefind", KStdAccel::shortcut(KStdAccel::Find), this, TQT_SLOT( slotToolFind() ), actionCollection(), "findfile" ); m_paPrint = KStdAction::print( 0, 0, actionCollection(), "print" ); (void) KStdAction::quit( this, TQT_SLOT( close() ), actionCollection(), "quit" ); m_ptaUseHTML = new KToggleAction( i18n( "&Use index.html" ), 0, this, TQT_SLOT( slotShowHTML() ), actionCollection(), "usehtml" ); m_paLockView = new KToggleAction( i18n( "Lock to Current Location"), 0, this, TQT_SLOT( slotLockView() ), actionCollection(), "lock" ); m_paLinkView = new KToggleAction( i18n( "Lin&k View"), 0, this, TQT_SLOT( slotLinkView() ), actionCollection(), "link" ); // Go menu m_paUp = new KToolBarPopupAction( i18n( "&Up" ), "up", KStdAccel::shortcut(KStdAccel::Up), actionCollection(), "up" ); connect( m_paUp, TQT_SIGNAL( activated( KAction::ActivationReason, Qt::ButtonState) ), this, TQT_SLOT( slotUp(KAction::ActivationReason, Qt::ButtonState) ) ); connect( m_paUp->popupMenu(), TQT_SIGNAL( aboutToShow() ), this, TQT_SLOT( slotUpAboutToShow() ) ); connect( m_paUp->popupMenu(), TQT_SIGNAL( activated( int ) ), this, TQT_SLOT( slotUpActivated( int ) ) ); QPair< KGuiItem, KGuiItem > backForward = KStdGuiItem::backAndForward(); m_paBack = new KToolBarPopupAction( backForward.first, KStdAccel::shortcut(KStdAccel::Back), 0, "", actionCollection(), "back" ); connect( m_paBack, TQT_SIGNAL( activated( KAction::ActivationReason, Qt::ButtonState) ), this, TQT_SLOT( slotBack(KAction::ActivationReason, Qt::ButtonState) ) ); connect( m_paBack->popupMenu(), TQT_SIGNAL( aboutToShow() ), this, TQT_SLOT( slotBackAboutToShow() ) ); connect( m_paBack->popupMenu(), TQT_SIGNAL( activated( int ) ), this, TQT_SLOT( slotBackActivated( int ) ) ); m_paForward = new KToolBarPopupAction( backForward.second, KStdAccel::shortcut(KStdAccel::Forward), 0, "", actionCollection(), "forward" ); connect( m_paForward, TQT_SIGNAL( activated( KAction::ActivationReason, Qt::ButtonState) ), this, TQT_SLOT( slotForward(KAction::ActivationReason, Qt::ButtonState) ) ); connect( m_paForward->popupMenu(), TQT_SIGNAL( aboutToShow() ), this, TQT_SLOT( slotForwardAboutToShow() ) ); connect( m_paForward->popupMenu(), TQT_SIGNAL( activated( int ) ), this, TQT_SLOT( slotForwardActivated( int ) ) ); m_paHistory = new KonqBidiHistoryAction( i18n("History"), actionCollection(), "history" ); connect( m_paHistory, TQT_SIGNAL( menuAboutToShow() ), this, TQT_SLOT( slotGoMenuAboutToShow() ) ); connect( m_paHistory, TQT_SIGNAL( activated( int ) ), this, TQT_SLOT( slotGoHistoryActivated( int ) ) ); m_paHome = new KAction( i18n( "Home" ), "gohome", KStdAccel::shortcut(KStdAccel::Home), actionCollection(), "home" ); connect( m_paHome, TQT_SIGNAL( activated( KAction::ActivationReason, Qt::ButtonState) ), this, TQT_SLOT( slotHome(KAction::ActivationReason, Qt::ButtonState) ) ); (void) new KAction( i18n( "S&ystem" ), "system", 0, this, TQT_SLOT( slotGoSystem() ), actionCollection(), "go_system" ); (void) new KAction( i18n( "App&lications" ), "kmenu", 0, this, TQT_SLOT( slotGoApplications() ), actionCollection(), "go_applications" ); (void) new KAction( i18n( "&Storage Media" ), "system", 0, this, TQT_SLOT( slotGoMedia() ), actionCollection(), "go_media" ); (void) new KAction( i18n( "&Network Folders" ), "network", 0, this, TQT_SLOT( slotGoNetworkFolders() ), actionCollection(), "go_network_folders" ); (void) new KAction( i18n( "Sett&ings" ), "kcontrol", 0, this, TQT_SLOT( slotGoSettings() ), actionCollection(), "go_settings" ); //(void) new KAction( i18n( "Sidebar Configuration" ), 0, this, TQT_SLOT( slotGoDirTree() ), actionCollection(), "go_dirtree" ); (void) new KAction( i18n( "Trash" ), "trashcan_full", 0, this, TQT_SLOT( slotGoTrash() ), actionCollection(), "go_trash" ); (void) new KAction( i18n( "Autostart" ), 0, this, TQT_SLOT( slotGoAutostart() ), actionCollection(), "go_autostart" ); KonqMostOftenURLSAction *mostOften = new KonqMostOftenURLSAction( i18n("Most Often Visited"), actionCollection(), "go_most_often" ); connect( mostOften, TQT_SIGNAL( activated( const KURL& )), TQT_SLOT( slotOpenURL( const KURL& ))); (void) new KAction( i18n( "History" ), "history", 0, this, TQT_SLOT( slotGoHistory() ), actionCollection(), "go_history" ); // Settings menu m_paSaveViewProfile = new KAction( i18n( "&Save View Profile..." ), 0, this, TQT_SLOT( slotSaveViewProfile() ), actionCollection(), "saveviewprofile" ); m_paSaveViewPropertiesLocally = new KToggleAction( i18n( "Save View Changes per &Folder" ), 0, this, TQT_SLOT( slotSaveViewPropertiesLocally() ), actionCollection(), "saveViewPropertiesLocally" ); // "Remove" ? "Reset" ? The former is more correct, the latter is more kcontrol-like... m_paRemoveLocalProperties = new KAction( i18n( "Remove Folder Properties" ), 0, this, TQT_SLOT( slotRemoveLocalProperties() ), actionCollection(), "removeLocalProperties" ); m_configureModules << "kde-filebehavior.desktop" << "kde-fileappearance.desktop" << "kde-filepreviews.desktop" << "kde-filetypes.desktop" << "kde-khtml_behavior.desktop" << "kde-khtml_java_js.desktop" << "kde-khtml_filter.desktop" << "kde-khtml_fonts.desktop" << "kde-ebrowsing.desktop" << "kde-kcmhistory.desktop" << "kde-cookies.desktop" << "kde-cache.desktop" << "kde-proxy.desktop" << "kde-kcmcss.desktop" << "kde-crypto.desktop" << "kde-useragent.desktop" << "kde-khtml_plugins.desktop" << "kde-kcmkonqyperformance.desktop"; if (!kapp->authorizeControlModules(configModules()).isEmpty()) KStdAction::preferences (this, TQT_SLOT (slotConfigure()), actionCollection() ); KStdAction::keyBindings( guiFactory(), TQT_SLOT( configureShortcuts() ), actionCollection() ); KStdAction::configureToolbars( this, TQT_SLOT( slotConfigureToolbars() ), actionCollection() ); m_paConfigureExtensions = new KAction( i18n("Configure Extensions..."), 0, this, TQT_SLOT( slotConfigureExtensions()), actionCollection(), "options_configure_extensions"); m_paConfigureSpellChecking = new KAction( i18n("Configure Spell Checking..."), "spellcheck", 0,this, TQT_SLOT( slotConfigureSpellChecking()), actionCollection(), "configurespellcheck"); // Window menu m_paSplitViewHor = new KAction( i18n( "Split View &Left/Right" ), "view_left_right", CTRL+SHIFT+Key_L, this, TQT_SLOT( slotSplitViewHorizontal() ), actionCollection(), "splitviewh" ); m_paSplitViewVer = new KAction( i18n( "Split View &Top/Bottom" ), "view_top_bottom", CTRL+SHIFT+Key_T, this, TQT_SLOT( slotSplitViewVertical() ), actionCollection(), "splitviewv" ); m_paAddTab = new KAction( i18n( "&New Tab" ), "tab_new", "CTRL+SHIFT+N;CTRL+T", this, TQT_SLOT( slotAddTab() ), actionCollection(), "newtab" ); m_paDuplicateTab = new KAction( i18n( "&Duplicate Current Tab" ), "tab_duplicate", CTRL+SHIFT+Key_D, this, TQT_SLOT( slotDuplicateTab() ), actionCollection(), "duplicatecurrenttab" ); m_paBreakOffTab = new KAction( i18n( "Detach Current Tab" ), "tab_breakoff", CTRL+SHIFT+Key_B, this, TQT_SLOT( slotBreakOffTab() ), actionCollection(), "breakoffcurrenttab" ); m_paRemoveView = new KAction( i18n( "&Close Active View" ),"view_remove", CTRL+SHIFT+Key_R, this, TQT_SLOT( slotRemoveView() ), actionCollection(), "removeview" ); m_paRemoveTab = new KAction( i18n( "Close Current Tab" ), "tab_remove", CTRL+Key_W, this, TQT_SLOT( slotRemoveTab() ), actionCollection(), "removecurrenttab" ); m_paRemoveOtherTabs = new KAction( i18n( "Close &Other Tabs" ), "tab_remove_other", 0, this, TQT_SLOT( slotRemoveOtherTabsPopup() ), actionCollection(), "removeothertabs" ); m_paActivateNextTab = new KAction( i18n( "Activate Next Tab" ), "tab_next", TQApplication::reverseLayout() ? KStdAccel::tabPrev() : KStdAccel::tabNext(), this, TQT_SLOT( slotActivateNextTab() ), actionCollection(), "activatenexttab" ); m_paActivatePrevTab = new KAction( i18n( "Activate Previous Tab" ), "tab_previous", TQApplication::reverseLayout() ? KStdAccel::tabNext() : KStdAccel::tabPrev(), this, TQT_SLOT( slotActivatePrevTab() ), actionCollection(), "activateprevtab" ); TQCString actionname; for (int i=1;i<13;i++) { actionname.sprintf("activate_tab_%02d", i); new KAction(i18n("Activate Tab %1").arg(i), 0, this, TQT_SLOT(slotActivateTab()), actionCollection(), actionname); } m_paMoveTabLeft = new KAction( i18n("Move Tab Left"), 0 , CTRL+SHIFT+Key_Left,this, TQT_SLOT( slotMoveTabLeft()),actionCollection(),"tab_move_left"); m_paMoveTabRight = new KAction( i18n("Move Tab Right"), 0 , CTRL+SHIFT+Key_Right,this, TQT_SLOT( slotMoveTabRight()),actionCollection(),"tab_move_right"); #ifndef NDEBUG (void) new KAction( i18n( "Dump Debug Info" ), "view_dump_debug_info", 0, this, TQT_SLOT( slotDumpDebugInfo() ), actionCollection(), "dumpdebuginfo" ); #endif m_paSaveRemoveViewProfile = new KAction( i18n( "C&onfigure View Profiles..." ), 0, m_pViewManager, TQT_SLOT( slotProfileDlg() ), actionCollection(), "saveremoveviewprofile" ); m_pamLoadViewProfile = new KActionMenu( i18n( "Load &View Profile" ), actionCollection(), "loadviewprofile" ); m_pViewManager->setProfiles( m_pamLoadViewProfile ); m_ptaFullScreen = KStdAction::fullScreen( 0, 0, actionCollection(), this ); KShortcut fullScreenShortcut = m_ptaFullScreen->shortcut(); fullScreenShortcut.append( KKey( Key_F11 ) ); m_ptaFullScreen->setShortcut( fullScreenShortcut ); connect( m_ptaFullScreen, TQT_SIGNAL( toggled( bool )), this, TQT_SLOT( slotUpdateFullScreen( bool ))); KShortcut reloadShortcut = KStdAccel::shortcut(KStdAccel::Reload); reloadShortcut.append(KKey(CTRL + Key_R)); m_paReload = new KAction( i18n( "&Reload" ), "reload", reloadShortcut, this, TQT_SLOT( slotReload() ), actionCollection(), "reload" ); m_paReloadAllTabs = new KAction( i18n( "&Reload All Tabs" ), "reload_all_tabs", SHIFT+Key_F5, this, TQT_SLOT( slotReloadAllTabs() ), actionCollection(), "reload_all_tabs" ); m_paReloadStop = new KAction( i18n( "&Reload/Stop" ), "reload", 0, this, TQT_SLOT( slotReloadStop() ), actionCollection(), "reload_stop" ); m_paUndo = KStdAction::undo( KonqUndoManager::self(), TQT_SLOT( undo() ), actionCollection(), "undo" ); //m_paUndo->setEnabled( KonqUndoManager::self()->undoAvailable() ); connect( KonqUndoManager::self(), TQT_SIGNAL( undoTextChanged( const TQString & ) ), m_paUndo, TQT_SLOT( setText( const TQString & ) ) ); // Those are connected to the browserextension directly m_paCut = KStdAction::cut( 0, 0, actionCollection(), "cut" ); KShortcut cutShortCut = m_paCut->shortcut(); cutShortCut.remove( KKey( SHIFT + Key_Delete ) ); // used for deleting files m_paCut->setShortcut( cutShortCut ); m_paCopy = KStdAction::copy( 0, 0, actionCollection(), "copy" ); m_paPaste = KStdAction::paste( 0, 0, actionCollection(), "paste" ); m_paStop = new KAction( i18n( "&Stop" ), "stop", Key_Escape, this, TQT_SLOT( slotStop() ), actionCollection(), "stop" ); m_paRename = new KAction( i18n( "&Rename" ), /*"editrename",*/ Key_F2, actionCollection(), "rename" ); m_paTrash = new KAction( i18n( "&Move to Trash" ), "edittrash", Key_Delete, actionCollection(), "trash" ); connect( m_paTrash, TQT_SIGNAL( activated( KAction::ActivationReason, Qt::ButtonState ) ), this, TQT_SLOT( slotTrashActivated( KAction::ActivationReason, Qt::ButtonState ) ) ); m_paDelete = new KAction( i18n( "&Delete" ), "editdelete", SHIFT+Key_Delete, actionCollection(), "del" ); m_paAnimatedLogo = new KonqLogoAction( i18n("Animated Logo"), 0, this, TQT_SLOT( slotDuplicateWindow() ), actionCollection(), "animated_logo" ); // Location bar m_locationLabel = new KonqDraggableLabel( this, i18n("L&ocation: ") ); (void) new KWidgetAction( m_locationLabel, i18n("L&ocation: "), Key_F6, this, TQT_SLOT( slotLocationLabelActivated() ), actionCollection(), "location_label" ); m_locationLabel->setBuddy( m_combo ); KWidgetAction* comboAction = new KWidgetAction( m_combo, i18n( "Location Bar" ), 0, 0, 0, actionCollection(), "toolbar_url_combo" ); comboAction->setShortcutConfigurable( false ); comboAction->setAutoSized( true ); TQWhatsThis::add( m_combo, i18n( "Location Bar

" "Enter a web address or search term." ) ); KAction *clearLocation = new KAction( i18n( "Clear Location Bar" ), TQApplication::reverseLayout() ? "clear_left" : "locationbar_erase", CTRL+Key_L, actionCollection(), "clear_location" ); connect( clearLocation, TQT_SIGNAL( activated( KAction::ActivationReason, Qt::ButtonState ) ), TQT_SLOT( slotClearLocationBar( KAction::ActivationReason, Qt::ButtonState ) ) ); clearLocation->setWhatsThis( i18n( "Clear Location bar

" "Clears the content of the location bar." ) ); // Bookmarks menu m_pamBookmarks = new KActionMenu( i18n( "&Bookmarks" ), "bookmark", actionCollection(), "bookmarks" ); m_pamBookmarks->setDelayed( false ); // The actual menu needs a different action collection, so that the bookmarks // don't appear in kedittoolbar m_bookmarksActionCollection = new KActionCollection( this ); m_bookmarksActionCollection->setHighlightingEnabled( true ); connectActionCollection( m_bookmarksActionCollection ); m_pBookmarkMenu = new KBookmarkMenu( KonqBookmarkManager::self(), m_pBookmarksOwner, m_pamBookmarks->popupMenu(), m_bookmarksActionCollection, true ); connect( m_pBookmarkMenu, TQT_SIGNAL( aboutToShowContextMenu(const KBookmark &, TQPopupMenu*) ), this, TQT_SLOT( slotFillContextMenu(const KBookmark &, TQPopupMenu*) )); connect( m_pBookmarkMenu, TQT_SIGNAL( openBookmark(const TQString &, Qt::ButtonState) ), this, TQT_SLOT( slotOpenBookmarkURL(const TQString &, Qt::ButtonState) )); KAction *addBookmark = actionCollection()->action("add_bookmark"); if (addBookmark) addBookmark->setText(i18n("Bookmark This Location")); m_paShowMenuBar = KStdAction::showMenubar( this, TQT_SLOT( slotShowMenuBar() ), actionCollection() ); (void) new KAction( i18n( "Kon&queror Introduction" ), 0, this, TQT_SLOT( slotIntro() ), actionCollection(), "konqintro" ); KAction *goUrl = new KAction( i18n( "Go" ), "key_enter", 0, this, TQT_SLOT( goURL() ), actionCollection(), "go_url" ); goUrl->setWhatsThis( i18n( "Go

" "Goes to the page that has been entered into the location bar." ) ); enableAllActions( false ); // help stuff m_paUp->setWhatsThis( i18n( "Enter the parent folder

" "For instance, if the current location is file:/home/%1 clicking this " "button will take you to file:/home." ).arg( KUser().loginName() ) ); m_paUp->setToolTip( i18n( "Enter the parent folder" ) ); m_paBack->setWhatsThis( i18n( "Move backwards one step in the browsing history

" ) ); m_paBack->setToolTip( i18n( "Move backwards one step in the browsing history" ) ); m_paForward->setWhatsThis( i18n( "Move forward one step in the browsing history

" ) ); m_paForward->setToolTip( i18n( "Move forward one step in the browsing history" ) ); m_paHome->setWhatsThis( i18n( "Navigate to your 'Home Location'

" "You can configure the location this button takes you to in the " "KDE Control Center, under File Manager/Behavior." ) ); m_paHome->setToolTip( i18n( "Navigate to your 'Home Location'" ) ); m_paReload->setWhatsThis( i18n( "Reload the currently displayed document

" "This may, for example, be needed to refresh webpages that have been " "modified since they were loaded, in order to make the changes visible." ) ); m_paReload->setToolTip( i18n( "Reload the currently displayed document" ) ); m_paReloadAllTabs->setWhatsThis( i18n( "Reload all currently displayed documents in tabs

" "This may, for example, be needed to refresh webpages that have been " "modified since they were loaded, in order to make the changes visible." ) ); m_paReloadAllTabs->setToolTip( i18n( "Reload all currently displayed document in tabs" ) ); m_paStop->setWhatsThis( i18n( "Stop loading the document

" "All network transfers will be stopped and Konqueror will display the content " "that has been received so far." ) ); m_paStop->setToolTip( i18n( "Stop loading the document" ) ); m_paCut->setWhatsThis( i18n( "Cut the currently selected text or item(s) and move it " "to the system clipboard

" "This makes it available to the Paste command in Konqueror " "and other KDE applications." ) ); m_paCut->setToolTip( i18n( "Move the selected text or item(s) to the clipboard" ) ); m_paCopy->setWhatsThis( i18n( "Copy the currently selected text or item(s) to the " "system clipboard

" "This makes it available to the Paste command in Konqueror " "and other KDE applications." ) ); m_paCopy->setToolTip( i18n( "Copy the selected text or item(s) to the clipboard" ) ); m_paPaste->setWhatsThis( i18n( "Paste the previously cut or copied clipboard " "contents

" "This also works for text copied or cut from other KDE applications." ) ); m_paPaste->setToolTip( i18n( "Paste the clipboard contents" ) ); m_paPrint->setWhatsThis( i18n( "Print the currently displayed document

" "You will be presented with a dialog where you can set various " "options, such as the number of copies to print and which printer " "to use.

" "This dialog also provides access to special KDE printing " "services such as creating a PDF file from the current document." ) ); m_paPrint->setToolTip( i18n( "Print the current document" ) ); // Please proof-read those (David) m_ptaUseHTML->setToolTip( i18n("If present, open index.html when entering a folder.") ); m_paLockView->setToolTip( i18n("A locked view cannot change folders. Use in combination with 'link view' to explore many files from one folder") ); m_paLinkView->setToolTip( i18n("Sets the view as 'linked'. A linked view follows folder changes made in other linked views.") ); } void KonqMainWindow::slotFillContextMenu( const KBookmark &bk, TQPopupMenu * pm ) { kdDebug() << "KonqMainWindow::slotFillContextMenu(bk, pm == " << pm << ")" << endl; popupItems.clear(); popupUrlArgs = KParts::URLArgs(); //Set tab_new_x to point to the correct icon based on NewTabsInFront bool newtabsinfront = KonqSettings::newTabsInFront(); TQString tab_new_x ; if ( newtabsinfront ) tab_new_x = "tab_new" ; else tab_new_x = "tab_new_bg" ; if ( bk.isGroup() ) { KBookmarkGroup grp = bk.toGroup(); TQValueList list = grp.groupUrlList(); TQValueList::Iterator it = list.begin(); for (; it != list.end(); ++it ) popupItems.append( new KFileItem( (*it), TQString::null, KFileItem::Unknown) ); pm->insertItem( SmallIcon(tab_new_x), i18n( "Open Folder in Tabs" ), this, TQT_SLOT( slotPopupNewTabRight() ) ); } else { popupItems.append( new KFileItem( bk.url(), TQString::null, KFileItem::Unknown) ); pm->insertItem( SmallIcon("window_new"), i18n( "Open in New Window" ), this, TQT_SLOT( slotPopupNewWindow() ) ); pm->insertItem( SmallIcon(tab_new_x), i18n( "Open in New Tab" ), this, TQT_SLOT( slotPopupNewTabRight() ) ); } } void KonqMainWindow::slotOpenBookmarkURL( const TQString & url, Qt::ButtonState state) { kdDebug(1202) << "KonqMainWindow::slotOpenBookmarkURL(" << url << ", " << state << ")" << endl; KonqOpenURLRequest req; req.newTab = true; req.newTabInFront = KonqSettings::newTabsInFront(); if (state & Qt::ShiftButton) req.newTabInFront = !req.newTabInFront; if( state & Qt::ControlButton ) // Ctrl Left/MMB openFilteredURL( url, req); else if( state & Qt::MidButton ) { if(KonqSettings::mmbOpensTab()) openFilteredURL( url, req); else { KURL finalURL = KonqMisc::konqFilteredURL( this, url ); KonqMisc::createNewWindow( finalURL.url() ); } } else openFilteredURL( url, false ); } void KonqMainWindow::slotMoveTabLeft() { if ( TQApplication::reverseLayout() ) m_pViewManager->moveTabForward(); else m_pViewManager->moveTabBackward(); } void KonqMainWindow::slotMoveTabRight() { if ( TQApplication::reverseLayout() ) m_pViewManager->moveTabBackward(); else m_pViewManager->moveTabForward(); } void KonqMainWindow::updateToolBarActions( bool pendingAction /*=false*/) { // Enables/disables actions that depend on the current view & url (mostly toolbar) // Up, back, forward, the edit extension, stop button, wheel setUpEnabled( m_currentView->url() ); m_paBack->setEnabled( m_currentView->canGoBack() ); m_paForward->setEnabled( m_currentView->canGoForward() ); if ( m_currentView->isLoading() ) { startAnimation(); // takes care of m_paStop } else { m_paAnimatedLogo->stop(); m_paStop->setEnabled( pendingAction ); //enable/disable based on any pending actions... toggleReloadStopButton( pendingAction ); } if ( m_currentView && m_currentView->url().isLocalFile() && !m_currentView->isLockedViewMode() ) { if ( m_currentView->serviceTypes().tqcontains( "inode/directory" ) ) m_ptaUseHTML->setEnabled( true ); else if ( m_currentView->serviceTypes().tqcontains( "text/html" ) ) { // Currently viewing an index.html file via this feature (i.e. url points to a dir) TQString locPath = KURL( m_currentView->locationBarURL() ).path(); m_ptaUseHTML->setEnabled( TQFileInfo( locPath ).isDir() ); } else m_ptaUseHTML->setEnabled( false ); } else { m_ptaUseHTML->setEnabled( false ); } } void KonqMainWindow::updateViewActions() { // Update actions that depend on the current view and its mode, or on the number of views etc. // Don't do things in this method that depend on m_currentView->url(). // When going 'back' in history this will be called before opening the url. // Use updateToolBarActions instead. slotUndoAvailable( KonqUndoManager::self()->undoAvailable() ); // Can lock a view only if there is a next view //m_paLockView->setEnabled( m_pViewManager->chooseNextView(m_currentView) != 0L && ); //kdDebug(1202) << "KonqMainWindow::updateViewActions m_paLockView enabled ? " << m_paLockView->isEnabled() << endl; m_paLockView->setEnabled( viewCount() > 1 ); m_paLockView->setChecked( m_currentView && m_currentView->isLockedLocation() ); // Can remove view if we'll still have a main view after that m_paRemoveView->setEnabled( mainViewsCount() > 1 || ( m_currentView && m_currentView->isToggleView() ) ); KonqFrameBase* docContainer = m_pViewManager->docContainer(); if ( docContainer == 0L && !(currentView() && currentView()->frame())) { m_paAddTab->setEnabled( false ); m_paDuplicateTab->setEnabled( false ); m_paRemoveTab->setEnabled( false ); m_paRemoveOtherTabs->setEnabled( false ); m_paBreakOffTab->setEnabled( false ); m_paActivateNextTab->setEnabled( false ); m_paActivatePrevTab->setEnabled( false ); m_paMoveTabLeft->setEnabled( false ); m_paMoveTabRight->setEnabled( false ); } else { m_paAddTab->setEnabled( true ); m_paDuplicateTab->setEnabled( true ); if ( docContainer && docContainer->frameType() == "Tabs" ) { KonqFrameTabs* tabContainer = static_cast(docContainer); bool state = (tabContainer->count()>1); m_paRemoveTab->setEnabled( state ); m_paRemoveOtherTabs->setEnabled( state ); m_paBreakOffTab->setEnabled( state ); m_paActivateNextTab->setEnabled( state ); m_paActivatePrevTab->setEnabled( state ); TQPtrList* childFrameList = tabContainer->childFrameList(); m_paMoveTabLeft->setEnabled( currentView() ? currentView()->frame()!= (TQApplication::reverseLayout() ? childFrameList->last() : childFrameList->first()) : false ); m_paMoveTabRight->setEnabled( currentView() ? currentView()->frame()!= (TQApplication::reverseLayout() ? childFrameList->first() : childFrameList->last()) : false ); } else { m_paRemoveTab->setEnabled( false ); m_paRemoveOtherTabs->setEnabled( false ); m_paBreakOffTab->setEnabled( false ); m_paActivateNextTab->setEnabled( false ); m_paActivatePrevTab->setEnabled( false ); m_paMoveTabLeft->setEnabled( false ); m_paMoveTabRight->setEnabled( false ); } } // Can split a view if it's not a toggle view (because a toggle view can be here only once) bool isNotToggle = m_currentView && !m_currentView->isToggleView(); m_paSplitViewHor->setEnabled( isNotToggle ); m_paSplitViewVer->setEnabled( isNotToggle ); m_paLinkView->setChecked( m_currentView && m_currentView->isLinkedView() ); if ( m_currentView && m_currentView->part() && m_currentView->part()->inherits("KonqDirPart") ) { KonqDirPart * dirPart = static_cast(m_currentView->part()); m_paFindFiles->setEnabled( dirPart->findPart() == 0 ); // Create the copy/move options if not already done if ( !m_paCopyFiles ) { // F5 is the default key binding for Reload.... a la Windows. // mc users want F5 for Copy and F6 for move, but I can't make that default. m_paCopyFiles = new KAction( i18n("Copy &Files..."), Key_F7, this, TQT_SLOT( slotCopyFiles() ), actionCollection(), "copyfiles" ); m_paMoveFiles = new KAction( i18n("M&ove Files..."), Key_F8, this, TQT_SLOT( slotMoveFiles() ), actionCollection(), "movefiles" ); // This action doesn't appear in the GUI, it's for the shortcut only. // KNewMenu takes care of the GUI stuff. m_paNewDir = new KAction( i18n("Create Folder..." ), Key_F10, this, TQT_SLOT( slotNewDir() ), actionCollection(), "konq_create_dir" ); TQPtrList lst; lst.append( m_paCopyFiles ); lst.append( m_paMoveFiles ); m_paCopyFiles->setEnabled( false ); m_paMoveFiles->setEnabled( false ); plugActionList( "operations", lst ); } } else { m_paFindFiles->setEnabled( false ); if (m_paCopyFiles) { unplugActionList( "operations" ); delete m_paCopyFiles; m_paCopyFiles = 0; delete m_paMoveFiles; m_paMoveFiles = 0; delete m_paNewDir; m_paNewDir = 0; } } } TQString KonqMainWindow::findIndexFile( const TQString &dir ) { TQDir d( dir ); TQString f = d.filePath( "index.html", false ); if ( TQFile::exists( f ) ) return f; f = d.filePath( "index.htm", false ); if ( TQFile::exists( f ) ) return f; f = d.filePath( "index.HTML", false ); if ( TQFile::exists( f ) ) return f; return TQString::null; } void KonqMainWindow::connectExtension( KParts::BrowserExtension *ext ) { //kdDebug(1202) << "Connecting extension " << ext << endl; KParts::BrowserExtension::ActionSlotMap * actionSlotMap = KParts::BrowserExtension::actionSlotMapPtr(); KParts::BrowserExtension::ActionSlotMap::ConstIterator it = actionSlotMap->begin(); KParts::BrowserExtension::ActionSlotMap::ConstIterator itEnd = actionSlotMap->end(); TQStrList slotNames = ext->tqmetaObject()->slotNames(); for ( ; it != itEnd ; ++it ) { KAction * act = actionCollection()->action( it.key() ); //kdDebug(1202) << it.key() << endl; if ( act ) { // Does the extension have a slot with the name of this action ? if ( slotNames.tqcontains( it.key()+"()" ) ) { if ( it.key() != "trash" ) connect( act, TQT_SIGNAL( activated() ), ext, it.data() /* TQT_SLOT(slot name) */ ); act->setEnabled( ext->isActionEnabled( it.key() ) ); const TQString text = ext->actionText( it.key() ); if ( !text.isEmpty() ) act->setText( text ); // TODO how to re-set the original action text, when switching to a part that didn't call setAction? // Can't test with Paste... } else act->setEnabled(false); } else kdError(1202) << "Error in BrowserExtension::actionSlotMap(), unknown action : " << it.key() << endl; } } void KonqMainWindow::disconnectExtension( KParts::BrowserExtension *ext ) { //kdDebug(1202) << "Disconnecting extension " << ext << endl; KParts::BrowserExtension::ActionSlotMap * actionSlotMap = KParts::BrowserExtension::actionSlotMapPtr(); KParts::BrowserExtension::ActionSlotMap::ConstIterator it = actionSlotMap->begin(); KParts::BrowserExtension::ActionSlotMap::ConstIterator itEnd = actionSlotMap->end(); TQStrList slotNames = ext->tqmetaObject()->slotNames(); for ( ; it != itEnd ; ++it ) { KAction * act = actionCollection()->action( it.key() ); //kdDebug(1202) << it.key() << endl; if ( act && slotNames.tqcontains( it.key()+"()" ) ) { //kdDebug(1202) << "disconnectExtension: " << act << " " << act->name() << endl; act->disconnect( ext ); } } } void KonqMainWindow::slotTrashActivated( KAction::ActivationReason reason, Qt::ButtonState state ) { if ( !m_currentView ) return; if ( reason == KAction::PopupMenuActivation && ( state & Qt::ShiftButton ) ) m_currentView->callExtensionMethod( "del()" ); else m_currentView->callExtensionMethod( "trash()" ); } void KonqMainWindow::enableAction( const char * name, bool enabled ) { KAction * act = actionCollection()->action( name ); if (!act) kdWarning(1202) << "Unknown action " << name << " - can't enable" << endl; else { if ( m_bLocationBarConnected && ( act==m_paCopy || act==m_paCut || act==m_paPaste || act==m_paDelete || act==m_paTrash ) ) // Don't change action state while the location bar has focus. return; //kdDebug(1202) << "KonqMainWindow::enableAction " << name << " " << enabled << endl; act->setEnabled( enabled ); } // Update "copy files" and "move files" accordingly if (m_paCopyFiles && !strcmp( name, "copy" )) { m_paCopyFiles->setEnabled( enabled ); } else if (m_paMoveFiles && !strcmp( name, "cut" )) { m_paMoveFiles->setEnabled( enabled ); } } void KonqMainWindow::setActionText( const char * name, const TQString& text ) { KAction * act = actionCollection()->action( name ); if (!act) kdWarning(1202) << "Unknown action " << name << " - can't enable" << endl; else { kdDebug(1202) << "KonqMainWindow::setActionText " << name << " " << text << endl; act->setText( text ); } } void KonqMainWindow::currentProfileChanged() { bool enabled = !m_pViewManager->currentProfile().isEmpty(); m_paSaveViewProfile->setEnabled( enabled ); m_paSaveViewProfile->setText( enabled ? i18n("&Save View Profile \"%1\"...").arg(m_pViewManager->currentProfileText()) : i18n("&Save View Profile...") ); } void KonqMainWindow::enableAllActions( bool enable ) { kdDebug(1202) << "KonqMainWindow::enableAllActions " << enable << endl; KParts::BrowserExtension::ActionSlotMap * actionSlotMap = KParts::BrowserExtension::actionSlotMapPtr(); TQValueList actions = actionCollection()->actions(); TQValueList::Iterator it = actions.begin(); TQValueList::Iterator end = actions.end(); for (; it != end; ++it ) { KAction *act = *it; if ( !TQString(act->name()).startsWith("options_configure") /* do not touch the configureblah actions */ && ( !enable || !actionSlotMap->tqcontains( act->name() ) ) ) /* don't enable BE actions */ act->setEnabled( enable ); } // This method is called with enable=false on startup, and // then only once with enable=true when the first view is setup. // So the code below is where actions that should initially be disabled are disabled. if (enable) { setUpEnabled( m_currentView ? m_currentView->url() : KURL() ); // we surely don't have any history buffers at this time m_paBack->setEnabled( false ); m_paForward->setEnabled( false ); // Load profile submenu m_pViewManager->profileListDirty( false ); currentProfileChanged(); updateViewActions(); // undo, lock, link and other view-dependent actions m_paStop->setEnabled( m_currentView && m_currentView->isLoading() ); toggleReloadStopButton( m_currentView && m_currentView->isLoading() ); if (m_toggleViewGUIClient) { TQPtrList actions = m_toggleViewGUIClient->actions(); for ( KAction * it = actions.first(); it ; it = actions.next() ) it->setEnabled( true ); } } actionCollection()->action( "quit" )->setEnabled( true ); } void KonqMainWindow::disableActionsNoView() { // No view -> there are some things we can't do m_paUp->setEnabled( false ); m_paReload->setEnabled( false ); m_paReloadAllTabs->setEnabled( false ); m_paBack->setEnabled( false ); m_paForward->setEnabled( false ); m_ptaUseHTML->setEnabled( false ); m_pMenuNew->setEnabled( false ); m_paLockView->setEnabled( false ); m_paLockView->setChecked( false ); m_paSplitViewVer->setEnabled( false ); m_paSplitViewHor->setEnabled( false ); m_paRemoveView->setEnabled( false ); m_paLinkView->setEnabled( false ); if (m_toggleViewGUIClient) { TQPtrList actions = m_toggleViewGUIClient->actions(); for ( KAction * it = actions.first(); it ; it = actions.next() ) it->setEnabled( false ); } // There are things we can do, though : bookmarks, view profile, location bar, new window, // settings, etc. m_paHome->setEnabled( true ); m_pamBookmarks->setEnabled( true ); static const char* const s_enActions[] = { "new_window", "duplicate_window", "open_location", "toolbar_url_combo", "clear_location", "animated_logo", "konqintro", "go_most_often", "go_applications", "go_dirtree", "go_trash", "go_settings", "go_network_folders", "go_autostart", "go_url", "go_media", "go_history", "options_configure_extensions", 0 }; for ( int i = 0 ; s_enActions[i] ; ++i ) { KAction * act = action(s_enActions[i]); if (act) act->setEnabled( true ); } m_pamLoadViewProfile->setEnabled( true ); m_paSaveViewProfile->setEnabled( true ); m_paSaveRemoveViewProfile->setEnabled( true ); m_combo->clearTemporary(); updateLocalPropsActions(); } void KonqExtendedBookmarkOwner::openBookmarkURL( const TQString & /*url*/ ) { // Do nothing, we catch the signal } void KonqMainWindow::setCaption( const TQString &caption ) { // KParts sends us empty captions when activating a brand new part // We can't change it there (in case of apps removing all parts altogether) // but here we never do that. if ( !caption.isEmpty() && m_currentView ) { kdDebug(1202) << "KonqMainWindow::setCaption(" << caption << ")" << endl; // Keep an unmodified copy of the caption (before kapp->makeStdCaption is applied) m_currentView->setCaption( caption ); KParts::MainWindow::setCaption( m_currentView->caption() ); } } void KonqMainWindow::show() { // We need to check if our toolbars are shown/hidden here, and set // our menu items accordingly. We can't do it in the constructor because // view profiles store toolbar info, and that info is read after // construct time. m_paShowMenuBar->setChecked( !menuBar()->isHidden() ); updateBookmarkBar(); // hide if empty // Call parent method KParts::MainWindow::show(); } TQString KonqExtendedBookmarkOwner::currentURL() const { return m_pKonqMainWindow->currentURL(); } TQString KonqMainWindow::currentProfile() const { return m_pViewManager->currentProfile(); } TQString KonqMainWindow::currentURL() const { if ( !m_currentView ) return TQString::null; TQString url = m_currentView->url().prettyURL(); if ( m_currentView->part() && m_currentView->part()->inherits("KonqDirPart") ) { TQString nameFilter = static_cast(m_currentView->part())->nameFilter(); if ( !nameFilter.isEmpty() ) { if (!url.endsWith("/")) url += '/'; url += nameFilter; } } return url; } void KonqExtendedBookmarkOwner::slotFillBookmarksList( KExtendedBookmarkOwner::QStringPairList & list ) { KonqFrameBase *docContainer = m_pKonqMainWindow->viewManager()->docContainer(); if (docContainer == 0L) return; if (docContainer->frameType() != "Tabs") return; KonqFrameTabs* tabContainer = static_cast(docContainer); TQPtrList frameList = *tabContainer->childFrameList(); TQPtrListIterator it( frameList ); for ( it.toFirst(); it != 0L; ++it ) { if ( !it.current()->activeChildView() ) continue; if( it.current()->activeChildView()->locationBarURL().isEmpty() ) continue; list << qMakePair( it.current()->activeChildView()->caption(), it.current()->activeChildView()->url().url() ); } } TQString KonqExtendedBookmarkOwner::currentTitle() const { return m_pKonqMainWindow->currentTitle(); } TQString KonqMainWindow::currentTitle() const { return m_currentView ? m_currentView->caption() : TQString::null; } void KonqMainWindow::slotPopupMenu( const TQPoint &_global, const KURL &url, const TQString &_mimeType, mode_t _mode ) { slotPopupMenu( 0L, _global, url, _mimeType, _mode ); } void KonqMainWindow::slotPopupMenu( KXMLGUIClient *client, const TQPoint &_global, const KURL &url, const TQString &_mimeType, mode_t _mode ) { KFileItem item( url, _mimeType, _mode ); KFileItemList items; items.append( &item ); slotPopupMenu( client, _global, items, KParts::URLArgs(), KParts::BrowserExtension::DefaultPopupItems, false ); //BE CAREFUL WITH sender() ! } void KonqMainWindow::slotPopupMenu( KXMLGUIClient *client, const TQPoint &_global, const KURL &url, const KParts::URLArgs &_args, KParts::BrowserExtension::PopupFlags f, mode_t _mode ) { KFileItem item( url, _args.serviceType, _mode ); KFileItemList items; items.append( &item ); slotPopupMenu( client, _global, items, _args, f, false ); //BE CAREFUL WITH sender() ! } void KonqMainWindow::slotPopupMenu( const TQPoint &_global, const KFileItemList &_items ) { slotPopupMenu( 0L, _global, _items ); } void KonqMainWindow::slotPopupMenu( KXMLGUIClient *client, const TQPoint &_global, const KFileItemList &_items ) { slotPopupMenu( client, _global, _items, KParts::URLArgs(), KParts::BrowserExtension::DefaultPopupItems, true ); } void KonqMainWindow::slotPopupMenu( KXMLGUIClient *client, const TQPoint &_global, const KFileItemList &_items, const KParts::URLArgs &_args, KParts::BrowserExtension::PopupFlags _flags ) { slotPopupMenu( client, _global, _items, _args, _flags, true ); } void KonqMainWindow::slotPopupMenu( KXMLGUIClient *client, const TQPoint &_global, const KFileItemList &_items, const KParts::URLArgs &_args, KParts::BrowserExtension::PopupFlags itemFlags, bool showProperties ) { KonqView * m_oldView = m_currentView; KonqView * currentView = childView( static_cast( sender()->parent() ) ); //kdDebug() << "KonqMainWindow::slotPopupMenu m_oldView=" << m_oldView << " new currentView=" << currentView << " passive:" << currentView->isPassiveMode() << endl; if ( (m_oldView != currentView) && currentView->isPassiveMode() ) { // Make this view active only temporarily (because it's passive) m_currentView = currentView; if ( m_oldView && m_oldView->browserExtension() ) disconnectExtension( m_oldView->browserExtension() ); if ( m_currentView->browserExtension() ) connectExtension( m_currentView->browserExtension() ); } // Note that if m_oldView!=currentView and currentView isn't passive, // then the KParts mechanism has already noticed the click in it, // but KonqViewManager delays the GUI-rebuilding with a single-shot timer. // Right after the popup shows up, currentView _will_ be m_currentView. //kdDebug(1202) << "KonqMainWindow::slotPopupMenu( " << client << "...)" << " current view=" << m_currentView << " " << m_currentView->part()->className() << endl; // This action collection is used to pass actions to KonqPopupMenu. // It has to be a KActionCollection instead of a KActionPtrList because we need // the actiontqStatusText signal... KActionCollection popupMenuCollection( (TQWidget*)0 ); popupMenuCollection.insert( m_paBack ); popupMenuCollection.insert( m_paForward ); popupMenuCollection.insert( m_paUp ); popupMenuCollection.insert( m_paReload ); popupMenuCollection.insert( m_paFindFiles ); popupMenuCollection.insert( m_paUndo ); popupMenuCollection.insert( m_paCut ); popupMenuCollection.insert( m_paCopy ); popupMenuCollection.insert( m_paPaste ); popupMenuCollection.insert( m_paTrash ); popupMenuCollection.insert( m_paRename ); popupMenuCollection.insert( m_paDelete ); // The pasteto action is used when clicking on a dir, to paste into it. KAction *actPaste = KStdAction::paste( this, TQT_SLOT( slotPopupPasteTo() ), &popupMenuCollection, "pasteto" ); actPaste->setEnabled( m_paPaste->isEnabled() ); popupMenuCollection.insert( actPaste ); bool sReading = false; if ( _items.count() > 0 ) { m_popupURL = _items.getFirst()->url(); sReading = KProtocolInfo::supportsReading( m_popupURL ); if (sReading) m_popupServiceType = _items.getFirst()->mimetype(); } else { m_popupURL = KURL(); m_popupServiceType = TQString::null; } if ( (_items.count() == 1) && !m_popupServiceType.isEmpty() ) { TQString currentServiceName = currentView->service()->desktopEntryName(); // List of services for the "Preview In" submenu. m_popupEmbeddingServices = KTrader::self()->query( m_popupServiceType, "KParts/ReadOnlyPart", // Obey "HideFromMenus". It defaults to false so we want "absent or true" // (wow, testing for 'true' if absent doesn't work, so order matters) "(not exist [X-KDE-BrowserView-HideFromMenus] or not [X-KDE-BrowserView-HideFromMenus]) " "and DesktopEntryName != '"+currentServiceName+"' " // I had an old local dirtree.desktop without lib, no need for invalid entries "and exist [Library]", TQString::null ); } // Don't set the view URL for a toggle view. // (This is a bit of a hack for the directory tree....) // ## should use the new currentView->isHierarchicalView() instead? // Would this be correct for the konqlistview tree view? KURL viewURL = currentView->isToggleView() ? KURL() : currentView->url(); bool openedForViewURL = false; //bool dirsSelected = false; bool devicesFile = false; if ( _items.count() == 1 ) { KURL firstURL = _items.getFirst()->url(); if ( !viewURL.isEmpty() ) { //firstURL.cleanPath(); openedForViewURL = firstURL.equals( viewURL, true ); } devicesFile = firstURL.protocol().find("device", 0, false) == 0; //dirsSelected = S_ISDIR( _items.getFirst()->mode() ); } //check if current url is trash KURL url = viewURL; url.cleanPath(); bool isIntoTrash = url.protocol() == "trash" || url.url().startsWith( "system:/trash" ); bool doTabHandling = !openedForViewURL && !isIntoTrash && sReading; bool showEmbeddingServices = !isIntoTrash && !devicesFile && (itemFlags & KParts::BrowserExtension::ShowTextSelectionItems) == 0; PopupMenuGUIClient *konqyMenuClient = new PopupMenuGUIClient( this, m_popupEmbeddingServices, showEmbeddingServices, doTabHandling ); //kdDebug(1202) << "KonqMainWindow::slotPopupMenu " << viewURL.prettyURL() << endl; // Those actions go into the PopupMenuGUIClient, since that's the one defining them. KAction *actNewWindow = 0L, *actNewTab = 0L; if( doTabHandling ) { if (_args.forcesNewWindow()) { actNewWindow = new KAction( i18n( "Open in T&his Window" ), 0, this, TQT_SLOT( slotPopupThisWindow() ), konqyMenuClient->actionCollection(), "sameview" ); actNewWindow->setToolTip( i18n( "Open the document in current window" ) ); } actNewWindow = new KAction( i18n( "Open in New &Window" ), "window_new", 0, this, TQT_SLOT( slotPopupNewWindow() ), konqyMenuClient->actionCollection(), "newview" ); actNewWindow->setToolTip( i18n( "Open the document in a new window" ) ); //Set tab_new_x to point to the correct icon based on NewTabsInFront bool newtabsinfront = KonqSettings::newTabsInFront(); TQString tab_new_x ; if ( newtabsinfront ) tab_new_x = "tab_new" ; else tab_new_x = "tab_new_bg" ; actNewTab = new KAction( i18n( "Open in &New Tab" ), tab_new_x, 0, this, TQT_SLOT( slotPopupNewTab() ), konqyMenuClient->actionCollection(), "openintab" ); actNewTab->setToolTip( i18n( "Open the document in a new tab" ) ); doTabHandling = true; } if (currentView->isHierarchicalView()) itemFlags |= KParts::BrowserExtension::ShowCreateDirectory; KonqPopupMenu::KonqPopupFlags kpf = 0; if ( showProperties ) kpf |= KonqPopupMenu::ShowProperties; else kpf |= KonqPopupMenu::IsLink; // HACK TQGuardedPtr pPopupMenu = new KonqPopupMenu( KonqBookmarkManager::self(), _items, viewURL, popupMenuCollection, m_pMenuNew, // This parent ensures that if the part destroys itself (e.g. KHTML redirection), // it will close the popupmenu currentView->part()->widget(), kpf, itemFlags ); if ( openedForViewURL && !viewURL.isLocalFile() ) pPopupMenu->setURLTitle( currentView->caption() ); // We will need these if we call the newTab slot popupItems = _items; popupUrlArgs = _args; popupUrlArgs.serviceType = TQString::null; // Reset so that Open in New Window/Tab does mimetype detection connectActionCollection( pPopupMenu->actionCollection() ); pPopupMenu->factory()->addClient( konqyMenuClient ); if ( client ) pPopupMenu->factory()->addClient( client ); KParts::BrowserExtension *be = ::qt_cast(sender()); if ( be ) { TQObject::connect( this, TQT_SIGNAL(popupItemsDisturbed()), pPopupMenu, TQT_SLOT(close()) ); TQObject::connect( be, TQT_SIGNAL(itemsRemoved(const KFileItemList &)), this, TQT_SLOT(slotItemsRemoved(const KFileItemList &)) ); } TQObject::disconnect( m_pMenuNew->popupMenu(), TQT_SIGNAL(aboutToShow()), this, TQT_SLOT(slotFileNewAboutToShow()) ); TQGuardedPtr guard(this); // #149736 pPopupMenu->exec( _global ); delete pPopupMenu; // We're sort of misusing KActionCollection here, but we need it for the actiontqStatusText signal... // Anyway. If the action belonged to the view, and the view got deleted, we don't want ~KActionCollection // to iterate over those deleted actions KActionPtrList lst = popupMenuCollection.actions(); KActionPtrList::iterator it = lst.begin(); for ( ; it != lst.end() ; ++it ) popupMenuCollection.take( *it ); if (guard.isNull()) { // the placement of this test is very important, double-check #149736 if moving stuff around return; } TQObject::connect( m_pMenuNew->popupMenu(), TQT_SIGNAL(aboutToShow()), this, TQT_SLOT(slotFileNewAboutToShow()) ); if ( be ) { TQObject::disconnect( be, TQT_SIGNAL(itemsRemoved(const KFileItemList &)), this, TQT_SLOT(slotItemsRemoved(const KFileItemList &)) ); } delete konqyMenuClient; m_popupEmbeddingServices.clear(); popupItems.clear(); // Deleted by konqyMenuClient's actioncollection //delete actNewTab; //delete actNewWindow; delete actPaste; //kdDebug(1202) << "-------- KonqMainWindow::slotPopupMenu() - m_oldView = " << m_oldView << ", currentView = " << currentView //<< ", m_currentView = " << m_currentView << endl; // Restore current view if current is passive if ( (m_oldView != currentView) && (currentView == m_currentView) && currentView->isPassiveMode() ) { //kdDebug() << "KonqMainWindow::slotPopupMenu restoring active view " << m_oldView << endl; if ( m_currentView->browserExtension() ) disconnectExtension( m_currentView->browserExtension() ); if ( m_oldView ) { if ( m_oldView->browserExtension() ) { connectExtension( m_oldView->browserExtension() ); m_currentView = m_oldView; } // Special case: RMB + renaming in sidebar; setFocus would abort editing. TQWidget* fw = tqfocusWidget(); if ( !fw || !::qt_cast( fw ) ) m_oldView->part()->widget()->setFocus(); } } } void KonqMainWindow::slotItemsRemoved( const KFileItemList &items ) { TQPtrListIterator it( items ); for ( ; it.current(); ++it ) { if ( popupItems.tqcontains( it.current() ) ) { emit popupItemsDisturbed(); return; } } } void KonqMainWindow::slotOpenEmbedded() { TQCString name = sender()->name(); m_popupService = m_popupEmbeddingServices[ name.toInt() ]->desktopEntryName(); m_popupEmbeddingServices.clear(); TQTimer::singleShot( 0, this, TQT_SLOT( slotOpenEmbeddedDoIt() ) ); } void KonqMainWindow::slotOpenEmbeddedDoIt() { m_currentView->stop(); m_currentView->setLocationBarURL(m_popupURL); m_currentView->setTypedURL(TQString::null); if ( m_currentView->changeViewMode( m_popupServiceType, m_popupService ) ) m_currentView->openURL( m_popupURL, m_popupURL.pathOrURL() ); } void KonqMainWindow::slotDatabaseChanged() { if ( KSycoca::isChanged("mimetypes") ) { MapViews::ConstIterator it = m_mapViews.begin(); MapViews::ConstIterator end = m_mapViews.end(); for (; it != end; ++it ) (*it)->callExtensionMethod( "refreshMimeTypes()" ); } } void KonqMainWindow::slotPopupPasteTo() { if ( !m_currentView || m_popupURL.isEmpty() ) return; m_currentView->callExtensionURLMethod( "pasteTo(const KURL&)", m_popupURL ); } void KonqMainWindow::slotReconfigure() { reparseConfiguration(); } void KonqMainWindow::reparseConfiguration() { kdDebug(1202) << "KonqMainWindow::reparseConfiguration() !" << endl; KonqSettings::self()->readConfig(); m_bSaveViewPropertiesLocally = KonqSettings::saveViewPropertiesLocally(); m_bHTMLAllowed = KonqSettings::htmlAllowed(); MapViews::ConstIterator it = m_mapViews.begin(); MapViews::ConstIterator end = m_mapViews.end(); for (; it != end; ++it ) (*it)->reparseConfiguration(); } void KonqMainWindow::saveProperties( KConfig *config ) { m_pViewManager->saveViewProfile( *config, true /* save URLs */, false ); } void KonqMainWindow::readProperties( KConfig *config ) { kdDebug(1202) << "KonqMainWindow::readProperties( KConfig *config )" << endl; m_pViewManager->loadViewProfile( *config, TQString::null /*no profile name*/ ); } void KonqMainWindow::setInitialFrameName( const TQString &name ) { m_initialFrameName = name; } void KonqMainWindow::slotActiontqStatusText( const TQString &text ) { if ( !m_currentView ) return; KonqFrameStatusBar *statusBar = m_currentView->frame()->statusbar(); if ( !statusBar ) return; statusBar->message( text ); } void KonqMainWindow::slotCleartqStatusText() { if ( !m_currentView ) return; KonqFrameStatusBar *statusBar = m_currentView->frame()->statusbar(); if ( !statusBar ) return; statusBar->slotClear(); } void KonqMainWindow::updateOpenWithActions() { unplugActionList( "openwith" ); m_openWithActions.clear(); if (!kapp->authorizeKAction("openwith")) return; const KTrader::OfferList & services = m_currentView->appServiceOffers(); KTrader::OfferList::ConstIterator it = services.begin(); KTrader::OfferList::ConstIterator end = services.end(); for (; it != end; ++it ) { KAction *action = new KAction( i18n( "Open with %1" ).arg( (*it)->name() ), 0, 0, (*it)->desktopEntryName().latin1() ); action->setIcon( (*it)->icon() ); connect( action, TQT_SIGNAL( activated() ), this, TQT_SLOT( slotOpenWith() ) ); m_openWithActions.append( action ); } if ( services.count() > 0 ) { m_openWithActions.append( new KActionSeparator ); plugActionList( "openwith", m_openWithActions ); } } TQString KonqMainWindow::viewModeActionKey( KService::Ptr service ) { TQString library = service->library(); // Group all non-builtin views together TQVariant builtIntoProp = service->property( "X-KDE-BrowserView-Built-Into" ); if ( !builtIntoProp.isValid() || builtIntoProp.toString() != "konqueror" ) library = "external"; return library; } void KonqMainWindow::updateViewModeActions() { unplugViewModeActions(); if ( m_viewModeMenu ) { TQPtrListIterator it( m_viewModeActions ); for (; it.current(); ++it ) it.current()->unplugAll(); delete m_viewModeMenu; } m_viewModeMenu = 0; m_toolBarViewModeActions.clear(); m_viewModeActions.clear(); // if we changed the viewmode to something new, then we have to // make sure to also clear our [libiconview,liblistview]->service-for-viewmode // map if ( m_viewModeToolBarServices.count() > 0 && !m_viewModeToolBarServices.begin().data()->serviceTypes().tqcontains( m_currentView->serviceType() ) ) { // Save the current map to the config file, for later reuse saveToolBarServicesMap(); m_viewModeToolBarServices.clear(); } KTrader::OfferList services = m_currentView->partServiceOffers(); if ( services.count() <= 1 ) return; m_viewModeMenu = new KActionMenu( i18n( "&View Mode" ), this ); // a temporary map, just like the m_viewModeToolBarServices map, but // mapping to a KonqViewModeAction object. It's just temporary as we // of use it to group the viewmode actions (iconview,multicolumnview, // treeview, etc.) into to two groups -> icon/list // Although I wrote this now only of icon/listview it has to work for // any view, that's why it's so general :) TQMap groupedServiceMap; // Another temporary map, the preferred service for each library (2 entries in our example) TQMap preferredServiceMap; KConfig * config = KGlobal::config(); config->setGroup( "ModeToolBarServices" ); KTrader::OfferList::ConstIterator it = services.begin(); KTrader::OfferList::ConstIterator end = services.end(); for (; it != end; ++it ) { TQVariant prop = (*it)->property( "X-KDE-BrowserView-Toggable" ); if ( prop.isValid() && prop.toBool() ) // No toggable views in view mode continue; KRadioAction *action; TQString itname = (*it)->genericName(); if (itname.isEmpty()) itname = (*it)->name(); TQString icon = (*it)->icon(); if ( icon != TQString::tqfromLatin1( "unknown" ) ) // we *have* to specify a parent qobject, otherwise the exclusive group stuff doesn't work!(Simon) action = new KRadioAction( itname, icon, 0, this, (*it)->desktopEntryName().ascii() ); else action = new KRadioAction( itname, 0, this, (*it)->desktopEntryName().ascii() ); action->setExclusiveGroup( "KonqMainWindow_ViewModes" ); connect( action, TQT_SIGNAL( toggled( bool ) ), this, TQT_SLOT( slotViewModeToggle( bool ) ) ); m_viewModeActions.append( action ); action->plug( m_viewModeMenu->popupMenu() ); const TQString library = viewModeActionKey( *it ); // look if we already have a KonqViewModeAction (in the toolbar) // for this component TQMap::Iterator mapIt = groupedServiceMap.find( library ); // if we don't have -> create one if ( mapIt == groupedServiceMap.end() ) { // default service on this action: the current one (i.e. the first one) TQString text = itname; TQString icon = (*it)->icon(); TQCString name = (*it)->desktopEntryName().latin1(); //kdDebug(1202) << " Creating action for " << library << ". Default service " << itname << endl; // if we previously changed the viewmode (see slotViewModeToggle!) // then we will want to use the previously used settings (previous as // in before the actions got deleted) TQMap::ConstIterator serviceIt = m_viewModeToolBarServices.find( library ); if ( serviceIt != m_viewModeToolBarServices.end() ) { kdDebug(1202) << " Setting action for " << library << " to " << (*serviceIt)->name() << endl; text = (*serviceIt)->genericName(); if (text.isEmpty()) text = (*serviceIt)->name(); icon = (*serviceIt)->icon(); name = (*serviceIt)->desktopEntryName().ascii(); } else { // if we don't have it in the map, we should look for a setting // for this library in the config file. TQString preferredService = config->readEntry( library ); if ( !preferredService.isEmpty() && name != preferredService.latin1() ) { //kdDebug(1202) << " Inserting into preferredServiceMap(" << library << ") : " << preferredService << endl; // The preferred service isn't the current one, so remember to set it later preferredServiceMap[ library ] = preferredService; } } KonqViewModeAction *tbAction = new KonqViewModeAction( text, icon, this, name ); tbAction->setExclusiveGroup( "KonqMainWindow_ToolBarViewModes" ); tbAction->setChecked( action->isChecked() ); connect( tbAction, TQT_SIGNAL( toggled( bool ) ), this, TQT_SLOT( slotViewModeToggle( bool ) ) ); m_toolBarViewModeActions.append( tbAction ); mapIt = groupedServiceMap.insert( library, tbAction ); } // Check the actions (toolbar button and menu item) if they correspond to the current view bool bIsCurrentView = (*it)->desktopEntryName() == m_currentView->service()->desktopEntryName(); if ( bIsCurrentView ) { action->setChecked( true ); } // Set the contents of the button from the current service, either if it's the current view // or if it's our preferred service for this button (library) if ( bIsCurrentView || ( preferredServiceMap.tqcontains( library ) && (*it)->desktopEntryName() == preferredServiceMap[ library ] ) ) { //kdDebug(1202) << " Changing action for " << library << " into service " << (*it)->name() << endl; TQString mapitname = (*it)->genericName(); if (mapitname.isEmpty()) mapitname = (*it)->name(); (*mapIt)->setText( mapitname ); (*mapIt)->setIcon( (*it)->icon() ); (*mapIt)->setName( (*it)->desktopEntryName().ascii() ); // tricky... preferredServiceMap.remove( library ); // The current view has priority over the saved settings } // plug action also into the delayed popupmenu of appropriate toolbar action action->plug( (*mapIt)->popupMenu() ); } #ifndef NDEBUG // Note that this can happen (map not empty) when a inode/directory view is removed, // and remains in the KConfig file. Q_ASSERT( preferredServiceMap.isEmpty() ); TQMap::Iterator debugIt = preferredServiceMap.begin(); TQMap::Iterator debugEnd = preferredServiceMap.end(); for ( ; debugIt != debugEnd ; ++debugIt ) kdDebug(1202) << " STILL IN preferredServiceMap : " << debugIt.key() << " | " << debugIt.data() << endl; #endif if ( !m_currentView->isToggleView() ) // No view mode for toggable views // (The other way would be to enforce a better servicetype for them, than Browser/View) if ( /* already tested: services.count() > 1 && */ m_viewModeMenu ) plugViewModeActions(); } void KonqMainWindow::saveToolBarServicesMap() { TQMap::ConstIterator serviceIt = m_viewModeToolBarServices.begin(); TQMap::ConstIterator serviceEnd = m_viewModeToolBarServices.end(); KConfig * config = KGlobal::config(); config->setGroup( "ModeToolBarServices" ); for ( ; serviceIt != serviceEnd ; ++serviceIt ) config->writeEntry( serviceIt.key(), serviceIt.data()->desktopEntryName() ); config->sync(); } void KonqMainWindow::plugViewModeActions() { TQPtrList lst; lst.append( m_viewModeMenu ); plugActionList( "viewmode", lst ); // display the toolbar viewmode icons only for inode/directory, as here we have dedicated icons if ( m_currentView && m_currentView->supportsServiceType( "inode/directory" ) ) plugActionList( "viewmode_toolbar", m_toolBarViewModeActions ); } void KonqMainWindow::unplugViewModeActions() { unplugActionList( "viewmode" ); unplugActionList( "viewmode_toolbar" ); } KonqMainWindowIface* KonqMainWindow::dcopObject() { return m_dcopObject; } void KonqMainWindow::updateBookmarkBar() { KToolBar * bar = static_cast( child( "bookmarkToolBar", "KToolBar" ) ); if (!bar) return; // hide if empty if (m_paBookmarkBar && bar->count() == 0 ) bar->hide(); } void KonqMainWindow::closeEvent( TQCloseEvent *e ) { kdDebug(1202) << "KonqMainWindow::closeEvent begin" << endl; // This breaks session management (the window is withdrawn in kwin) // so let's do this only when closed by the user. if ( static_cast(kapp)->closedByUser() ) { if ( viewManager()->docContainer() && viewManager()->docContainer()->frameType()=="Tabs" ) { KonqFrameTabs* tabContainer = static_cast(viewManager()->docContainer()); if ( tabContainer->count() > 1 ) { KConfig *config = KGlobal::config(); KConfigGroupSaver cs( config, TQString::tqfromLatin1("Notification Messages") ); if ( !config->hasKey( "MultipleTabConfirm" ) ) { switch ( KMessageBox::warningYesNoCancel( this, i18n("You have multiple tabs open in this window, " "are you sure you want to quit?"), i18n("Confirmation"), KStdGuiItem::quit(), KGuiItem(i18n( "C&lose Current Tab" ), "tab_remove"), "MultipleTabConfirm" ) ) { case KMessageBox::Yes : break; case KMessageBox::No : { e->ignore(); slotRemoveTab(); return; } break; case KMessageBox::Cancel : { e->ignore(); return; } } } } KonqView *originalView = m_currentView; MapViews::ConstIterator it = m_mapViews.begin(); MapViews::ConstIterator end = m_mapViews.end(); for (; it != end; ++it ) { KonqView *view = it.data(); if (view && view->part() && (view->part()->tqmetaObject()->findProperty("modified") != -1) ) { TQVariant prop = view->part()->property("modified"); if (prop.isValid() && prop.toBool()) { m_pViewManager->showTab( view ); if ( KMessageBox::warningContinueCancel( this, i18n("This tab tqcontains changes that have not been submitted.\nClosing the window will discard these changes."), i18n("Discard Changes?"), KGuiItem(i18n("&Discard Changes"),"exit"), "discardchangesclose") != KMessageBox::Continue ) { e->ignore(); m_pViewManager->showTab( originalView ); return; } } } } // m_pViewManager->showTab( originalView ); } else if ( m_currentView && m_currentView->part() && (m_currentView->part()->tqmetaObject()->findProperty("modified") != -1) ) { TQVariant prop = m_currentView->part()->property("modified"); if (prop.isValid() && prop.toBool()) if ( KMessageBox::warningContinueCancel( this, i18n("This page tqcontains changes that have not been submitted.\nClosing the window will discard these changes."), i18n("Discard Changes?"), KGuiItem(i18n("&Discard Changes"),"exit"), "discardchangesclose") != KMessageBox::Continue ) { e->ignore(); return; } } // save size to have something to restore if the profile does not contain size saveWindowSize(); hide(); tqApp->flushX(); } // We're going to close - tell the parts MapViews::ConstIterator it = m_mapViews.begin(); MapViews::ConstIterator end = m_mapViews.end(); for (; it != end; ++it ) { if ( (*it)->part() && (*it)->part()->widget() ) TQApplication::sendEvent( (*it)->part()->widget(), e ); } KParts::MainWindow::closeEvent( e ); if( isPreloaded() && !kapp->sessionSaving()) { // queryExit() refused closing, hide instead hide(); } kdDebug(1202) << "KonqMainWindow::closeEvent end" << endl; } bool KonqMainWindow::queryExit() { if( kapp->sessionSaving()) // *sigh* return true; return !stayPreloaded(); } void KonqMainWindow::setIcon( const TQPixmap& pix ) { KParts::MainWindow::setIcon( pix ); TQPixmap big = pix; TQString url = m_combo->currentText(); if ( !url.isEmpty() ) big = KonqPixmapProvider::self()->pixmapFor( url, KIcon::SizeMedium ); KWin::setIcons( winId(), big, pix ); } void KonqMainWindow::slotIntro() { openURL( 0L, KURL("about:konqueror") ); } void KonqMainWindow::goURL() { TQLineEdit *lineEdit = m_combo->lineEdit(); if ( !lineEdit ) return; TQKeyEvent event( TQEvent::KeyPress, Key_Return, '\n', 0 ); TQApplication::sendEvent( lineEdit, &event ); } void KonqMainWindow::slotLocationLabelActivated() { focusLocationBar(); m_combo->lineEdit()->selectAll(); } void KonqMainWindow::slotOpenURL( const KURL& url ) { openURL( 0L, url ); } bool KonqMainWindow::sidebarVisible() const { KAction *a = m_toggleViewGUIClient->action("konq_sidebartng"); return (a && static_cast(a)->isChecked()); } void KonqMainWindow::slotAddWebSideBar(const KURL& url, const TQString& name) { if (url.url().isEmpty() && name.isEmpty()) return; kdDebug(1202) << "Requested to add URL " << url << " [" << name << "] to the sidebar!" << endl; KAction *a = m_toggleViewGUIClient->action("konq_sidebartng"); if (!a) { KMessageBox::sorry(0L, i18n("Your sidebar is not functional or unavailable. A new entry cannot be added."), i18n("Web Sidebar")); return; } int rc = KMessageBox::questionYesNo(0L, i18n("Add new web extension \"%1\" to your sidebar?") .arg(name.isEmpty() ? name : url.prettyURL()), i18n("Web Sidebar"),i18n("Add"),i18n("Do Not Add")); if (rc == KMessageBox::Yes) { // Show the sidebar if (!static_cast(a)->isChecked()) { a->activate(); } // Tell it to add a new panel MapViews::ConstIterator it; for (it = viewMap().begin(); it != viewMap().end(); ++it) { KonqView *view = it.data(); if (view) { KService::Ptr svc = view->service(); if (svc->desktopEntryName() == "konq_sidebartng") { emit view->browserExtension()->addWebSideBar(url, name); break; } } } } } void KonqMainWindow::bookmarksIntoCompletion( const KBookmarkGroup& group ) { static const TQString& http = KGlobal::staticQString( "http" ); static const TQString& ftp = KGlobal::staticQString( "ftp" ); if ( group.isNull() ) return; for ( KBookmark bm = group.first(); !bm.isNull(); bm = group.next(bm) ) { if ( bm.isGroup() ) { bookmarksIntoCompletion( bm.toGroup() ); continue; } KURL url = bm.url(); if ( !url.isValid() ) continue; TQString u = url.prettyURL(); s_pCompletion->addItem( u ); if ( url.isLocalFile() ) s_pCompletion->addItem( url.path() ); else if ( url.protocol() == http ) s_pCompletion->addItem( u.mid( 7 )); else if ( url.protocol() == ftp && url.host().startsWith( ftp ) ) s_pCompletion->addItem( u.mid( 6 ) ); } } void KonqMainWindow::connectActionCollection( KActionCollection *coll ) { connect( coll, TQT_SIGNAL( actiontqStatusText( const TQString & ) ), this, TQT_SLOT( slotActiontqStatusText( const TQString & ) ) ); connect( coll, TQT_SIGNAL( cleartqStatusText() ), this, TQT_SLOT( slotCleartqStatusText() ) ); } void KonqMainWindow::disconnectActionCollection( KActionCollection *coll ) { disconnect( coll, TQT_SIGNAL( actiontqStatusText( const TQString & ) ), this, TQT_SLOT( slotActiontqStatusText( const TQString & ) ) ); disconnect( coll, TQT_SIGNAL( cleartqStatusText() ), this, TQT_SLOT( slotCleartqStatusText() ) ); } // // the smart popup completion code , // // prepend http://www. or http:// if there's no protocol in 's' // used only when there are no completion matches static TQString hp_tryPrepend( const TQString& s ) { if( s.isEmpty() || s[ 0 ] == '/' ) return TQString::null; for( unsigned int pos = 0; pos < s.length() - 2; // 4 = ://x ++pos ) { if( s[ pos ] == ':' && s[ pos + 1 ] == '/' && s[ pos + 2 ] == '/' ) return TQString::null; if( !s[ pos ].isLetter() ) break; } return ( s.startsWith( "www." ) ? "http://" : "http://www." ) + s; } static void hp_removeDupe( KCompletionMatches& l, const TQString& dupe, KCompletionMatches::Iterator it_orig ) { for( KCompletionMatches::Iterator it = l.begin(); it != l.end(); ) { if( it == it_orig ) { ++it; continue; } if( (*it).value() == dupe ) { (*it_orig).first = kMax( (*it_orig).first, (*it).index()); it = l.remove( it ); continue; } ++it; } } // remove duplicates like 'http://www.kde.org' and 'http://www.kde.org/' // (i.e. the trailing slash) // some duplicates are also created by prepending protocols static void hp_removeDuplicates( KCompletionMatches& l ) { TQString http = "http://"; TQString ftp = "ftp://ftp."; TQString file = "file:"; TQString file2 = "file://"; l.removeDuplicates(); for( KCompletionMatches::Iterator it = l.begin(); it != l.end(); ++it ) { TQString str = (*it).value(); if( str.startsWith( http )) { if( str.find( '/', 7 ) < 0 ) { // http://something hp_removeDupe( l, str + '/', it ); hp_removeDupe( l, str.mid( 7 ) + '/', it ); } else if( str[ str.length() - 1 ] == '/' ) { hp_removeDupe( l, str.left( str.length() - 1 ), it ); hp_removeDupe( l, str.left( str.length() - 1 ).mid( 7 ), it ); } hp_removeDupe( l, str.mid( 7 ), it ); } else if( str.startsWith( ftp )) // ftp://ftp. hp_removeDupe( l, str.mid( 6 ), it ); // remove dupes without ftp:// else if( str.startsWith( file2 )) hp_removeDupe( l, str.mid( 7 ), it ); // remove dupes without file:// else if( str.startsWith( file )) hp_removeDupe( l, str.mid( 5 ), it ); // remove dupes without file: } } static void hp_removeCommonPrefix( KCompletionMatches& l, const TQString& prefix ) { for( KCompletionMatches::Iterator it = l.begin(); it != l.end(); ) { if( (*it).value().startsWith( prefix )) { it = l.remove( it ); continue; } ++it; } } // don't include common prefixes like 'http://', i.e. when s == 'h', include // http://hotmail.com but don't include everything just starting with 'http://' static void hp_checkCommonPrefixes( KCompletionMatches& matches, const TQString& s ) { static const char* const prefixes[] = { "http://", "https://", "www.", "ftp://", "http://www.", "https://www.", "ftp://ftp.", "file:", "file://", NULL }; for( const char* const *pos = prefixes; *pos != NULL; ++pos ) { TQString prefix = *pos; if( prefix.startsWith( s )) { hp_removeCommonPrefix( matches, prefix ); } } } TQStringList KonqMainWindow::historyPopupCompletionItems( const TQString& s) { const TQString http = "http://"; const TQString https = "https://"; const TQString www = "http://www."; const TQString wwws = "https://www."; const TQString ftp = "ftp://"; const TQString ftpftp = "ftp://ftp."; const TQString file = "file:"; // without /, because people enter /usr etc. const TQString file2 = "file://"; if( s.isEmpty()) return TQStringList(); KCompletionMatches matches= s_pCompletion->allWeightedMatches( s ); hp_checkCommonPrefixes( matches, s ); bool checkDuplicates = false; if ( !s.startsWith( ftp ) ) { matches += s_pCompletion->allWeightedMatches( ftp + s ); if( TQString( "ftp." ).startsWith( s )) hp_removeCommonPrefix( matches, ftpftp ); checkDuplicates = true; } if ( !s.startsWith( https ) ) { matches += s_pCompletion->allWeightedMatches( https + s ); if( TQString( "www." ).startsWith( s )) hp_removeCommonPrefix( matches, wwws ); checkDuplicates = true; } if ( !s.startsWith( http )) { matches += s_pCompletion->allWeightedMatches( http + s ); if( TQString( "www." ).startsWith( s )) hp_removeCommonPrefix( matches, www ); checkDuplicates = true; } if ( !s.startsWith( www ) ) { matches += s_pCompletion->allWeightedMatches( www + s ); checkDuplicates = true; } if ( !s.startsWith( wwws ) ) { matches += s_pCompletion->allWeightedMatches( wwws + s ); checkDuplicates = true; } if ( !s.startsWith( ftpftp ) ) { matches += s_pCompletion->allWeightedMatches( ftpftp + s ); checkDuplicates = true; } if ( !s.startsWith( file ) ) { matches += s_pCompletion->allWeightedMatches( file + s ); checkDuplicates = true; } if ( !s.startsWith( file2 ) ) { matches += s_pCompletion->allWeightedMatches( file2 + s ); checkDuplicates = true; } if( checkDuplicates ) hp_removeDuplicates( matches ); TQStringList items = matches.list(); if( items.count() == 0 && !s.tqcontains( ':' ) && s[ 0 ] != '/' ) { TQString pre = hp_tryPrepend( s ); if( !pre.isNull()) items += pre; } return items; } #ifndef NDEBUG void KonqMainWindow::dumpViewList() { MapViews::Iterator end = m_mapViews.end(); kdDebug(1202) << m_mapViews.count() << "Views" << endl; for (MapViews::Iterator it = m_mapViews.begin(); it != end; it++) { kdDebug(1202) << it.data() << endl; } } #endif // KonqFrameContainerBase implementation BEGIN /** * Call this after inserting a new frame into the splitter. */ void KonqMainWindow::insertChildFrame( KonqFrameBase * frame, int /*index*/ ) { m_pChildFrame = frame; m_pActiveChild = frame; frame->setParentContainer(this); setCentralWidget( frame->widget() ); } /** * Call this before deleting one of our children. */ void KonqMainWindow::removeChildFrame( KonqFrameBase * /*frame*/ ) { m_pChildFrame = 0L; m_pActiveChild = 0L; } void KonqMainWindow::saveConfig( KConfig* config, const TQString &prefix, bool saveURLs, KonqFrameBase* docContainer, int id, int depth ) { if( m_pChildFrame ) m_pChildFrame->saveConfig( config, prefix, saveURLs, docContainer, id, depth); } void KonqMainWindow::copyHistory( KonqFrameBase *other ) { if( m_pChildFrame ) m_pChildFrame->copyHistory( other ); } void KonqMainWindow::printFrameInfo( const TQString &spaces ) { if( m_pChildFrame ) m_pChildFrame->printFrameInfo( spaces ); } void KonqMainWindow::reparentFrame( TQWidget* /*parent*/, const TQPoint & /*p*/, bool /*showIt*/ ) { return; } KonqFrameContainerBase* KonqMainWindow::parentContainer()const { return 0L; } void KonqMainWindow::setParentContainer(KonqFrameContainerBase* /*parent*/) { return; } void KonqMainWindow::setTitle( const TQString &/*title*/ , TQWidget* /*sender*/) { return; } void KonqMainWindow::setTabIcon( const KURL &/*url*/, TQWidget* /*sender*/ ) { return; } TQWidget* KonqMainWindow::widget() { return this; } void KonqMainWindow::listViews( ChildViewList *viewList ) { if( m_pChildFrame ) m_pChildFrame->listViews( viewList ); } TQCString KonqMainWindow::frameType() { return TQCString("MainWindow"); } KonqFrameBase* KonqMainWindow::childFrame()const { return m_pChildFrame; } void KonqMainWindow::setActiveChild( KonqFrameBase* /*activeChild*/ ) { return; } bool KonqMainWindow::isMimeTypeAssociatedWithSelf( const TQString &mimeType ) { return isMimeTypeAssociatedWithSelf( mimeType, KServiceTypeProfile::preferredService( mimeType, "Application" ) ); } bool KonqMainWindow::isMimeTypeAssociatedWithSelf( const TQString &/*mimeType*/, const KService::Ptr &offer ) { // Prevention against user stupidity : if the associated app for this mimetype // is konqueror/kfmclient, then we'll loop forever. So we have to // 1) force embedding first, if that works we're ok // 2) check what KRun is going to do before calling it. return ( offer && ( offer->desktopEntryName() == "konqueror" || offer->exec().stripWhiteSpace().startsWith( "kfmclient" ) ) ); } // KonqFrameContainerBase implementation END void KonqMainWindow::setPreloadedFlag( bool preloaded ) { if( s_preloaded == preloaded ) return; s_preloaded = preloaded; if( s_preloaded ) { kapp->disableSessionManagement(); // dont restore preloaded konqy's return; // was registered before calling this } delete s_preloadedWindow; // preloaded state was abandoned without reusing the window s_preloadedWindow = NULL; kapp->enableSessionManagement(); // enable SM again DCOPRef ref( "kded", "konqy_preloader" ); ref.send( "unregisterPreloadedKonqy", kapp->dcopClient()->appId()); } void KonqMainWindow::setPreloadedWindow( KonqMainWindow* window ) { s_preloadedWindow = window; if( window == NULL ) return; window->viewManager()->clear(); KIO::Scheduler::unregisterWindow( window ); } // used by preloading - this KonqMainWindow will be reused, reset everything // that won't be reset by loading a profile void KonqMainWindow::resetWindow() { char data[ 1 ]; // empty append to get current X timestamp TQWidget tmp_widget; XChangeProperty( qt_xdisplay(), tmp_widget.winId(), XA_WM_CLASS, XA_STRING, 8, PropModeAppend, (unsigned char*) &data, 0 ); XEvent ev; XWindowEvent( qt_xdisplay(), tmp_widget.winId(), PropertyChangeMask, &ev ); long x_time = ev.xproperty.time; // bad hack - without updating the _KDE_NET_WM_USER_CREATION_TIME property, // KWin will apply don't_steal_focus to this window, and will not make it active // (shows mainly with 'konqueror --preload') static Atom atom = XInternAtom( qt_xdisplay(), "_KDE_NET_WM_USER_CREATION_TIME", False ); XChangeProperty( qt_xdisplay(), winId(), atom, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &x_time, 1); extern Time qt_x_user_time; // reset also user time, so that this window qt_x_user_time = CurrentTime; // won't have _NET_WM_USER_TIME set #if !KDE_IS_VERSION( 3, 2, 90 ) // _KDE_NET_USER_TIME is obsolete static Atom atom2 = XInternAtom( qt_xdisplay(), "_KDE_NET_USER_TIME", False ); timeval tv; gettimeofday( &tv, NULL ); unsigned long now = tv.tv_sec * 10 + tv.tv_usec / 100000; XChangeProperty(qt_xdisplay(), winId(), atom2, XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&now, 1); #endif static Atom atom3 = XInternAtom( qt_xdisplay(), "_NET_WM_USER_TIME", False ); XDeleteProperty( qt_xdisplay(), winId(), atom3 ); // Qt remembers the iconic state if the window was withdrawn while on another virtual desktop clearWState( WState_Minimized ); ignoreInitialGeometry(); kapp->setTopWidget( this ); // set again the default window icon } bool KonqMainWindow::event( TQEvent* e ) { if( e->type() == TQEvent::DeferredDelete ) { // since the preloading code tries to reuse KonqMainWindow, // the last window shouldn't be really deleted, but only hidden // deleting WDestructiveClose windows is done using deleteLater(), // so catch TQEvent::DefferedDelete and check if this window should stay if( stayPreloaded()) { setWFlags(WDestructiveClose); // was reset before deleteLater() return true; // no deleting } } return KParts::MainWindow::event( e ); } bool KonqMainWindow::stayPreloaded() { // last window? if( mainWindowList()->count() > 1 ) return false; // not running in full KDE environment? if( getenv( "KDE_FULL_SESSION" ) == NULL || getenv( "KDE_FULL_SESSION" )[ 0 ] == '\0' ) return false; // not the same user like the one running the session (most likely we're run via sudo or something) if( getenv( "KDE_SESSION_UID" ) != NULL && uid_t( atoi( getenv( "KDE_SESSION_UID" ))) != getuid()) return false; if( KonqSettings::maxPreloadCount() == 0 ) return false; viewManager()->clear(); // reduce resource usage before checking it if( !checkPreloadResourceUsage()) return false; DCOPRef ref( "kded", "konqy_preloader" ); if( !ref.callExt( "registerPreloadedKonqy", DCOPRef::NoEventLoop, 5000, kapp->dcopClient()->appId(), qt_xscreen())) { return false; } KonqMainWindow::setPreloadedFlag( true ); kdDebug(1202) << "Konqy kept for preloading :" << kapp->dcopClient()->appId() << endl; KonqMainWindow::setPreloadedWindow( this ); return true; } // try to avoid staying running when leaking too much memory // this is checked by using mallinfo() and comparing // memory usage during konqy startup and now, if the difference // is too large -> leaks -> quit // also, if this process is running for too long, or has been // already reused too many times -> quit, just in case bool KonqMainWindow::checkPreloadResourceUsage() { if( #ifndef NDEBUG isatty( STDIN_FILENO ) || #endif isatty( STDOUT_FILENO ) || isatty( STDERR_FILENO )) { kdDebug(1202) << "Running from tty, not keeping for preloading" << endl; return false; } int limit; int usage = current_memory_usage( &limit ); kdDebug(1202) << "Memory usage increase: " << ( usage - s_initialMemoryUsage ) << " (" << usage << "/" << s_initialMemoryUsage << "), increase limit: " << limit << endl; int max_allowed_usage = s_initialMemoryUsage + limit; if( usage > max_allowed_usage ) // too much memory used? { kdDebug(1202) << "Not keeping for preloading due to high memory usage" << endl; return false; } // working memory usage test ( usage != 0 ) makes others less strict if( ++s_preloadUsageCount > ( usage != 0 ? 100 : 10 )) // reused too many times? { kdDebug(1202) << "Not keeping for preloading due to high usage count" << endl; return false; } if( time( NULL ) > s_startupTime + 60 * 60 * ( usage != 0 ? 4 : 1 )) // running for too long? { kdDebug(1202) << "Not keeping for preloading due to long usage time" << endl; return false; } return true; } static int current_memory_usage( int* limit ) { #ifdef __linux__ // Check whole memory usage - VmSize TQFile f( TQCString().sprintf( "/proc/%i/statm", getpid())); if( f.open( IO_ReadOnly )) { TQString line; if( f.readLine( line, 1024 ) > 0 ) { line = line.stripWhiteSpace(); int usage = line.section( ' ', 0, 0 ).toInt(); if( usage > 0 ) { int pagesize = sysconf (_SC_PAGE_SIZE); if( pagesize < 0 ) pagesize = 4096; if( limit != NULL ) *limit = 16 * 1024 * 1024; return usage * pagesize; } } } kdWarning() << "Couldn't read VmSize from /proc/*/statm." << endl; #endif // Check malloc() usage - very imprecise, but better than nothing. int usage_sum = 0; #if defined(KDE_MALLINFO_STDLIB) || defined(KDE_MALLINFO_MALLOC) // ugly hack for kdecore/malloc extern int kde_malloc_is_used; free( calloc( 4, 4 )); // trigger setting kde_malloc_is_used if( kde_malloc_is_used ) { struct mallinfo m = mallinfo(); usage_sum = m.hblkhd + m.uordblks; } else { struct mallinfo m = mallinfo(); #ifdef KDE_MALLINFO_FIELD_hblkhd usage_sum += m.hblkhd; #endif #ifdef KDE_MALLINFO_FIELD_uordblks usage_sum += m.uordblks; #endif #ifdef KDE_MALLINFO_FIELD_usmblks usage_sum += m.usmblks; #endif } // unlike /proc , this doesn't include things like size of dlopened modules, // and also doesn't include malloc overhead if( limit != NULL ) *limit = 6 * 1024 * 1024; #endif return usage_sum; } void KonqMainWindow::saveWindowSize() const { TQString savedGroup = KGlobal::config()->group(); KGlobal::config()->setGroup( "KonqMainWindow_Size" ); KParts::MainWindow::saveWindowSize( KGlobal::config() ); KGlobal::config()->setGroup( savedGroup ); KGlobal::config()->sync(); } void KonqMainWindow::restoreWindowSize() { TQString savedGroup = KGlobal::config()->group(); KGlobal::config()->setGroup( "KonqMainWindow_Size" ); KParts::MainWindow::restoreWindowSize( KGlobal::config() ); KGlobal::config()->setGroup( savedGroup ); } #include "konq_mainwindow.moc" #include "konq_mainwindow_p.moc" /* vim: et sw=4 ts=4 */