KDevelop API Documentation

src/documentationpart.cpp

Go to the documentation of this file.
00001 #include <stdlib.h> 00002 #include <qfile.h> 00003 00004 #include <kaction.h> 00005 #include <klocale.h> 00006 #include <kpopupmenu.h> 00007 #include <kiconloader.h> 00008 #include <kmainwindow.h> 00009 00010 #include "kdevmainwindow.h" 00011 #include "partcontroller.h" 00012 #include "toplevel.h" 00013 00014 00015 #include "documentationpart.h" 00016 00017 00018 DocumentationPart::DocumentationPart() 00019 : KHTMLPart(0L, 0L, 0L, "DocumentationPart", BrowserViewGUI ) 00020 { 00021 connect(browserExtension(), SIGNAL(openURLRequestDelayed(const KURL &,const KParts::URLArgs &)), 00022 this, SLOT(openURLRequest(const KURL &)) ); 00023 00024 connect(this, SIGNAL(started(KIO::Job *)), this, SLOT(slotStarted(KIO::Job* ))); 00025 connect(this, SIGNAL(completed()), this, SLOT(slotCompleted())); 00026 connect(this, SIGNAL(canceled(const QString &)), this, SLOT(slotCancelled(const QString &))); 00027 00028 KActionCollection * actions = new KActionCollection( this ); 00029 reloadAction = new KAction( i18n( "Reload" ), "reload", 0, 00030 this, SLOT( slotReload() ), actions, "doc_reload" ); 00031 reloadAction->setWhatsThis(i18n("<b>Reload</b><p>Reloads the current document.")); 00032 stopAction = new KAction( i18n( "Stop" ), "stop", 0, 00033 this, SLOT( slotStop() ), actions, "doc_stop" ); 00034 stopAction->setWhatsThis(i18n("<b>Stop</b><p>Stops the loading of current document.")); 00035 duplicateAction = new KAction( i18n( "Duplicate Window" ), "window_new", 0, 00036 this, SLOT( slotDuplicate() ), actions, "doc_dup" ); 00037 duplicateAction->setWhatsThis(i18n("<b>Duplicate window</b><p>Opens current document in a new window.")); 00038 00039 connect( this, SIGNAL(popupMenu(const QString &, const QPoint &)), this, SLOT(popup(const QString &, const QPoint &))); 00040 } 00041 00042 void DocumentationPart::popup( const QString & url, const QPoint & p ) 00043 { 00044 KPopupMenu *m_popup = new KPopupMenu( i18n( "Documentation Viewer" ), this->widget() ); 00045 00046 // Install the global back and forward actions, if they are available 00047 KActionCollection *actions = TopLevel::getInstance()->main()->actionCollection(); 00048 KAction *backAction = actions->action("browser_back"); 00049 KAction *forwardAction = actions->action("browser_forward"); 00050 if(backAction && forwardAction) 00051 { 00052 backAction->plug(m_popup); 00053 forwardAction->plug(m_popup); 00054 m_popup->insertSeparator(); 00055 } 00056 00057 KAction * incFontAction = this->action("incFontSizes"); 00058 KAction * decFontAction = this->action("decFontSizes"); 00059 if ( incFontAction && decFontAction ) 00060 { 00061 incFontAction->plug( m_popup ); 00062 decFontAction->plug( m_popup ); 00063 m_popup->insertSeparator(); 00064 } 00065 00066 duplicateAction->plug(m_popup); 00067 int idNewWindow = -2; 00068 if (!url.isEmpty()) 00069 { 00070 idNewWindow = m_popup->insertItem(SmallIcon("window_new"),i18n("Open in New Window")); 00071 m_popup->setWhatsThis(idNewWindow, i18n("<b>Open in new window</b><p>Opens current link in a new window.")); 00072 } 00073 m_popup->insertSeparator(); 00074 reloadAction->plug(m_popup); 00075 stopAction->plug(m_popup); 00076 m_popup->insertSeparator(); 00077 00078 /* if (!url.isEmpty()) 00079 { 00080 KAction *ac = action("savelinkas"); 00081 if (ac) 00082 { 00083 qWarning("savelinkas found"); 00084 ac->plug(m_popup); 00085 } 00086 KAction *ac2 = action("copylinklocation"); 00087 if (ac2) 00088 ac2->plug(m_popup); 00089 m_popup->insertSeparator(); 00090 }*/ 00091 00092 KAction *ac = action("setEncoding"); 00093 if (ac) 00094 ac->plug(m_popup); 00095 00096 int r = m_popup->exec(p); 00097 00098 if (r == idNewWindow) 00099 { 00100 KURL kurl (DocumentationPart::url().upURL()); 00101 kurl.addPath(url); 00102 if (kurl.isValid()) 00103 PartController::getInstance()->showDocument(kurl, url); 00104 } 00105 } 00106 00107 void DocumentationPart::setContext(const QString &context) 00108 { 00109 m_context = context; 00110 } 00111 00112 00113 QString DocumentationPart::context() const 00114 { 00115 return m_context; 00116 } 00117 00118 00119 // Note: this function is a copy of code in kdecore/kconfigbase.cpp ;) 00120 static bool isUtf8(const char *buf) { 00121 int i, n; 00122 register unsigned char c; 00123 bool gotone = false; 00124 00125 #define F 0 /* character never appears in text */ 00126 #define T 1 /* character appears in plain ASCII text */ 00127 #define I 2 /* character appears in ISO-8859 text */ 00128 #define X 3 /* character appears in non-ISO extended ASCII (Mac, IBM PC) */ 00129 00130 static const unsigned char text_chars[256] = { 00131 /* BEL BS HT LF FF CR */ 00132 F, F, F, F, F, F, F, T, T, T, T, F, T, T, F, F, /* 0x0X */ 00133 /* ESC */ 00134 F, F, F, F, F, F, F, F, F, F, F, T, F, F, F, F, /* 0x1X */ 00135 T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, /* 0x2X */ 00136 T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, /* 0x3X */ 00137 T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, /* 0x4X */ 00138 T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, /* 0x5X */ 00139 T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, /* 0x6X */ 00140 T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, F, /* 0x7X */ 00141 /* NEL */ 00142 X, X, X, X, X, T, X, X, X, X, X, X, X, X, X, X, /* 0x8X */ 00143 X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, /* 0x9X */ 00144 I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, /* 0xaX */ 00145 I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, /* 0xbX */ 00146 I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, /* 0xcX */ 00147 I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, /* 0xdX */ 00148 I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, /* 0xeX */ 00149 I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I /* 0xfX */ 00150 }; 00151 00152 /* *ulen = 0; */ 00153 for (i = 0; (c = buf[i]); i++) { 00154 if ((c & 0x80) == 0) { /* 0xxxxxxx is plain ASCII */ 00155 /* 00156 * Even if the whole file is valid UTF-8 sequences, 00157 * still reject it if it uses weird control characters. 00158 */ 00159 00160 if (text_chars[c] != T) 00161 return false; 00162 00163 } else if ((c & 0x40) == 0) { /* 10xxxxxx never 1st byte */ 00164 return false; 00165 } else { /* 11xxxxxx begins UTF-8 */ 00166 int following; 00167 00168 if ((c & 0x20) == 0) { /* 110xxxxx */ 00169 following = 1; 00170 } else if ((c & 0x10) == 0) { /* 1110xxxx */ 00171 following = 2; 00172 } else if ((c & 0x08) == 0) { /* 11110xxx */ 00173 following = 3; 00174 } else if ((c & 0x04) == 0) { /* 111110xx */ 00175 following = 4; 00176 } else if ((c & 0x02) == 0) { /* 1111110x */ 00177 following = 5; 00178 } else 00179 return false; 00180 00181 for (n = 0; n < following; n++) { 00182 i++; 00183 if (!(c = buf[i])) 00184 goto done; 00185 00186 if ((c & 0x80) == 0 || (c & 0x40)) 00187 return false; 00188 } 00189 gotone = true; 00190 } 00191 } 00192 done: 00193 return gotone; /* don't claim it's UTF-8 if it's all 7-bit */ 00194 } 00195 #undef F 00196 #undef T 00197 #undef I 00198 #undef X 00199 00200 QString DocumentationPart::resolveEnvVarsInURL(const QString& url) 00201 { 00202 // check for environment variables and make necessary translations 00203 QString path = url; 00204 int nDollarPos = path.find( '$' ); 00205 00206 // Note: the while loop below is a copy of code in kdecore/kconfigbase.cpp ;) 00207 while( nDollarPos != -1 && nDollarPos+1 < static_cast<int>(path.length())) { 00208 // there is at least one $ 00209 if( (path)[nDollarPos+1] == '(' ) { 00210 uint nEndPos = nDollarPos+1; 00211 // the next character is no $ 00212 while ( (nEndPos <= path.length()) && (path[nEndPos]!=')') ) 00213 nEndPos++; 00214 nEndPos++; 00215 QString cmd = path.mid( nDollarPos+2, nEndPos-nDollarPos-3 ); 00216 00217 QString result; 00218 FILE *fs = popen(QFile::encodeName(cmd).data(), "r"); 00219 if (fs) 00220 { 00221 QTextStream ts(fs, IO_ReadOnly); 00222 result = ts.read().stripWhiteSpace(); 00223 pclose(fs); 00224 } 00225 path.replace( nDollarPos, nEndPos-nDollarPos, result ); 00226 } else if( (path)[nDollarPos+1] != '$' ) { 00227 uint nEndPos = nDollarPos+1; 00228 // the next character is no $ 00229 QString aVarName; 00230 if (path[nEndPos]=='{') 00231 { 00232 while ( (nEndPos <= path.length()) && (path[nEndPos]!='}') ) 00233 nEndPos++; 00234 nEndPos++; 00235 aVarName = path.mid( nDollarPos+2, nEndPos-nDollarPos-3 ); 00236 } 00237 else 00238 { 00239 while ( nEndPos <= path.length() && (path[nEndPos].isNumber() 00240 || path[nEndPos].isLetter() || path[nEndPos]=='_' ) ) 00241 nEndPos++; 00242 aVarName = path.mid( nDollarPos+1, nEndPos-nDollarPos-1 ); 00243 } 00244 const char* pEnv = 0; 00245 if (!aVarName.isEmpty()) 00246 pEnv = getenv( aVarName.ascii() ); 00247 if( pEnv ) { 00248 // !!! Sergey A. Sukiyazov <corwin@micom.don.ru> !!! 00249 // A environment variables may contain values in 8bit 00250 // locale cpecified encoding or in UTF8 encoding. 00251 if (isUtf8( pEnv )) 00252 path.replace( nDollarPos, nEndPos-nDollarPos, QString::fromUtf8(pEnv) ); 00253 else 00254 path.replace( nDollarPos, nEndPos-nDollarPos, QString::fromLocal8Bit(pEnv) ); 00255 } else 00256 path.remove( nDollarPos, nEndPos-nDollarPos ); 00257 } else { 00258 // remove one of the dollar signs 00259 path.remove( nDollarPos, 1 ); 00260 nDollarPos++; 00261 } 00262 nDollarPos = path.find( '$', nDollarPos ); 00263 } 00264 00265 return path; 00266 } 00267 00268 bool DocumentationPart::openURL(const KURL &url) 00269 { 00270 QString path = resolveEnvVarsInURL(url.url()); 00271 KURL newUrl(path); 00272 00273 bool retval = KHTMLPart::openURL(newUrl); 00274 if ( retval ) 00275 emit fileNameChanged(); 00276 00277 return retval; 00278 } 00279 00280 void DocumentationPart::openURLRequest(const KURL &url) 00281 { 00282 PartController::getInstance()->showDocument(url, context()); 00283 } 00284 00285 void DocumentationPart::slotReload( ) 00286 { 00287 PartController::getInstance()->showDocument(url(), m_context); 00288 } 00289 00290 void DocumentationPart::slotStop( ) 00291 { 00292 closeURL(); 00293 } 00294 00295 void DocumentationPart::slotStarted( KIO::Job * ) 00296 { 00297 stopAction->setEnabled(true); 00298 } 00299 00300 void DocumentationPart::slotCompleted( ) 00301 { 00302 stopAction->setEnabled(false); 00303 } 00304 00305 void DocumentationPart::slotCancelled( const QString & /*errMsg*/ ) 00306 { 00307 stopAction->setEnabled(false); 00308 } 00309 00310 void DocumentationPart::slotDuplicate( ) 00311 { 00312 PartController::getInstance()->showDocument(url(), m_context + "dup"); 00313 } 00314 00315 #include "documentationpart.moc"
KDE Logo
This file is part of the documentation for KDevelop Version 3.0.4.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Oct 6 17:39:13 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003