diff options
Diffstat (limited to 'src/kbibtexshell.cpp')
-rw-r--r-- | src/kbibtexshell.cpp | 387 |
1 files changed, 387 insertions, 0 deletions
diff --git a/src/kbibtexshell.cpp b/src/kbibtexshell.cpp new file mode 100644 index 0000000..e3182dd --- /dev/null +++ b/src/kbibtexshell.cpp @@ -0,0 +1,387 @@ +/*************************************************************************** +* Copyright (C) 2004-2009 by Thomas Fischer * +* fischer@unix-ag.uni-kl.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. * +* * +* 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; if not, write to the * +* Free Software Foundation, Inc., * +* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * +***************************************************************************/ +#include <qprocess.h> + +#include <kkeydialog.h> +#include <kencodingfiledialog.h> +#include <kconfig.h> +#include <kurl.h> +#include <kactionclasses.h> +#include <kedittoolbar.h> +#include <kdebug.h> +#include <kaction.h> +#include <kstdaction.h> +#include <kio/netaccess.h> +#include <klibloader.h> +#include <kmessagebox.h> +#include <kstatusbar.h> +#include <klocale.h> + +#include <kbibtex_part.h> +#include "kbibtexshell.h" + +KBibTeXShell::KBibTeXShell( QWidget* parentWidget, const char* name ) + : KParts::MainWindow( parentWidget, name ), m_part( NULL ), m_parentWidget( parentWidget ) +{ + // set the shell's ui resource file + setXMLFile( "kbibtex_shell.rc" ); + + // then, setup our actions + setupActions(); + + // and a status bar + statusBar() ->show(); + + // this routine will find and load our Part. it finds the Part by + // name which is a bad idea usually.. but it's alright in this + // case since our Part is made for this Shell + KLibFactory *factory = KLibLoader::self() ->factory( "libkbibtexpart" ); + if ( factory ) + { + // now that the Part is loaded, we cast it to a Part to get + // our hands on it + m_part = static_cast<KParts::ReadWritePart *>( factory->create( this, "kbibtex_part", "KParts::ReadWritePart" ) ); + + if ( m_part ) + { + // tell the KParts::MainWindow that this is indeed the main widget + setCentralWidget( m_part->widget() ); + + // and integrate the part's GUI with the shell's + createGUI( m_part ); + } + + } + else + { + // if we couldn't find our Part, we exit since the Shell by + // itself can't do anything useful + KMessageBox::error( this, i18n( "Could not find our part!" ) ); + kapp->quit(); + // we return here, cause kapp->quit() only means "exit the + // next time we enter the event loop... + return ; + } + + // apply the saved mainwindow settings, if any, and ask the mainwindow + // to automatically save settings if changed: window size, toolbar + // position, icon size, etc. + setAutoSaveSettings(); + + readConfig(); + +#ifdef HAVE_YAZ + kdDebug() << "Using YAZ to access Z39.50 databases" << endl; +#else // HAVE_YAZ + kdDebug() << "YAZ not linked to KBibTeX. No access to Z39.50 databases possible" << endl; +#endif // HAVE_YAZ + +} + +KBibTeXShell::~KBibTeXShell() +{ + // nothing +} + +bool KBibTeXShell::openURL( const KURL& url ) +{ + if ( url.isEmpty() ) + return false; + + // About this function, the style guide ( + // http://developer.kde.org/documentation/standards/kde/style/basics/index.html ) + // says that it should open a new window if the document is _not_ + // in its initial state. This is what we do here. + + // If there is no part yet created, create new one... + + if ( m_part->url().isEmpty() && !m_part->isModified() ) + { + if ( !m_part->openURL( url ) ) + return FALSE; + } + else + { + KBibTeXShell *shell = new KBibTeXShell(); + + if ( !shell->part() ->openURL( url ) ) + return FALSE; + else + initializePart( shell->part() ); + shell->show(); + } + + m_recentFiles->addURL( url ); + return TRUE; +} + +KParts::ReadWritePart * KBibTeXShell::part() +{ + return m_part; +} + +void KBibTeXShell::readConfig( KConfig *config ) +{ + config->setGroup( "Session" ); + m_recentFiles->loadEntries( config ); + m_recentFiles->setEnabled( true ); // force enabling + m_recentFiles->setToolTip( i18n( "Click to open a file\nClick and hold to open a recent file" ) ); +} + +void KBibTeXShell::writeConfig( KConfig *config ) +{ + config->setGroup( "Session" ); + m_recentFiles->saveEntries( config ); + config->sync(); +} + +void KBibTeXShell::readConfig() +{ + KConfig * config = kapp->config(); + readConfig( config ); +} + +void KBibTeXShell::writeConfig() +{ + KConfig * config = kapp->config(); + writeConfig( config ); +} + +QString KBibTeXShell::encoding() +{ + return "utf8"; +} + +void KBibTeXShell::slotAddRecentURL( const KURL&url ) +{ + m_recentFiles->addURL( url ); +} + +void KBibTeXShell::setupActions() +{ + KAction * action; + + action = KStdAction::openNew( this, SLOT( slotFileNew() ), actionCollection() ); + action ->setToolTip( i18n( "Create a new window for a new BibTeX file" ) ); + KAction *actionOpen = KStdAction::open( this, SLOT( slotFileOpen() ), actionCollection() ); + actionOpen->setToolTip( i18n( "Open an existing BibTeX file" ) ); + + m_recentFiles = KStdAction::openRecent( this, SLOT( slotFileOpen( const KURL& ) ), actionCollection() ); + m_recentFiles->setWhatsThis( i18n( "This lists files which you have opened recently, and allows you to easily open them again." ) ); + connect( m_recentFiles, SIGNAL( activated() ), actionOpen, SLOT( activate() ) ); + + action = KStdAction::close( this, SLOT( slotFileClose() ), actionCollection() ); + action->setToolTip( i18n( "Close this KBibTeX window" ) ); + // action = KStdAction::quit( kapp, SLOT( closeAllWindows() ), actionCollection() ); + // action->setToolTip( i18n( "Close all windows and quit KBibTeX" ) ); + + m_statusbarAction = KStdAction::showStatusbar( this, SLOT( optionsShowStatusbar() ), actionCollection() ); + m_statusbarAction->setToolTip( i18n( "Show or hide the window's status bar" ) ); + + KStdAction::keyBindings( this, SLOT( optionsConfigureKeys() ), actionCollection() ) ->setToolTip( i18n( "Configure key bindings for KBibTeX" ) ); + KStdAction::configureToolbars( this, SLOT( optionsConfigureToolbars() ), actionCollection() ) ->setToolTip( i18n( "Configure the tool bar for KBibTeX" ) ); + + connect( actionCollection(), SIGNAL( actionStatusText( const QString & ) ), this, SLOT( slotActionStatusText( const QString & ) ) ); + connect( actionCollection(), SIGNAL( clearStatusText( ) ), statusBar(), SLOT( clear() ) ); +} + +void KBibTeXShell::slotActionStatusText( const QString &text ) +{ + KStatusBar * stb = statusBar(); + + if ( stb ) + stb->message( text ); +} + +void KBibTeXShell::saveProperties( KConfig* /*config*/ ) +{ + // the 'config' object points to the session managed + // config file. anything you write here will be available + // later when this app is restored +} + +void KBibTeXShell::readProperties( KConfig* /*config*/ ) +{ + // the 'config' object points to the session managed + // config file. this function is automatically called whenever + // the app is being restored. read in here whatever you wrote + // in 'saveProperties' +} + +void KBibTeXShell::optionsShowStatusbar() +{ + // this is all very cut and paste code for showing/hiding the + // statusbar + if ( m_statusbarAction->isChecked() ) + statusBar() ->show(); + else + statusBar() ->hide(); +} + +void KBibTeXShell::optionsConfigureKeys() +{ + KKeyDialog dlg( false, this ); + QPtrList<KXMLGUIClient> clients = guiFactory()->clients(); + for ( QPtrListIterator<KXMLGUIClient> it( clients ); it.current(); ++it ) + { + dlg.insert(( *it )->actionCollection() ); + } + dlg.configure(); +} + +void KBibTeXShell::optionsConfigureToolbars() +{ +#if defined(KDE_MAKE_VERSION) +# if KDE_VERSION >= KDE_MAKE_VERSION(3,1,0) + saveMainWindowSettings( KGlobal::config(), autoSaveGroup() ); +# else + saveMainWindowSettings( KGlobal::config() ); +# endif +#else + saveMainWindowSettings( KGlobal::config() ); +#endif + + // use the standard toolbar editor + KEditToolbar dlg( factory() ); + connect( &dlg, SIGNAL( newToolbarConfig() ), + this, SLOT( applyNewToolbarConfig() ) ); + dlg.exec(); +} + +void KBibTeXShell::applyNewToolbarConfig() +{ +#if defined(KDE_MAKE_VERSION) +# if KDE_VERSION >= KDE_MAKE_VERSION(3,1,0) + applyMainWindowSettings( KGlobal::config(), autoSaveGroup() ); +# else + applyMainWindowSettings( KGlobal::config() ); +# endif +#else + applyMainWindowSettings( KGlobal::config() ); +#endif +} + +bool KBibTeXShell::queryClose() +{ + if ( m_part && !m_part ->closeURL() ) + return FALSE; + + writeConfig(); + + return KParts::MainWindow::queryClose(); +} + +void KBibTeXShell::slotFileNew() +{ + // this slot is called whenever the File->New menu is selected, + // the New shortcut is pressed (usually CTRL+N) or the New toolbar + // button is clicked + + // About this function, the style guide ( + // http://developer.kde.org/documentation/standards/kde/style/basics/index.html ) + // says that it should open a new window if the document is _not_ + // in its initial state. This is what we do here.. + if ( ! m_part->url().isEmpty() || m_part->isModified() ) + { + ( new KBibTeXShell() ) ->show(); + }; +} + +/** + * Show a file open dialog where a user can select one or several + * files for opening. + */ +void KBibTeXShell::slotFileOpen() +{ + bool bibUtilsAvailable = checkExternalToolAvailable( "xml2bib" ) && checkExternalToolAvailable( "end2xml" ); + QString startDir = ! m_part->url().isEmpty() ? m_part->url().url() : QDir::currentDirPath(); + KURL mergeURL = KFileDialog::getOpenURL( startDir, QString( "*.bib *.ris" ) + + ( bibUtilsAvailable ? " *.xml *.ref *.refer *.rfr *.txt *.isi *.cgi" : "" ) + "|" + i18n( "Supported Bibliographies" ) + "\n*.bib|" + i18n( "BibTeX (*.bib)" ) + "\n*.ris|" + i18n( "Reference Manager (*.ris)" ) + ( bibUtilsAvailable ? "\n*.ref *.refer *.rfr *.txt|" + i18n( "EndNote (Refer format) (*.ref *.refer *.rfr *.txt)" ) + "\n*.isi *.cgi|" + i18n( "ISI Web of Knowledge (*.isi *.cgi)" ) + "\n*.xml|" + i18n( "MODS or EndNote XML (*.xml)" ) : "" ) + "\n*|" + i18n( "All files (*.*)" ) + , widget() ); + slotFileOpen( mergeURL ); +} + + +/** + * Open a given url in a new window. + */ +void KBibTeXShell::slotFileOpen( const KURL& url ) +{ + if ( url.isEmpty() ) return ; + + if ( !KIO::NetAccess::exists( url, TRUE, this ) ) + { + m_recentFiles->removeURL( url ); + KMessageBox::error( this, i18n( "The given file could not be read, check if it exists or if it is readable for the current user." ) ); + return ; + } + + if ( m_part->url().isEmpty() && !m_part->isModified() ) + // we open the file in this window... + openURL( url ); + else + { + // we open the file in a new window... + KBibTeXShell * shell = new KBibTeXShell(); + if ( shell->openURL( url ) ) + { + initializePart( shell->part() ); + shell->show(); + } + else + { + KMessageBox::error( this, i18n( "Could not open file '%1'." ).arg( url.path() ) ); + } + } + +} + +/** + * Close currrent window + */ +void KBibTeXShell::slotFileClose() +{ + close(); +} + +void KBibTeXShell::initializePart( KParts::ReadWritePart* part ) +{ + if ( part ) + { + connect( static_cast<KBibTeXPart*>( part ), SIGNAL( signalAddRecentURL( const KURL & ) ), this, SLOT( slotAddRecentURL( const KURL& ) ) ); + } +} + +bool KBibTeXShell::checkExternalToolAvailable( const QString &binary ) +{ + QProcess *process = new QProcess( binary ); + bool ok = process->start(); + ok &= process->normalExit(); + if ( process->isRunning() ) + { + process->kill(); + ok = true; + } + delete process; + return ok; +} + + +#include "kbibtexshell.moc" |