diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-02-10 03:05:17 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-02-10 03:05:17 +0000 |
commit | 2c945cd914550233ed352ff195afeb4dd793f122 (patch) | |
tree | 4796bfab5733942b90b5a66bb05655be5fdcca03 /src/kile/texdocdialog.cpp | |
download | kile-2c945cd914550233ed352ff195afeb4dd793f122.tar.gz kile-2c945cd914550233ed352ff195afeb4dd793f122.zip |
Added abandoned KDE3 version of Kile
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/kile@1088055 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'src/kile/texdocdialog.cpp')
-rw-r--r-- | src/kile/texdocdialog.cpp | 660 |
1 files changed, 660 insertions, 0 deletions
diff --git a/src/kile/texdocdialog.cpp b/src/kile/texdocdialog.cpp new file mode 100644 index 0000000..6b88a29 --- /dev/null +++ b/src/kile/texdocdialog.cpp @@ -0,0 +1,660 @@ +/*************************************************************************** + texdocdialog.cpp + ---------------- + date : Feb 15 2007 + version : 0.14 + copyright : (C) 2005-2007 by Holger Danielsson + email : holger.danielsson@versanet.de + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#include "texdocdialog.h" + +#include <qlayout.h> +#include <qstringlist.h> +#include <qfile.h> +#include <qfileinfo.h> +#include <qtextstream.h> +#include <qgroupbox.h> +#include <qregexp.h> +#include <qwhatsthis.h> +#include <kapplication.h> +#include <qdesktopwidget.h> + +#include <kurl.h> +#include <krun.h> +#include <kmimetype.h> +#include <kiconloader.h> +#include <kmessagebox.h> +#include <klocale.h> +#include "kiledebug.h" +#include <kdeversion.h> + +#include <ktrader.h> +#include <kservice.h> + + +namespace KileDialog +{ + +//BEGIN TexDocDialog + +TexDocDialog::TexDocDialog(QWidget *parent, const char *name) + : KDialogBase( parent,name, true, i18n("Documentation Browser"), Close | Help, +#if KDE_VERSION >= KDE_MAKE_VERSION(3,3,0) + NoDefault +#else + Close +#endif + , true ), + m_tempfile(0), m_proc(0) +{ + QWidget *page = new QWidget( this ); + setMainWidget(page); + + QVBoxLayout *vbox = new QVBoxLayout(page,8,8); + + // listview + m_texdocs = new KListView(page); + m_texdocs->setRootIsDecorated(true); + m_texdocs->addColumn(i18n("Table of Contents")); + + // groupbox + QGroupBox *groupbox = new QGroupBox( i18n("Search"), page, "groupbox" ); + groupbox->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)5, (QSizePolicy::SizeType)1, 0, 0, groupbox->sizePolicy().hasHeightForWidth() ) ); + groupbox->setColumnLayout(0, Qt::Vertical ); + groupbox->layout()->setSpacing( 6 ); + groupbox->layout()->setMargin( 11 ); + QGridLayout *groupboxLayout = new QGridLayout( groupbox->layout() ); + groupboxLayout->setAlignment( Qt::AlignTop ); + + QLabel *label = new QLabel( i18n("&Keyword:"), groupbox, "label"); + m_leKeywords = new KLineEdit("",groupbox); + m_pbSearch = new KPushButton(i18n("&Search"),groupbox); + label->setBuddy(m_leKeywords); + + groupboxLayout->addWidget(label,0,0); + groupboxLayout->addWidget(m_leKeywords,0,1); + groupboxLayout->addWidget(m_pbSearch,1,0); + + vbox->addWidget(m_texdocs); + vbox->addWidget(groupbox); + + QWhatsThis::add(m_texdocs,i18n("A list of avaiblable documents, which are listed in 'texdoctk.dat', coming with TexLive/teTeX. A double click with the mouse or pressing the space key will open a viewer to show this file.")); + QWhatsThis::add(m_leKeywords,i18n("You can choose a keyword to show only document files, which are related to this keyword.")); + QWhatsThis::add(m_pbSearch,i18n("Start the search for the chosen keyword.")); + QWhatsThis::add(actionButton(Help),i18n("Reset TOC to show all available files.")); + + setButtonText(Help,i18n("Reset &TOC")); + m_pbSearch->setEnabled(false); + enableButton(Help,false); + + // catch some Return/Enter events + m_texdocs->installEventFilter(this); + m_leKeywords->installEventFilter(this); + + connect(m_texdocs, SIGNAL(doubleClicked(QListViewItem *,const QPoint &,int)), + this, SLOT(slotListViewDoubleClicked(QListViewItem *,const QPoint &,int))); + connect(m_pbSearch, SIGNAL(clicked()), this, SLOT(slotSearchClicked())); + connect(m_leKeywords, SIGNAL(textChanged(const QString &)), this, SLOT(slotTextChanged(const QString &))); + + // kpsewhich --expand-path='$TEXMF' + //m_texmfPath = "/usr/local/share/texmf:/usr/local/lib/texmf:/var/lib/texmf:/usr/share/texmf"; + // kpsewhich --expand-path='$TEXMF/doc' + //m_texmfdocPath = "/usr/local/share/texmf/doc:/usr/local/lib/texmf/doc:/usr/share/texmf/doc"; + // kpsewhich --progname=texdoctk --format='other text files' texdoctk.dat + //m_texdoctkPath = "/usr/share/texmf/texdoctk/texdoctk.dat"; + + m_texmfPath = QString::null; + m_texmfdocPath = QString::null; + m_texdoctkPath = QString::null; + + QDesktopWidget *desktop = KApplication::desktop(); + int w = desktop->screenGeometry(0).width(); + if ( w >= 1024 ) + w = 550; + else if ( w >= 800 ) + w = 500; + else + w = 450; + int h = desktop->screenGeometry(0).height() ; + if ( h >= 768 ) + h = 550; + else if ( h >= 600 ) + h = 500; + else + h = 450; + resize(w,h); + + connect(this, SIGNAL(processFinished()), this, SLOT(slotInitToc())); + executeScript( + "kpsewhich --progname=texdoctk --format='other text files' texdoctk.dat && " + "kpsewhich --expand-path='$TEXMF/doc' && " + "kpsewhich --expand-path='$TEXMF'" + ); + + //readToc(); + //slotHelp(); +} + +TexDocDialog::~TexDocDialog() +{ + if (m_proc ) + delete m_proc; + if ( m_tempfile ) + delete m_tempfile; +} + +////////////////////// TOC ////////////////////// + +void TexDocDialog::readToc() +{ + // open to read + QFile fin( m_texdoctkPath ); + if ( !fin.exists() || !fin.open(IO_ReadOnly) ) + { + KMessageBox::error(this,i18n("Could not read 'texdoctk.dat'.")); + return; + } + + // use a textstream to read all data + QString textline; + QTextStream data(&fin); + while ( ! data.eof() ) + { + textline = data.readLine(); + if ( ! (textline.isEmpty() || textline[0]=='#') ) + { + // save the whole entry + m_tocList.append( textline ); + + // list entries 0,1,basename(2),3 are needed for keyword search + // (key,title,filepath,keywords) + QStringList list = QStringList::split(';',textline,true); + + // get basename of help file + QString basename; + if ( list.count() > 2 ) + { + QFileInfo fi(list[2]); + basename = fi.baseName().lower(); + } + + QString entry = list[0] + ';' + list[1]; + if ( ! basename.isEmpty() ) + entry += ';' + basename; + if ( list.count() > 3 ) + entry += ';' + list[3]; + m_tocSearchList.append(entry); + } + } +} + +void TexDocDialog::showToc(const QString &caption,const QStringList &doclist, bool toc) +{ + QString section,textline; + QStringList keylist; + KListViewItem *itemsection = 0L; + + setUpdatesEnabled( false ); + m_texdocs->setColumnText(0,caption); + + for (uint i=0; i<doclist.count(); i++ ) + { + if ( doclist[i][0] == '@' ) + { + section = doclist[i]; + itemsection = new KListViewItem(m_texdocs,section.remove(0,1)); + } + else + { + keylist = QStringList::split(';',doclist[i],true); + if ( itemsection ) + { + KListViewItem *item = new KListViewItem(itemsection,keylist[1],keylist[0]); + item->setPixmap(0, SmallIcon(getIconName(keylist[2])) ); + + // save filename in dictionary + m_dictDocuments[keylist[0]] = keylist[2]; + + // search for special keywords + QRegExp reg( "^\\s*(-\\d-)" ); + if ( keylist[3].find(reg,0) == 0 ) + { + m_dictStyleCodes[keylist[0]] = reg.cap(1); + } + } + } + } + setUpdatesEnabled( true ); + + if ( toc ) + m_pbSearch->setEnabled(false); + enableButton(Help,!toc); + m_texdocs->setFocus(); +} + +bool TexDocDialog::eventFilter(QObject *o, QEvent *e) +{ + // catch KeyPress events + if ( e->type() == QEvent::KeyPress ) + { + QKeyEvent *kev = (QKeyEvent*) e; + + // ListView: + // - space: enable start of viewer + // - return: ignore + if ( o == m_texdocs ) + { + if ( kev->key() == Qt::Key_Space ) + { + slotListViewDoubleClicked(m_texdocs->currentItem(), QPoint(0,0), 0) ; + return true; + } + if ( kev->key()==Qt::Key_Return || kev->key()==Qt::Key_Enter ) + return true; + } + + // LineEdit + // - return: start search, if button is enabled + if ( o == m_leKeywords ) + { + if ( kev->key()==Qt::Key_Return || kev->key()==Qt::Key_Enter ) + { + callSearch(); + return true; + } + } + } + + return false; +} + +////////////////////// prepare document file ////////////////////// + +QString TexDocDialog::searchFile(const QString &docfilename,const QString &listofpathes, const QString &subdir) +{ + QStringList pathlist = QStringList::split(':',listofpathes); + QStringList extlist = QStringList::split(',',",.gz,.bz2",true); + + QString filename; + for ( QStringList::Iterator itp = pathlist.begin(); itp!=pathlist.end(); ++itp ) + { + for ( QStringList::Iterator ite = extlist.begin(); ite!=extlist.end(); ++ite ) + { + filename = ( subdir.isEmpty() ) ? (*itp) + '/' + docfilename + (*ite) + : (*itp) + '/' + subdir + '/' + docfilename + (*ite); + // KILE_DEBUG() << "search file: " << filename << endl; + if ( QFile::exists(filename) ) + return filename; + } + } + + return QString::null; +} + +void TexDocDialog::decompressFile(const QString &docfile,const QString &command) +{ + QString ext = QFileInfo(docfile).extension(false).lower(); + if ( ! ( ext=="dvi" || ext=="pdf" || ext=="ps" || ext=="html") ) + ext = "txt"; + + if ( m_tempfile ) + delete m_tempfile; + + m_tempfile = new KTempFile(QString::null, '.' + ext); + m_tempfile->setAutoDelete(true); + m_filename = m_tempfile->name(); + + KILE_DEBUG() << "\tdecompress file: " << command + " > " + m_tempfile->name() << endl; + connect(this, SIGNAL(processFinished()), this, SLOT(slotShowFile())); + executeScript(command + " > " + m_tempfile->name()); +} + +void TexDocDialog::showStyleFile(const QString &filename,const QString &stylecode) +{ + KILE_DEBUG() << "\tshow style file: "<< filename << endl; + if ( ! QFile::exists(filename) ) + return; + + // open to read + QFile fin( filename ); + if ( !fin.exists() || !fin.open(IO_ReadOnly) ) + { + KMessageBox::error(this,i18n("Could not read the style file.")); + return; + } + + if ( m_tempfile ) + delete m_tempfile; + m_tempfile = new KTempFile(QString::null,".txt"); + m_tempfile->setAutoDelete(true); + + // use a textstream to write to the temporary file + QFile tmpfile(m_tempfile->name()); + if ( ! tmpfile.open( IO_WriteOnly ) ) + { + KMessageBox::error(this,i18n("Could not create a temporary file.")); + return ; + } + QTextStream stream(&tmpfile); + + // use another textstream to read from the style file + QTextStream sty( &fin ); + + // there are four mode to read from the style file + QString textline; + if ( stylecode == "-3-" ) + { + // mode 3: read everything up to the first empty line + while ( ! sty.eof() ) { + textline = sty.readLine().stripWhiteSpace(); + if ( textline.isEmpty() ) + break; + stream << textline << "\n"; + } + } + else if ( stylecode == "-2-" ) + { + // mode 2: read everything up to a line starting with at least 4 '%' characters + for ( int i=0; i<9; ++i ) + stream << sty.readLine() << "\n"; + while ( ! sty.eof() ) + { + textline = sty.readLine(); + if ( textline.find("%%%%") == 0 ) + break; + stream << textline << "\n"; + } + } + else if ( stylecode == "-1-" ) + { + // mode 1: read all lines at the end behind \endinput + while ( ! sty.eof() ) + { + textline = sty.readLine().stripWhiteSpace(); + if ( textline.find("\\endinput") == 0 ) + break; + } + while ( ! sty.eof() ) + { + stream << sty.readLine() << "\n"; + } + } + else + { + // mode 0: read everything except empty lines and comments + while ( ! sty.eof() ) + { + textline = sty.readLine(); + if ( !textline.isEmpty() && textline[0]!='%' ) + stream << textline << "\n"; + } + } + tmpfile.close(); + + // start the viewer + showFile(m_tempfile->name()); +} + +void TexDocDialog::showFile(const QString &filename) +{ + KILE_DEBUG() << "\tshow file: "<< filename << endl; + if ( QFile::exists(filename) ) + { + KURL url; + url.setPath(filename); + + KTrader::OfferList offers = KTrader::self()->query( getMimeType(filename),"Type == 'Application'"); + if ( offers.isEmpty() ) + { + KMessageBox::error(this,i18n("No KDE service found for this file.")); + return; + } + KService::Ptr ptr = offers.first(); + KURL::List lst; + lst.append(url); + KRun::run(*ptr, lst, true); + } +} + + +////////////////////// Slots ////////////////////// + +void TexDocDialog::slotListViewDoubleClicked(QListViewItem *item,const QPoint &,int) +{ + if ( ! item->parent() ) + return; + + QString package = item->text(1); + KILE_DEBUG() << "\tselect child: " << item->text(0) << endl + << "\tis package: " << package << endl; + if ( ! m_dictDocuments.contains( package ) ) + return; + + QString texdocfile = m_dictDocuments[package]; + KILE_DEBUG() << "\tis texdocfile: " << texdocfile << endl; + + // search for the file in the documentation directories + QString filename = searchFile(texdocfile,m_texmfdocPath); + if ( filename.isEmpty() ) + { + // not found: search it elsewhere + filename = searchFile(texdocfile,m_texmfPath,"tex"); + if ( filename.isEmpty() ) + { + KMessageBox::error(this,i18n("Could not find '%1'").arg(filename)); + return; + } + } + KILE_DEBUG() << "\tfound file: " << filename << endl; + + QString ext = QFileInfo(filename).extension(false).lower(); + m_filename = QString::null; + if ( ext == "gz" ) + decompressFile(m_dictDocuments[package],"gzip -cd "+filename); + else if ( ext == "bz2" ) + decompressFile(m_dictDocuments[package],"bzip2 -cd "+filename); + else if ( ext=="sty" && m_dictStyleCodes.contains(package) ) + showStyleFile(filename,m_dictStyleCodes[package]); + else + showFile(filename); +} + +void TexDocDialog::slotTextChanged(const QString &text) +{ + m_pbSearch->setEnabled( ! text.stripWhiteSpace().isEmpty() ); +} + +void TexDocDialog::slotSearchClicked() +{ + QString keyword = m_leKeywords->text().stripWhiteSpace(); + if ( keyword.isEmpty() ) + { + KMessageBox::error(this,i18n("No keyword given.")); + return; + } + + QString section; + bool writesection = true; + QStringList searchlist; + + for (uint i=0; i<m_tocList.count(); i++ ) + { + if ( m_tocList[i][0] == '@' ) + { + section = m_tocList[i]; + writesection = true; + } + else if ( m_tocSearchList[i].find(keyword,0,false) > -1 ) + { + if ( writesection ) + searchlist.append(section); + searchlist.append(m_tocList[i]); + writesection = false; + } + } + + if ( searchlist.count() > 0 ) + { + m_texdocs->clear(); + showToc(i18n("Search results for keyword '%1'").arg(keyword),searchlist,false); + } + else + KMessageBox::error(this,i18n("No documents found for keyword '%1'.").arg(keyword)); +} + +void TexDocDialog::slotHelp() +{ + m_leKeywords->setText(QString::null); + m_texdocs->clear(); + showToc(i18n("Table of Contents"),m_tocList,true); +} + +void TexDocDialog::callSearch() +{ + if ( m_pbSearch->isEnabled() ) + slotSearchClicked(); +} + +////////////////////// execute shell script ////////////////////// + +void TexDocDialog::executeScript(const QString &command) +{ + if ( m_proc ) + delete m_proc; + + m_proc = new KShellProcess("/bin/sh"); + m_proc->clearArguments(); + (*m_proc) << QStringList::split(' ',command); + m_output = QString::null; + + connect(m_proc, SIGNAL(receivedStdout(KProcess*,char*,int)), + this, SLOT(slotProcessOutput(KProcess*,char*,int)) ); + connect(m_proc, SIGNAL(receivedStderr(KProcess*,char*,int)), + this, SLOT(slotProcessOutput(KProcess*,char*,int)) ); + connect(m_proc, SIGNAL(processExited(KProcess*)), + this, SLOT(slotProcessExited(KProcess*)) ); + + KILE_DEBUG() << "=== TexDocDialog::runShellSkript() ====================" << endl; + KILE_DEBUG() << " execute: " << command << endl; + if ( ! m_proc->start(KProcess::NotifyOnExit, KProcess::AllOutput) ) + KILE_DEBUG() << "\tstart of shell process failed" << endl; +} + +void TexDocDialog::slotProcessOutput(KProcess*,char* buf,int len) +{ + m_output += QString::fromLocal8Bit(buf,len); +} + + +void TexDocDialog::slotProcessExited(KProcess *proc) +{ + if ( proc->normalExit() && !proc->exitStatus() ) + { + //showFile(m_filename); + emit( processFinished() ); + } + else + { + KMessageBox::error( this,i18n("<center>") + i18n("Could not determine the search paths of TexLive/teTeX or file 'texdoctk.dat'.<br> So this dialog is useless.") + i18n("</center>"),i18n("TexDoc Dialog") ); + } +} + +////////////////////// process slots, when finished ////////////////////// + +void TexDocDialog::slotInitToc() +{ + disconnect(this, SIGNAL(processFinished()), this, SLOT(slotInitToc())); + + QStringList results = QStringList::split('\n',m_output,true); + if ( results.count() < 3 ) + { + KMessageBox::error(this,i18n("Could not determine the search paths of TexLive/teTeX or file 'texdoctk.dat'.<br> So this dialog is useless.")); + return; + } + + m_texdoctkPath = results[0]; + m_texmfdocPath = results[1]; + m_texmfPath = results[2]; + + KILE_DEBUG() << "\ttexdoctk path: " << m_texdoctkPath << endl; + KILE_DEBUG() << "\ttexmfdoc path: " << m_texmfdocPath << endl; + KILE_DEBUG() << "\ttexmf path: " << m_texmfPath << endl; + + if ( m_texdoctkPath.find('\n',-1) > -1 ) + { + m_texdoctkPath.truncate(m_texdoctkPath.length()-1); + } + + // read data and initialize listview + readToc(); + slotHelp(); +} + +void TexDocDialog::slotShowFile() +{ + disconnect(this, SIGNAL(processFinished()), this, SLOT(slotShowFile())); + showFile(m_filename); +} + +////////////////////// Icon/Mime ////////////////////// + +QString TexDocDialog::getMimeType(const QString &filename) +{ + QFileInfo fi(filename); + QString basename = fi.baseName().lower(); + QString ext = fi.extension(false).lower(); + + QString mimetype; + if ( ext=="txt" || ext=="faq" || ext=="sty" || basename=="readme" || basename=="00readme" ) + { + mimetype = "text/plain"; + } + else + { + KURL mimeurl; + mimeurl.setPath(filename); + KMimeType::Ptr pMime = KMimeType::findByURL(mimeurl); + mimetype = pMime->name(); + } + + KILE_DEBUG() << "\tmime = " << mimetype << " " << endl; + return mimetype; +} + +QString TexDocDialog::getIconName(const QString &filename) +{ + QFileInfo fi( filename ); + QString basename = fi.baseName().lower(); + QString ext = fi.extension(false).lower(); + + QString icon; + if ( ext=="dvi" || ext=="pdf" || ext=="html" || ext == "htm" || ext == "txt") + icon = ext; + else if ( ext == "ps" ) + icon = "postscript"; + else if ( ext == "sty" ) + icon = "tex"; + else if ( ext == "faq" || basename=="readme" || basename=="00readme" ) + icon = "readme"; + else + icon = "ascii"; + + return icon; +} + + +//END TexDocDialog + + +} +#include "texdocdialog.moc" |