diff options
Diffstat (limited to 'lib/widgets/kdevhtmlpart.cpp')
-rw-r--r-- | lib/widgets/kdevhtmlpart.cpp | 512 |
1 files changed, 512 insertions, 0 deletions
diff --git a/lib/widgets/kdevhtmlpart.cpp b/lib/widgets/kdevhtmlpart.cpp new file mode 100644 index 00000000..76697cfa --- /dev/null +++ b/lib/widgets/kdevhtmlpart.cpp @@ -0,0 +1,512 @@ +#include <tqfile.h> +#include <tqclipboard.h> +#include <tqapplication.h> + +#include <kxmlguiclient.h> +#include <tdeaction.h> +#include <kstdaction.h> +#include <kstandarddirs.h> +#include <tdelocale.h> +#include <tdepopupmenu.h> +#include <kiconloader.h> +#include <tdemainwindow.h> +#include <tdehtmlview.h> +#include <tdehtml_settings.h> +#include <tdeconfig.h> + +#include <kdevmainwindow.h> + + +#include "kdevhtmlpart.h" + +KDevHTMLPart::KDevHTMLPart() + : TDEHTMLPart(0L, 0L, 0L, "KDevHTMLPart", DefaultGUI ) +{ + setXMLFile(locate("data", "tdevelop/kdevhtml_partui.rc"), true); + + connect(browserExtension(), TQT_SIGNAL(openURLRequestDelayed(const KURL &,const KParts::URLArgs &)), + this, TQT_SLOT(openURLRequest(const KURL &)) ); + + connect(this, TQT_SIGNAL(started(TDEIO::Job *)), this, TQT_SLOT(slotStarted(TDEIO::Job* ))); + connect(this, TQT_SIGNAL(completed()), this, TQT_SLOT(slotCompleted())); + connect(this, TQT_SIGNAL(canceled(const TQString &)), this, TQT_SLOT(slotCancelled(const TQString &))); + + TDEActionCollection * actions = actionCollection();// new TDEActionCollection( this ); + reloadAction = new TDEAction( i18n( "Reload" ), "reload", 0, + this, TQT_SLOT( slotReload() ), actions, "doc_reload" ); + reloadAction->setWhatsThis(i18n("<b>Reload</b><p>Reloads the current document.")); + stopAction = new TDEAction( i18n( "Stop" ), "stop", 0, + this, TQT_SLOT( slotStop() ), actions, "doc_stop" ); + stopAction->setWhatsThis(i18n("<b>Stop</b><p>Stops the loading of current document.")); + duplicateAction = new TDEAction( i18n( "Duplicate Tab" ), "window_new", 0, + this, TQT_SLOT( slotDuplicate() ), actions, "doc_dup" ); + duplicateAction->setWhatsThis(i18n("<b>Duplicate window</b><p>Opens current document in a new window.")); + printAction = KStdAction::print(this, TQT_SLOT(slotPrint()), actions, "print_doc"); + copyAction = KStdAction::copy(this, TQT_SLOT(slotCopy()), actions, "copy_doc_selection"); + + connect( this, TQT_SIGNAL(popupMenu(const TQString &, const TQPoint &)), this, TQT_SLOT(popup(const TQString &, const TQPoint &))); + connect(this, TQT_SIGNAL(selectionChanged()), this, TQT_SLOT(slotSelectionChanged())); + +//BEGIN documentation history stuff + + m_backAction = new TDEToolBarPopupAction(i18n("Back"), "back", 0, + this, TQT_SLOT(slotBack()), + actions, "browser_back"); + m_backAction->setEnabled( false ); + m_backAction->setToolTip(i18n("Back")); + m_backAction->setWhatsThis(i18n("<b>Back</b><p>Moves backwards one step in the <b>documentation</b> browsing history.")); + + connect(m_backAction->popupMenu(), TQT_SIGNAL(aboutToShow()), + this, TQT_SLOT(slotBackAboutToShow())); + connect(m_backAction->popupMenu(), TQT_SIGNAL(activated(int)), + this, TQT_SLOT(slotPopupActivated(int))); + + m_forwardAction = new TDEToolBarPopupAction(i18n("Forward"), "forward", 0, + this, TQT_SLOT(slotForward()), + actions, "browser_forward"); + m_forwardAction->setEnabled( false ); + m_forwardAction->setToolTip(i18n("Forward")); + m_forwardAction->setWhatsThis(i18n("<b>Forward</b><p>Moves forward one step in the <b>documentation</b> browsing history.")); + + connect(m_forwardAction->popupMenu(), TQT_SIGNAL(aboutToShow()), + this, TQT_SLOT(slotForwardAboutToShow())); + connect(m_forwardAction->popupMenu(), TQT_SIGNAL(activated(int)), + this, TQT_SLOT(slotPopupActivated(int))); + + m_restoring = false; + m_Current = m_history.end(); +//END documentation history stuff + + //settings: + TDEConfig *appConfig = TDEGlobal::config(); + appConfig->setGroup("TDEHTMLPart"); + setStandardFont(appConfig->readEntry("StandardFont", + settings()->stdFontName())); + setFixedFont(appConfig->readEntry("FixedFont", + settings()->fixedFontName())); + setZoomFactor(appConfig->readEntry("Zoom", "100").toInt()); +} + +void KDevHTMLPart::popup( const TQString & url, const TQPoint & p ) +{ +// TDEPopupMenu popup( i18n( "Documentation Viewer" ), this->widget() ); + TDEPopupMenu popup(this->widget()); + + bool needSep = false; + int idNewWindow = -2; + if (!url.isEmpty() && (m_options & CanOpenInNewWindow)) + { + idNewWindow = popup.insertItem(SmallIcon("window_new"),i18n("Open in New Tab")); + popup.TQMenuData::setWhatsThis(idNewWindow, i18n("<b>Open in new window</b><p>Opens current link in a new window.")); + needSep = true; + } + if (m_options & CanDuplicate) + { + duplicateAction->plug(&popup); + needSep = true; + } + if (needSep) + popup.insertSeparator(); + + m_backAction->plug( &popup ); + m_forwardAction->plug( &popup ); + reloadAction->plug(&popup); +// stopAction->plug(&popup); + popup.insertSeparator(); + + copyAction->plug( &popup ); + popup.insertSeparator(); + + printAction->plug(&popup); + popup.insertSeparator(); + + TDEAction * incFontAction = this->action("incFontSizes"); + TDEAction * decFontAction = this->action("decFontSizes"); + if ( incFontAction && decFontAction ) + { + incFontAction->plug( &popup ); + decFontAction->plug( &popup ); + popup.insertSeparator(); + } + + TDEAction *ac = action("setEncoding"); + if (ac) + ac->plug(&popup); + + int r = popup.exec(p); + + if (r == idNewWindow) + { + KURL kurl; + if (!KURL(url).path().startsWith("/")) + { + kdDebug() << "processing relative url: " << url << endl; + if (url.startsWith("#")) + { + kurl = KURL(KDevHTMLPart::url()); + kurl.setRef(url.mid(1)); + } + else + kurl = KURL(KDevHTMLPart::url().upURL().url(true)+url); + } + else + kurl = KURL(url); + + if (kurl.isValid()) + slotOpenInNewWindow(kurl); + } +} + +void KDevHTMLPart::setContext(const TQString &context) +{ + m_context = context; +} + + +TQString KDevHTMLPart::context() const +{ + return m_context; +} + + +// Note: this function is a copy of code in tdecore/tdeconfigbase.cpp ;) +static bool isUtf8(const char *buf) { + int i, n; + register unsigned char c; + bool gotone = false; + +#define F 0 /* character never appears in text */ +#define T 1 /* character appears in plain ASCII text */ +#define I 2 /* character appears in ISO-8859 text */ +#define X 3 /* character appears in non-ISO extended ASCII (Mac, IBM PC) */ + + static const unsigned char text_chars[256] = { + /* BEL BS HT LF FF CR */ + F, F, F, F, F, F, F, T, T, T, T, F, T, T, F, F, /* 0x0X */ + /* ESC */ + F, F, F, F, F, F, F, F, F, F, F, T, F, F, F, F, /* 0x1X */ + T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, /* 0x2X */ + T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, /* 0x3X */ + T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, /* 0x4X */ + T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, /* 0x5X */ + T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, /* 0x6X */ + T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, F, /* 0x7X */ + /* NEL */ + X, X, X, X, X, T, X, X, X, X, X, X, X, X, X, X, /* 0x8X */ + X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, /* 0x9X */ + I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, /* 0xaX */ + I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, /* 0xbX */ + I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, /* 0xcX */ + I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, /* 0xdX */ + I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, /* 0xeX */ + I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I /* 0xfX */ + }; + + /* *ulen = 0; */ + for (i = 0; (c = buf[i]); i++) { + if ((c & 0x80) == 0) { /* 0xxxxxxx is plain ASCII */ + /* + * Even if the whole file is valid UTF-8 sequences, + * still reject it if it uses weird control characters. + */ + + if (text_chars[c] != T) + return false; + + } else if ((c & 0x40) == 0) { /* 10xxxxxx never 1st byte */ + return false; + } else { /* 11xxxxxx begins UTF-8 */ + int following; + + if ((c & 0x20) == 0) { /* 110xxxxx */ + following = 1; + } else if ((c & 0x10) == 0) { /* 1110xxxx */ + following = 2; + } else if ((c & 0x08) == 0) { /* 11110xxx */ + following = 3; + } else if ((c & 0x04) == 0) { /* 111110xx */ + following = 4; + } else if ((c & 0x02) == 0) { /* 1111110x */ + following = 5; + } else + return false; + + for (n = 0; n < following; n++) { + i++; + if (!(c = buf[i])) + goto done; + + if ((c & 0x80) == 0 || (c & 0x40)) + return false; + } + gotone = true; + } + } +done: + return gotone; /* don't claim it's UTF-8 if it's all 7-bit */ +} +#undef F +#undef T +#undef I +#undef X + +TQString KDevHTMLPart::resolveEnvVarsInURL(const TQString& url) +{ + // check for environment variables and make necessary translations + TQString path = url; + int nDollarPos = path.find( '$' ); + + // Note: the while loop below is a copy of code in tdecore/tdeconfigbase.cpp ;) + while( nDollarPos != -1 && nDollarPos+1 < static_cast<int>(path.length())) { + // there is at least one $ + if( (path)[nDollarPos+1] == '(' ) { + uint nEndPos = nDollarPos+1; + // the next character is no $ + while ( (nEndPos <= path.length()) && (path[nEndPos]!=')') ) + nEndPos++; + nEndPos++; + TQString cmd = path.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); + } + path.replace( nDollarPos, nEndPos-nDollarPos, result ); + } else if( (path)[nDollarPos+1] != '$' ) { + uint nEndPos = nDollarPos+1; + // the next character is no $ + TQString aVarName; + if (path[nEndPos]=='{') + { + while ( (nEndPos <= path.length()) && (path[nEndPos]!='}') ) + nEndPos++; + nEndPos++; + aVarName = path.mid( nDollarPos+2, nEndPos-nDollarPos-3 ); + } + else + { + while ( nEndPos <= path.length() && (path[nEndPos].isNumber() + || path[nEndPos].isLetter() || path[nEndPos]=='_' ) ) + nEndPos++; + aVarName = path.mid( nDollarPos+1, nEndPos-nDollarPos-1 ); + } + const char* pEnv = 0; + if (!aVarName.isEmpty()) + pEnv = getenv( aVarName.ascii() ); + if( pEnv ) { + // !!! Sergey A. Sukiyazov <corwin@micom.don.ru> !!! + // A environment variables may contain values in 8bit + // locale cpecified encoding or in UTF8 encoding. + if (isUtf8( pEnv )) + path.replace( nDollarPos, nEndPos-nDollarPos, TQString::fromUtf8(pEnv) ); + else + path.replace( nDollarPos, nEndPos-nDollarPos, TQString::fromLocal8Bit(pEnv) ); + } else + path.remove( nDollarPos, nEndPos-nDollarPos ); + } else { + // remove one of the dollar signs + path.remove( nDollarPos, 1 ); + nDollarPos++; + } + nDollarPos = path.find( '$', nDollarPos ); + } + + return path; +} + +bool KDevHTMLPart::openURL(const KURL &url) +{ + TQString path = resolveEnvVarsInURL(url.url()); + KURL newUrl(path); + + bool retval = TDEHTMLPart::openURL(newUrl); + if ( retval ) + { + emit fileNameChanged(this); + if ( !m_restoring ) + { + addHistoryEntry(); + } + } + + m_backAction->setEnabled( m_Current != m_history.begin() ); + m_forwardAction->setEnabled( m_Current != m_history.fromLast() ); + + return retval; +} + +void KDevHTMLPart::openURLRequest(const KURL &url) +{ + openURL( url ); +} + +void KDevHTMLPart::slotReload( ) +{ + openURL( url() ); +} + +void KDevHTMLPart::slotStop( ) +{ + closeURL(); +} + +void KDevHTMLPart::slotStarted( TDEIO::Job * ) +{ + stopAction->setEnabled(true); +} + +void KDevHTMLPart::slotCompleted( ) +{ + stopAction->setEnabled(false); +} + +void KDevHTMLPart::slotCancelled( const TQString & /*errMsg*/ ) +{ + stopAction->setEnabled(false); +} + +/*void KDevHTMLPart::slotDuplicate( ) +{ + PartController::getInstance()->showDocument(url(), true); +}*/ + +void KDevHTMLPart::slotPrint( ) +{ + view()->print(); +} + +void KDevHTMLPart::slotBack() +{ + if ( m_Current != m_history.begin() ) + { + --m_Current; + m_restoring = true; + openURL( (*m_Current).url ); + m_restoring = false; + } +} + +void KDevHTMLPart::slotForward() +{ + if ( m_Current != m_history.fromLast() ) + { + ++m_Current; + m_restoring = true; + openURL( (*m_Current).url ); + m_restoring = false; + } +} + +void KDevHTMLPart::slotBackAboutToShow() +{ + TDEPopupMenu *popup = m_backAction->popupMenu(); + popup->clear(); + + if ( m_Current == m_history.begin() ) return; + + TQValueList<DocumentationHistoryEntry>::Iterator it = m_Current; + --it; + + int i = 0; + while( i < 10 ) + { + if ( it == m_history.begin() ) + { + popup->insertItem( (*it).url.url(), (*it).id ); + return; + } + + popup->insertItem( (*it).url.url(), (*it).id ); + ++i; + --it; + } +} + +void KDevHTMLPart::slotForwardAboutToShow() +{ + TDEPopupMenu *popup = m_forwardAction->popupMenu(); + popup->clear(); + + if ( m_Current == m_history.fromLast() ) return; + + TQValueList<DocumentationHistoryEntry>::Iterator it = m_Current; + ++it; + + int i = 0; + while( i < 10 ) + { + if ( it == m_history.fromLast() ) + { + popup->insertItem( (*it).url.url(), (*it).id ); + return; + } + + popup->insertItem( (*it).url.url(), (*it).id ); + ++i; + ++it; + } +} + +void KDevHTMLPart::slotPopupActivated( int id ) +{ + kdDebug(9000) << "id: " << id << endl; + + TQValueList<DocumentationHistoryEntry>::Iterator it = m_history.begin(); + while( it != m_history.end() ) + { + kdDebug(9000) << "(*it).id: " << (*it).id << endl; + if ( (*it).id == id ) + { + m_Current = it; + m_restoring = true; + openURL( (*m_Current).url ); + m_restoring = false; + return; + } + ++it; + } +} + +void KDevHTMLPart::addHistoryEntry() +{ + TQValueList<DocumentationHistoryEntry>::Iterator it = m_Current; + + // if We're not already the last entry, we truncate the list here before adding an entry + if ( it != m_history.end() && it != m_history.fromLast() ) + { + m_history.erase( ++it, m_history.end() ); + } + + DocumentationHistoryEntry newEntry( url() ); + + // Only save the new entry if it is different from the last + if ( newEntry.url != (*m_Current).url ) + { + m_history.append( newEntry ); + m_Current = m_history.fromLast(); + } +} + +void KDevHTMLPart::slotCopy( ) +{ + TQString text = selectedText(); + text.replace( TQChar( 0xa0 ), ' ' ); + TQClipboard *cb = TQApplication::clipboard(); + disconnect( cb, TQT_SIGNAL( selectionChanged() ), this, TQT_SLOT( slotClearSelection() ) ); + cb->setText(text); + connect( cb, TQT_SIGNAL( selectionChanged() ), this, TQT_SLOT( slotClearSelection() ) ); +} + +void KDevHTMLPart::slotSelectionChanged( ) +{ + if (selectedText().isEmpty()) + copyAction->setEnabled(false); + else + copyAction->setEnabled(true); +} + +#include "kdevhtmlpart.moc" |