diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-03-01 19:17:32 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-03-01 19:17:32 +0000 |
commit | e38d2351b83fa65c66ccde443777647ef5cb6cff (patch) | |
tree | 1897fc20e9f73a81c520a5b9f76f8ed042124883 /src/cite | |
download | tellico-e38d2351b83fa65c66ccde443777647ef5cb6cff.tar.gz tellico-e38d2351b83fa65c66ccde443777647ef5cb6cff.zip |
Added KDE3 version of Tellico
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/tellico@1097620 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'src/cite')
-rw-r--r-- | src/cite/Makefile.am | 20 | ||||
-rw-r--r-- | src/cite/actionmanager.cpp | 85 | ||||
-rw-r--r-- | src/cite/actionmanager.h | 64 | ||||
-rw-r--r-- | src/cite/clipboard.cpp | 51 | ||||
-rw-r--r-- | src/cite/clipboard.h | 36 | ||||
-rw-r--r-- | src/cite/handler.h | 61 | ||||
-rw-r--r-- | src/cite/lyxpipe.cpp | 92 | ||||
-rw-r--r-- | src/cite/lyxpipe.h | 36 | ||||
-rw-r--r-- | src/cite/ooo/Makefile.am | 88 | ||||
-rw-r--r-- | src/cite/ooo/interface.cpp | 430 | ||||
-rw-r--r-- | src/cite/ooo/interface.h | 62 | ||||
-rw-r--r-- | src/cite/ooo/ooohandler.cpp | 159 | ||||
-rw-r--r-- | src/cite/ooo/ooohandler.h | 54 | ||||
-rw-r--r-- | src/cite/openoffice.cpp | 267 | ||||
-rw-r--r-- | src/cite/openoffice.h | 47 |
15 files changed, 1552 insertions, 0 deletions
diff --git a/src/cite/Makefile.am b/src/cite/Makefile.am new file mode 100644 index 0000000..74e7c81 --- /dev/null +++ b/src/cite/Makefile.am @@ -0,0 +1,20 @@ +AM_CPPFLAGS = $(all_includes) +METASOURCES = AUTO +KDE_OPTIONS = noautodist +CLEANFILES = *~ *.loT +noinst_LIBRARIES = libcite.a +libcite_a_SOURCES = lyxpipe.cpp actionmanager.cpp clipboard.cpp openoffice.cpp + +EXTRA_DIST = \ +actionmanager.h actionmanager.cpp \ +lyxpipe.h lyxpipe.cpp \ +actionmanager.h actionmanager.cpp \ +openoffice.h openoffice.cpp \ +clipboard.h clipboard.cpp \ +handler.h + +OOO_SUBDIR = ooo + +if WITH_OOO +SUBDIRS = $(OOO_SUBDIR) +endif diff --git a/src/cite/actionmanager.cpp b/src/cite/actionmanager.cpp new file mode 100644 index 0000000..905f81a --- /dev/null +++ b/src/cite/actionmanager.cpp @@ -0,0 +1,85 @@ +/*************************************************************************** + copyright : (C) 2005-2006 by Robby Stephenson + email : [email protected] + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of version 2 of the GNU General Public License as * + * published by the Free Software Foundation; * + * * + ***************************************************************************/ + +#include "actionmanager.h" +#include "lyxpipe.h" +#include "clipboard.h" +#include "openoffice.h" +#include "../entry.h" +#include "../tellico_debug.h" + +using Tellico::Cite::ActionManager; + +ActionManager::ActionManager* ActionManager::self() { + static ActionManager self; + return &self; +} + +ActionManager::ActionManager() : m_action(0) { +} + +ActionManager::~ActionManager() { + delete m_action; +} + +bool ActionManager::connect(CiteAction action_) { + if(m_action && m_action->type() == action_) { + return m_action->connect(); + } else if(m_action) { + delete m_action; + m_action = 0; + } + + switch(action_) { + case Cite::CiteClipboard: + m_action = new Clipboard(); + break; + + case Cite::CiteLyxpipe: + m_action = new Lyxpipe(); + break; + + case Cite::CiteOpenOffice: + m_action = new OpenOffice(); + break; + } + return m_action ? m_action->connect() : false; +} + +bool ActionManager::cite(CiteAction action_, Data::EntryVec entries_) { + if(entries_.isEmpty()) { + myDebug() << "ActionManager::cite() - no entries to cite" << endl; + return false; + } + if(m_action && m_action->type() != action_) { + delete m_action; + m_action = 0; + } + if(!m_action && !connect(action_)) { + myDebug() << "ActionManager::cite() - unable to connect" << endl; + return false; + } + if(!m_action) { + myDebug() << "ActionManager::cite() - no action found" << endl; + return false; + } + + return m_action->cite(entries_); +} + +bool ActionManager::isEnabled(CiteAction action_) { + if(action_ == CiteOpenOffice) { + return OpenOffice::hasLibrary(); + } + return true; +} diff --git a/src/cite/actionmanager.h b/src/cite/actionmanager.h new file mode 100644 index 0000000..fd6ffd1 --- /dev/null +++ b/src/cite/actionmanager.h @@ -0,0 +1,64 @@ +/*************************************************************************** + copyright : (C) 2005-2006 by Robby Stephenson + email : [email protected] + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of version 2 of the GNU General Public License as * + * published by the Free Software Foundation; * + * * + ***************************************************************************/ + +#ifndef TELLICO_CITE_ACTIONMANAGER_H +#define TELLICO_CITE_ACTIONMANAGER_H + +#include "../datavectors.h" +#include "handler.h" + +namespace Tellico { + namespace Cite { + +enum CiteAction { + CiteClipboard, + CiteLyxpipe, + CiteOpenOffice +}; + +/** + * @author Robby Stephenson + */ +class Action { +public: + Action() {} + virtual ~Action() {} + + virtual CiteAction type() const = 0; + virtual bool connect() { return true; } + virtual bool cite(Data::EntryVec entries) = 0; + virtual State state() const { return Success; } +}; + +/** + * @author Robby Stephenson + */ +class ActionManager { +public: + static ActionManager* self(); + ~ActionManager(); + + bool cite(CiteAction action, Data::EntryVec entries); + static bool isEnabled(CiteAction action); + +private: + ActionManager(); + bool connect(CiteAction action); + + Action* m_action; +}; + + } +} + +#endif diff --git a/src/cite/clipboard.cpp b/src/cite/clipboard.cpp new file mode 100644 index 0000000..9b98b89 --- /dev/null +++ b/src/cite/clipboard.cpp @@ -0,0 +1,51 @@ +/*************************************************************************** + copyright : (C) 2005-2006 by Robby Stephenson + email : [email protected] + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of version 2 of the GNU General Public License as * + * published by the Free Software Foundation; * + * * + ***************************************************************************/ + +#include "clipboard.h" +#include "../collection.h" +#include "../translators/bibtexhandler.h" + +#include <klocale.h> + +#include <qapplication.h> +#include <qclipboard.h> + +using Tellico::Cite::Clipboard; + +Clipboard::Clipboard() : Action() { +} + +bool Clipboard::cite(Data::EntryVec entries_) { + if(entries_.isEmpty()) { + return false; + } + + Data::CollPtr coll = entries_.front()->collection(); + if(!coll || coll->type() != Data::Collection::Bibtex) { + return false; + } + + QString s = QString::fromLatin1("\\cite{"); + for(Data::EntryVecIt it = entries_.begin(); it != entries_.end(); ++it) { + s += BibtexHandler::bibtexKey(it.data()); + if(!it.nextEnd()) { + s += QString::fromLatin1(", "); + } + } + s += '}'; + + QClipboard *cb = QApplication::clipboard(); + cb->setText(s, QClipboard::Clipboard); + return true; +} + diff --git a/src/cite/clipboard.h b/src/cite/clipboard.h new file mode 100644 index 0000000..153f02f --- /dev/null +++ b/src/cite/clipboard.h @@ -0,0 +1,36 @@ +/*************************************************************************** + copyright : (C) 2005-2006 by Robby Stephenson + email : [email protected] + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of version 2 of the GNU General Public License as * + * published by the Free Software Foundation; * + * * + ***************************************************************************/ + +#ifndef TELLICO_CITE_CLIPBOARD_H +#define TELLICO_CITE_CLIPBOARD_H + +#include "actionmanager.h" + +namespace Tellico { + namespace Cite { + +/** + * @author Robby Stephenson +*/ +class Clipboard : public Action { +public: + Clipboard(); + + virtual CiteAction type() const { return CiteClipboard; } + virtual bool cite(Data::EntryVec entries); +}; + + } +} + +#endif diff --git a/src/cite/handler.h b/src/cite/handler.h new file mode 100644 index 0000000..d03a3e7 --- /dev/null +++ b/src/cite/handler.h @@ -0,0 +1,61 @@ +/*************************************************************************** + copyright : (C) 2005-2006 by Robby Stephenson + email : [email protected] + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of version 2 of the GNU General Public License as * + * published by the Free Software Foundation; * + * * + ***************************************************************************/ + +#ifndef TELLICO_CITE_HANDLER_H +#define TELLICO_CITE_HANDLER_H + +#include <map> +#include <string> + +namespace Tellico { + namespace Cite { + +enum State { + NoConnection, + NoDocument, + NoCitation, + Success +}; + +typedef std::map<std::string, std::string> Map; + +/** + * @author Robby Stephenson + */ +class Handler { +public: + Handler() {} + virtual ~Handler() {} + + virtual bool connect() = 0; + virtual bool cite(Map& s) = 0; + virtual State state() const = 0; + + // really specific to ooo + void setHost(const char* host) { m_host = host; } + const std::string& host() const { return m_host; } + void setPort(int port) { m_port = port; } + int port() const { return m_port; } + void setPipe(const char* pipe) { m_pipe = pipe; } + const std::string& pipe() const { return m_pipe; } + +private: + std::string m_host; + int m_port; + std::string m_pipe; +}; + + } +} + +#endif diff --git a/src/cite/lyxpipe.cpp b/src/cite/lyxpipe.cpp new file mode 100644 index 0000000..6075324 --- /dev/null +++ b/src/cite/lyxpipe.cpp @@ -0,0 +1,92 @@ +/*************************************************************************** + copyright : (C) 2005-2006 by Robby Stephenson + email : [email protected] + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of version 2 of the GNU General Public License as * + * published by the Free Software Foundation; * + * * + ***************************************************************************/ + +#include "lyxpipe.h" +#include "../collection.h" +#include "../translators/bibtexhandler.h" +#include "../tellico_kernel.h" +#include "../core/tellico_config.h" +#include "../tellico_debug.h" + +#include <klocale.h> + +#include <qfile.h> + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> + +using Tellico::Cite::Lyxpipe; + +Lyxpipe::Lyxpipe() : Action() { +} + +bool Lyxpipe::cite(Data::EntryVec entries_) { + if(entries_.isEmpty()) { + return false; + } + + Data::CollPtr coll = entries_.front()->collection(); + if(!coll || coll->type() != Data::Collection::Bibtex) { + myDebug() << "Lyxpipe::cite() - collection must be a bibliography!" << endl; + return false; + } + + QString lyxpipe = Config::lyxpipe(); + lyxpipe += QString::fromLatin1(".in"); +// myDebug() << "Lyxpipe::cite() - " << lyxpipe << endl; + + QString errorStr = i18n("<qt>Tellico is unable to write to the server pipe at <b>%1</b>.</qt>").arg(lyxpipe); + + QFile file(lyxpipe); + if(!file.exists()) { + Kernel::self()->sorry(errorStr); + return false; + } + + int pipeFd = ::open(QFile::encodeName(lyxpipe), O_WRONLY); + if(!file.open(IO_WriteOnly, pipeFd)) { + Kernel::self()->sorry(errorStr); + ::close(pipeFd); + return false; + } + + QString output; + QTextStream ts(&file); + for(Data::EntryVecIt it = entries_.begin(); it != entries_.end(); ++it) { + QString s = BibtexHandler::bibtexKey(it.data()); + if(s.isEmpty()) { + continue; + } + output += s; + if(!it.nextEnd() && !output.isEmpty()) { + // pybliographer uses comma-space, and pyblink expects the space there + output += QString::fromLatin1(", "); + } + } + if(output.isEmpty()) { + myDebug() << "Lyxpipe::cite() - no available bibtex keys!" << endl; + return false; + } + +// ts << "LYXSRV:tellico:hello\n"; + ts << "LYXCMD:tellico:citation-insert:"; + ts << output.local8Bit(); + ts << "\n"; +// ts << "LYXSRV:tellico:bye\n"; + file.flush(); + file.close(); + ::close(pipeFd); + return true; +} diff --git a/src/cite/lyxpipe.h b/src/cite/lyxpipe.h new file mode 100644 index 0000000..da738ae --- /dev/null +++ b/src/cite/lyxpipe.h @@ -0,0 +1,36 @@ +/*************************************************************************** + copyright : (C) 2005-2006 by Robby Stephenson + email : $EMAIL + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of version 2 of the GNU General Public License as * + * published by the Free Software Foundation; * + * * + ***************************************************************************/ + +#ifndef TELLICO_CITE_LYXPIPE_H +#define TELLICO_CITE_LYXPIPE_H + +#include "actionmanager.h" + +namespace Tellico { + namespace Cite { + +/** + * @author Robby Stephenson + */ +class Lyxpipe : public Action { +public: + Lyxpipe(); + + virtual CiteAction type() const { return CiteClipboard; } + virtual bool cite(Data::EntryVec entries); +}; + + } // end namespace +} // end namespace + +#endif diff --git a/src/cite/ooo/Makefile.am b/src/cite/ooo/Makefile.am new file mode 100644 index 0000000..ff11fca --- /dev/null +++ b/src/cite/ooo/Makefile.am @@ -0,0 +1,88 @@ +METASOURCES = AUTO + +KDE_CXXFLAGS = $(USE_EXCEPTIONS) +KDE_OPTIONS = noautodist + +COMID=gcc3 +CPPULIB=-luno_cppu +CPPUHELPERLIB=-luno_cppuhelper$(COMID) +SALLIB=-luno_sal +SALHELPERLIB=-luno_salhelper$(COMID) +# REGLIB=-lreg + +# Where the UNO includes will be generated +INCDIR = $(srcdir)/.include +UNODIR = $(INCDIR)/uno + +# OpenOffice.org additional includes and libraries +# might have to be adjusted for other architectures +OFFICE_includes = -I$(INCDIR) -I$(UNODIR) -DUNX -DGCC -DLINUX -DCPPU_ENV=$(COMID) -DOSL_DEBUG_LEVEL=0 +OFFICE_libraries = $(CPPULIB) $(CPPUHELPERLIB) $(SALLIB) $(SALHELPERLIB) + +AM_CPPFLAGS = $(all_includes) $(OFFICE_SDK_includes) $(OFFICE_includes) + +kde_module_LTLIBRARIES = tellico_ooo.la + +tellico_ooo_la_SOURCES = ooohandler.cpp interface.cpp +tellico_ooo_la_LDFLAGS = -module $(KDE_PLUGIN) $(KDE_RPATH) \ + $(all_libraries) $(OFFICE_libraries) +tellico_ooo_la_LIBADD = $(OFFICE_libadd) + +EXTRA_DIST = ooohandler.h ooohandler.cpp \ + interface.h interface.cpp + +CLEANFILES = *~ *.loT + +# Clean target for the generated stuff +clean-local: + rm -rf $(UNODIR) $(INCDIR) $(CLEANFILES) + +UNOTYPES := \ + com.sun.star.uno.XComponentContext \ + com.sun.star.lang.XMultiServiceFactory \ + com.sun.star.lang.XSingleComponentFactory \ + com.sun.star.lang.XComponent \ + com.sun.star.lang.XServiceInfo \ + com.sun.star.bridge.XUnoUrlResolver \ + com.sun.star.frame.XDesktop \ + com.sun.star.frame.XComponentLoader \ + com.sun.star.text.ControlCharacter \ + com.sun.star.text.XDocumentIndexesSupplier \ + com.sun.star.text.XDocumentIndex \ + com.sun.star.text.XTextDocument \ + com.sun.star.text.XTextField \ + com.sun.star.text.XTextViewCursor \ + com.sun.star.text.XTextViewCursorSupplier \ + com.sun.star.text.BibliographyDataType \ + com.sun.star.container.XIndexAccess \ + com.sun.star.container.XHierarchicalNameAccess \ + com.sun.star.registry.XSimpleRegistry \ + com.sun.star.beans.XPropertySet \ + com.sun.star.sdbc.XRow \ + com.sun.star.sdbc.XRowSet \ + com.sun.star.sdbc.XResultSetMetaDataSupplier \ + com.sun.star.sdbc.XResultSetUpdate \ + com.sun.star.sdbc.XRowUpdate \ + com.sun.star.sdbc.SQLException \ + com.sun.star.sdb.CommandType \ + com.sun.star.document.XEventListener \ + com.sun.star.document.XEventBroadcaster \ + com.sun.star.uno.XWeak \ + com.sun.star.uno.XAggregation \ + com.sun.star.lang.XTypeProvider + + +UNOHPPFILES = $(foreach t,$(UNOTYPES),$(UNODIR)/$(subst .,/,$(t)).hpp) + +interface.o: $(UNOHPPFILES) $(INCDIR) + +$(INCDIR): + mkdir -p $(INCDIR) + +$(UNODIR): + mkdir -p $(UNODIR) + +$(UNOHPPFILES): $(UNODIR) + $(CPPUMAKER) -Gc -BUCR -O$(UNODIR) $(foreach t,$(UNOTYPES),-T$(t)) \ + $(OFFICE_registry) + diff --git a/src/cite/ooo/interface.cpp b/src/cite/ooo/interface.cpp new file mode 100644 index 0000000..383ed1e --- /dev/null +++ b/src/cite/ooo/interface.cpp @@ -0,0 +1,430 @@ +/*************************************************************************** + copyright : (C) 2005-2006 by Robby Stephenson + email : [email protected] + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of version 2 of the GNU General Public License as * + * published by the Free Software Foundation; * + * * + ***************************************************************************/ + +#include "interface.h" + +#include <cppuhelper/bootstrap.hxx> +#include <cppuhelper/implbase1.hxx> +#include <com/sun/star/bridge/XUnoUrlResolver.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/frame/XComponentLoader.hpp> +#include <com/sun/star/frame/XDesktop.hpp> +#include <com/sun/star/container/XIndexAccess.hpp> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/text/ControlCharacter.hpp> +#include <com/sun/star/text/XDocumentIndexesSupplier.hpp> +#include <com/sun/star/text/XDocumentIndex.hpp> +#include <com/sun/star/text/XTextField.hpp> +#include <com/sun/star/text/XTextViewCursorSupplier.hpp> +#include <com/sun/star/text/BibliographyDataType.hpp> +#include <com/sun/star/sdbc/XRowSet.hpp> +#include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp> +#include <com/sun/star/sdbc/XResultSetUpdate.hpp> +#include <com/sun/star/sdbc/XRow.hpp> +#include <com/sun/star/sdbc/XRowUpdate.hpp> +#include <com/sun/star/sdbc/SQLException.hpp> +#include <com/sun/star/sdb/CommandType.hpp> +#include <com/sun/star/document/XEventListener.hpp> +#include <com/sun/star/document/XEventBroadcaster.hpp> + +#include <iostream> + +#define DEBUG(s) std::cout << s << std::endl +#define OUSTR(s) ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(s)) +#define OU2O(s) OUStringToOString(s, RTL_TEXTENCODING_ASCII_US) +#define O2OU(s) OStringToOUString(s.c_str(), RTL_TEXTENCODING_UTF8) + +using Tellico::Cite::OOOHandler; + +using namespace com::sun::star; +using namespace com::sun::star::uno; +using namespace rtl; +using namespace cppu; + +namespace Tellico { + namespace Cite { + typedef cppu::WeakImplHelper1<document::XEventListener> EventListenerHelper; + } +} + +class OOOHandler::Interface::EventListener : public cppu::WeakImplHelper1<document::XEventListener> { +public: + EventListener(OOOHandler::Interface* i) : EventListenerHelper(), m_interface(i) {} + virtual void SAL_CALL disposing(const lang::EventObject&) throw(RuntimeException) { + DEBUG("Document is being disposed"); + m_interface->disconnect(); + } + virtual void SAL_CALL notifyEvent(const document::EventObject&) throw(RuntimeException) { +// std::cout << "Event: " << rtl::OUStringToOString(aEvent.EventName,RTL_TEXTENCODING_ISO_8859_1).getStr() << std::endl; + } +private: + OOOHandler::Interface* m_interface; +}; + +OOOHandler::Interface::Interface() : m_listener(0) { +} + +OOOHandler::Interface::~Interface() { + delete m_listener; + m_listener = 0; +} + +bool OOOHandler::Interface::isConnected() const { + return m_gsmgr.is(); +} + +bool OOOHandler::Interface::connect(const std::string& host_, int port_, const std::string& pipe_) { + if(isConnected()) { + return true; + } + + // create the initial component context + Reference<uno::XComponentContext> context; + try { + context = defaultBootstrap_InitialComponentContext(); + } catch(Exception& e) { + OString o = OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US); + std::cout << "Unable to get initial component context: " << o << std::endl; + return false; + } catch(...) { + DEBUG("Unable to get initial component context."); + return false; + } + + // retrieve the servicemanager from the context + Reference<lang::XMultiComponentFactory> rServiceManager; + try { + rServiceManager = context->getServiceManager(); + } catch(...) { + DEBUG("Unable to get initial service manager."); + return false; + } + + // instantiate a sample service with the servicemanager. + OUString s = OUString::createFromAscii("com.sun.star.bridge.UnoUrlResolver"); + Reference<uno::XInterface> rInstance; + try { + rInstance = rServiceManager->createInstanceWithContext(s, context); + } catch(...) { + DEBUG("Unable to get initial instance."); + return false; + } + + // Query for the XUnoUrlResolver interface + Reference<bridge::XUnoUrlResolver> rResolver(rInstance, UNO_QUERY); + if(!rResolver.is()) { + DEBUG("Error: Couldn't instantiate com.sun.star.bridge.UnoUrlResolver service"); + return false; + } + + // "uno:socket,host=%s,port=%s;urp;StarOffice.ComponentContext"%(host,port) + // "uno:pipe,name=%s;urp;StarOffice.ComponentContext"%pipe + if(pipe_.empty()) { + s = OUSTR("socket,host=") + O2OU(host_) + OUSTR(",port=") + OUString::valueOf((sal_Int32)port_); + } else { + s = OUSTR("pipe,name=") + O2OU(pipe_); + } + std::cout << "Connection string: " << OU2O(s) << std::endl; + s = OUSTR("uno:") + s + OUSTR(";urp;StarOffice.ServiceManager"); + + try { + rInstance = rResolver->resolve(s); + if(!rInstance.is()) { + DEBUG("StarOffice.ServiceManager is not exported from remote counterpart"); + return false; + } + + m_gsmgr = Reference<lang::XMultiServiceFactory>(rInstance, UNO_QUERY); + if(m_gsmgr.is()) { + DEBUG("Connected successfully to office"); + } else { + DEBUG("XMultiServiceFactory interface is not exported"); + } + } catch(Exception& e) { + std::cout << "Error: " << OU2O(e.Message) << std::endl; + } catch(...) { + DEBUG("Unable to resolve connection."); + return false; + } + return m_gsmgr.is(); +} + +bool OOOHandler::Interface::disconnect() { + m_gsmgr = 0; + m_dsmgr = 0; + m_doc = 0; + m_bib = 0; + m_cursor = 0; + return true; +} + +bool OOOHandler::Interface::createDocument() { + if(!m_gsmgr.is()) { + return false; + } + + if(m_doc.is()) { + return true; + } + + // get the desktop service using createInstance, returns an XInterface type + Reference<uno::XInterface> xInstance = m_gsmgr->createInstance(OUString::createFromAscii("com.sun.star.frame.Desktop")); + Reference<frame::XDesktop> desktop(xInstance, UNO_QUERY); + + Reference<lang::XComponent> writer = desktop->getCurrentComponent(); + Reference<lang::XServiceInfo> info(writer, UNO_QUERY); + if(info.is() && info->getImplementationName() == OUString::createFromAscii("SwXTextDocument")) { + DEBUG("Document already open"); + } else { + DEBUG("Opening a new document"); + //query for the XComponentLoader interface + Reference<frame::XComponentLoader> rComponentLoader(desktop, UNO_QUERY); + if(!rComponentLoader.is()){ + DEBUG("XComponentloader failed to instantiate"); + return 0; + } + + //get an instance of the OOowriter document + writer = rComponentLoader->loadComponentFromURL(OUSTR("private:factory/swriter"), + OUSTR("_default"), + 0, + Sequence<beans::PropertyValue>()); + } + + //Manage many events with EventListener + Reference<document::XEventBroadcaster> eventBroadcast(writer, UNO_QUERY); + m_listener = new EventListener(this); + Reference<document::XEventListener> xEventListener = static_cast<document::XEventListener*>(m_listener); + eventBroadcast->addEventListener(xEventListener); + + Reference<frame::XController> controller = Reference<frame::XModel>(writer, UNO_QUERY)->getCurrentController(); + m_cursor = Reference<text::XTextViewCursorSupplier>(controller, UNO_QUERY)->getViewCursor(); + m_doc = Reference<text::XTextDocument>(writer, UNO_QUERY); + if(m_doc.is()) { + m_dsmgr = Reference<lang::XMultiServiceFactory>(m_doc, UNO_QUERY); + } + return m_doc.is(); +} + +bool OOOHandler::Interface::updateBibliography() { + if(!m_bib.is()) { + createBibliography(); + if(!m_bib.is()) { + DEBUG("ERROR: could not create or find bibliography index"); + return false; + } + } + + m_bib->update(); + return true; +} + +void OOOHandler::Interface::createBibliography() { + Reference<container::XIndexAccess> indexes(Reference<text::XDocumentIndexesSupplier>(m_doc, UNO_QUERY)->getDocumentIndexes(), UNO_QUERY); + for(int i = 0; i < indexes->getCount(); ++i) { + Reference<lang::XServiceInfo> info(indexes->getByIndex(i), UNO_QUERY); + if(info->supportsService(OUSTR("com.sun.star.text.Bibliography"))) { + DEBUG("Found existing bibliography..."); + m_bib = Reference<text::XDocumentIndex>(indexes->getByIndex(i), UNO_QUERY); + break; + } + } + + if(!m_bib.is()) { + DEBUG("Creating new bibliography..."); + Reference<text::XText> text = m_doc->getText(); + Reference<text::XTextRange> textRange(text->createTextCursor(), UNO_QUERY); + Reference<text::XTextCursor> cursor(textRange, UNO_QUERY); + cursor->gotoEnd(false); + text->insertControlCharacter(textRange, text::ControlCharacter::PARAGRAPH_BREAK, false); + m_bib = Reference<text::XDocumentIndex>(m_dsmgr->createInstance(OUSTR("com.sun.star.text.Bibliography")), UNO_QUERY); + Reference<text::XTextContent> textContent(m_bib, UNO_QUERY); + text->insertTextContent(textRange, textContent, false); + } +} + +bool OOOHandler::Interface::insertCitations(Cite::Map& fields) { + Reference<text::XTextField> entry(m_dsmgr->createInstance(OUString::createFromAscii("com.sun.star.text.TextField.Bibliography")), UNO_QUERY); + if(!entry.is()) { + DEBUG("Interface::insertCitation - can't create TextField"); + return false; + } + Sequence<beans::PropertyValue> values(fields.size()); + int i = 0; + for(Cite::Map::iterator it = fields.begin(); it != fields.end(); ++it, ++i) { + values[i] = propValue(it->first, it->second); + std::cout << "Setting " << OU2O(values[i].Name) << " = " << it->second << std::endl; + } + Reference<beans::XPropertySet>(entry, UNO_QUERY)->setPropertyValue(OUSTR("Fields"), Any(values)); + + Reference<text::XText> text = m_doc->getText(); + Reference<text::XTextCursor> cursor = text->createTextCursorByRange(Reference<text::XTextRange>(m_cursor, UNO_QUERY)); + Reference<text::XTextRange> textRange(cursor, UNO_QUERY); + Reference<text::XTextContent> textContent(entry, UNO_QUERY); + text->insertTextContent(textRange, textContent, false); + return true; +} + +beans::PropertyValue OOOHandler::Interface::propValue(const std::string& field, const std::string& value) { + return beans::PropertyValue(O2OU(field), 0, fieldValue(field, value), beans::PropertyState_DIRECT_VALUE); +} + +uno::Any OOOHandler::Interface::fieldValue(const std::string& field, const std::string& value) { + if(field == "BibiliographicType" || field == "BibliographicType") { // in case the typo gets fixed + return typeValue(value); + } + return Any(O2OU(value)); +} + +uno::Any OOOHandler::Interface::typeValue(const std::string& value) { + if(value == "article") { + return Any(text::BibliographyDataType::ARTICLE); + } else if(value == "book") { + return Any(text::BibliographyDataType::BOOK); + } else if(value == "booklet") { + return Any(text::BibliographyDataType::BOOKLET); + } else if(value == "conference") { + return Any(text::BibliographyDataType::CONFERENCE); + } else if(value == "inbook") { + return Any(text::BibliographyDataType::INBOOK); + } else if(value == "incollection") { + return Any(text::BibliographyDataType::INCOLLECTION); + } else if(value == "inproceedings") { + return Any(text::BibliographyDataType::INPROCEEDINGS); + } else if(value == "journal") { + return Any(text::BibliographyDataType::JOURNAL); + } else if(value == "manual") { + return Any(text::BibliographyDataType::MANUAL); + } else if(value == "mastersthesis") { + return Any(text::BibliographyDataType::MASTERSTHESIS); + } else if(value == "misc") { + return Any(text::BibliographyDataType::MISC); + } else if(value == "phdthesis") { + return Any(text::BibliographyDataType::PHDTHESIS); + } else if(value == "proceedings") { + return Any(text::BibliographyDataType::PROCEEDINGS); + } else if(value == "techreport") { + return Any(text::BibliographyDataType::TECHREPORT); + } else if(value == "unpublished") { + return Any(text::BibliographyDataType::UNPUBLISHED); + } else { + // periodical ? + return Any(text::BibliographyDataType::BOOK); + } +} + +bool OOOHandler::Interface::insertRecords(Cite::Map& fields) { + Reference<uno::XInterface> interface; + try { + interface = m_gsmgr->createInstance(OUString::createFromAscii("com.sun.star.sdb.RowSet")); + } catch(Exception& e) { + std::cout << "Error: " << OU2O(e.Message) << std::endl; + } + if(!interface.is()) { + DEBUG("Could not create rowset interface"); + return false; + } + + Reference<sdbc::XRowSet> rowSet(interface, UNO_QUERY); + if(!rowSet.is()) { + DEBUG("Could not create rowset interface"); + return false; + } + + Reference<beans::XPropertySet> props(rowSet, UNO_QUERY); + props->setPropertyValue(OUSTR("DataSourceName"), Any(OUSTR("Bibliography"))); + props->setPropertyValue(OUSTR("CommandType"), Any(sdb::CommandType::COMMAND)); + OUString s = OUSTR("SELECT COUNT(*) FROM \"biblio\" WHERE identifier='") + O2OU(fields["Identifier"]) + OUSTR("'"); + props->setPropertyValue(OUSTR("Command"), Any(s)); + + try { + rowSet->execute(); + } catch(sdbc::SQLException& e) { + DEBUG(OU2O(s)); + DEBUG(OUSTR("SQL error - ") + e.SQLState); + return false; + } catch(Exception& e) { + DEBUG(OU2O(s)); + DEBUG(OUSTR("General error - ") + e.Message); + return false; + } + + Reference<sdbc::XRow> row(rowSet, UNO_QUERY); + int count = 0; + if(rowSet->next()) { + count = row->getString(1).toInt32(); + } + + if(count > 0) { + DEBUG("Found existing bibliographic entries, updating..."); + } else { + DEBUG("Inserting new bibliographic entry..."); + } + + s = OUSTR("SELECT * FROM \"biblio\""); + if(count > 0) { + s += OUSTR(" WHERE identifier='") + O2OU(fields["Identifier"]) + OUSTR("'"); + } + props->setPropertyValue(OUSTR("Command"), Any(s)); + + try { + rowSet->execute(); + } catch(sdbc::SQLException& e) { + DEBUG(OU2O(s)); + DEBUG(OUSTR("SQL error(2) - ") + e.SQLState); + return false; + } catch(Exception& e) { + DEBUG(OU2O(s)); + DEBUG(OUSTR("General error(2) - ") + e.Message); + return false; + } + + Reference<sdbc::XResultSet> resultSet(rowSet, UNO_QUERY); + Reference<sdbc::XResultSetMetaDataSupplier> mdSupplier(resultSet, UNO_QUERY); + Reference<sdbc::XResultSetMetaData> metaData = mdSupplier->getMetaData(); + + Reference<sdbc::XRowUpdate> rowUpdate(rowSet, UNO_QUERY); + Reference<sdbc::XResultSetUpdate> update(rowSet, UNO_QUERY); + if(count > 0) { + resultSet->last(); + } else { + update->moveToInsertRow(); + } + + const long colCount = metaData->getColumnCount(); + // column numbers start with 1 + for(long i = 1; i <= colCount; ++i) { + std::string s = OU2O(metaData->getColumnName(i)).getStr(); + std::string value = fields[s]; + if(!value.empty()) { + std::cout << "column " << i << ": " << OU2O(metaData->getColumnName(i)) << "..." << std::endl; + std::cout << s << " = " << value << std::endl; + try { + rowUpdate->updateString(i, O2OU(value)); + } catch(sdbc::SQLException& e) { + DEBUG(OUSTR("SQL error(3) - ") + e.SQLState); + } catch(Exception& e) { + DEBUG(OUSTR("General error(3) - ") + e.Message); + } + } + } + if(count > 0) { + update->updateRow(); + } else { + update->insertRow(); + } + + Reference<lang::XComponent>(rowSet, UNO_QUERY)->dispose(); + return true; +} diff --git a/src/cite/ooo/interface.h b/src/cite/ooo/interface.h new file mode 100644 index 0000000..c1a0f33 --- /dev/null +++ b/src/cite/ooo/interface.h @@ -0,0 +1,62 @@ +/*************************************************************************** + copyright : (C) 2005-2006 by Robby Stephenson + email : [email protected] + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of version 2 of the GNU General Public License as * + * published by the Free Software Foundation; * + * * + ***************************************************************************/ + +#ifndef TELLICO_CITE_OOOHANDLER_INTERFACE_H +#define TELLICO_CITE_OOOHANDLER_INTERFACE_H + +#include "ooohandler.h" + +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/text/XTextDocument.hpp> +#include <com/sun/star/text/XDocumentIndex.hpp> +#include <com/sun/star/text/XTextViewCursor.hpp> + +namespace Tellico { + namespace Cite { + +class OOOHandler::Interface { + friend class OOOHandler; + + Interface(); + ~Interface(); + + bool isConnected() const; + bool connect(const std::string& host, int port, const std::string& pipe); + bool disconnect(); + bool createDocument(); + bool updateBibliography(); + bool insertCitations(Cite::Map& fields); + bool insertRecords(Cite::Map& fields); + +private: + void createBibliography(); + com::sun::star::beans::PropertyValue propValue(const std::string& field, const std::string& value); + com::sun::star::uno::Any fieldValue(const std::string& field, const std::string& value); + com::sun::star::uno::Any typeValue(const std::string& value); + + // global service manager + com::sun::star::uno::Reference<com::sun::star::lang::XMultiServiceFactory> m_gsmgr; + // document service manager + com::sun::star::uno::Reference<com::sun::star::lang::XMultiServiceFactory> m_dsmgr; + com::sun::star::uno::Reference<com::sun::star::text::XTextDocument> m_doc; + com::sun::star::uno::Reference<com::sun::star::text::XDocumentIndex> m_bib; + com::sun::star::uno::Reference<com::sun::star::text::XTextViewCursor> m_cursor; + + class EventListener; + EventListener* m_listener; +}; + + } // end namespace +} // end namespace + +#endif diff --git a/src/cite/ooo/ooohandler.cpp b/src/cite/ooo/ooohandler.cpp new file mode 100644 index 0000000..1741896 --- /dev/null +++ b/src/cite/ooo/ooohandler.cpp @@ -0,0 +1,159 @@ +/*************************************************************************** + copyright : (C) 2005-2006 by Robby Stephenson + email : [email protected] + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of version 2 of the GNU General Public License as * + * published by the Free Software Foundation; * + * * + ***************************************************************************/ + +#include "ooohandler.h" +#include "interface.h" + +#include <iostream> + +extern "C" { + Tellico::Cite::Handler* handler() { + return new Tellico::Cite::OOOHandler(); + } +} + +using Tellico::Cite::OOOHandler; +Tellico::Cite::Map OOOHandler::s_fieldsMap; + +/* +QString OOOHandler::OUString2Q(const rtl::OUString& str) { + const uint len = str.getLength(); + QChar* uni = new QChar[len + 1]; + + const sal_Unicode* ouPtr = str.getStr(); + const sal_Unicode* ouEnd = ouPtr + len; + QChar* qPtr = uni; + + while (ouPtr != ouEnd) { + *(qPtr++) = *(ouPtr++); + } + + *qPtr = 0; + + QString ret(uni, len); + delete[] uni; + + return ret; +} + +rtl::OUString OOOHandler::QString2OU(const QString& str) { + const uint len = str.length(); + sal_Unicode* uni = new sal_Unicode[len + 1]; + + const QChar* qPtr = str.unicode(); + const QChar* qEnd = qPtr + len; + sal_Unicode* uPtr = uni; + + while (qPtr != qEnd) { + *(uPtr++) = (*(qPtr++)).unicode(); + } + + *uPtr = 0; + + rtl::OUString ret(uni, len); + delete[] uni; + + return ret; +} +*/ + +void OOOHandler::buildFieldsMap() { +// s_fieldsMap["entry-type"] = "BibliographicType"; + s_fieldsMap["entry-type"] = "BibiliographicType"; // typo in OpenOffice + s_fieldsMap["key"] = "Identifier"; + s_fieldsMap["title"] = "Title"; + s_fieldsMap["author"] = "Author"; + s_fieldsMap["booktitle"] = "Booktitle"; + s_fieldsMap["address"] = "Address"; + s_fieldsMap["chapter"] = "Chapter"; + s_fieldsMap["edition"] = "Edition"; + s_fieldsMap["editor"] = "Editor"; + s_fieldsMap["organization"] = "Organizations"; // OOO has an 's' + s_fieldsMap["publisher"] = "Publisher"; + s_fieldsMap["pages"] = "Pages"; + s_fieldsMap["howpublished"] = "Howpublished"; + s_fieldsMap["institution"] = "Institution"; + s_fieldsMap["journal"] = "Journal"; + s_fieldsMap["month"] = "Month"; + s_fieldsMap["number"] = "Number"; + s_fieldsMap["note"] = "Note"; + s_fieldsMap["annote"] = "Annote"; + s_fieldsMap["series"] = "Series"; + s_fieldsMap["volume"] = "Volume"; + s_fieldsMap["year"] = "Year"; + s_fieldsMap["url"] = "URL"; + s_fieldsMap["isbn"] = "ISBN"; +} + +OOOHandler::OOOHandler() : Handler(), m_interface(0), m_state(NoConnection) { +} + +Tellico::Cite::State OOOHandler::state() const { + // possibly the write got closed underneath us + if(m_state != NoConnection && m_interface && !m_interface->isConnected()) { + m_state = NoConnection; + } + return m_state; +} + +bool OOOHandler::connect() { + if(!m_interface) { + m_interface = new Interface(); + } + + if(!m_interface->connect(host(), port(), pipe())) { + return false; + } + + if(!m_interface->createDocument()) { + m_state = NoDocument; + return false; + } + + m_state = NoCitation; + return true; +} + +bool OOOHandler::cite(Map& fields) { + if(!m_interface && !connect()) { + return false; + } + Cite::Map newFields = convertFields(fields); + // the ooo interface can insert records in the database, but the citations in the + // document ARE NOT linked to them, meaning they aren't updated by changing the database + // the user has to manually edit each entry + bool success = m_interface->insertCitations(newFields) && m_interface->updateBibliography(); +// bool success = m_interface->insertRecords(newFields); + if(success) { + m_state = Success; +// m_interface->disconnect(); +// m_state = NoConnection; + } + return success; +} + +Tellico::Cite::Map OOOHandler::convertFields(Cite::Map& fields) { + if(s_fieldsMap.empty()) { + buildFieldsMap(); + } + + Cite::Map values; + for(Cite::Map::iterator it = s_fieldsMap.begin(); it != s_fieldsMap.end(); ++it) { + std::string value = fields[it->first]; + if(!value.empty()) { + values[it->second] = value; + } + } + + return values; +} diff --git a/src/cite/ooo/ooohandler.h b/src/cite/ooo/ooohandler.h new file mode 100644 index 0000000..fd7f308 --- /dev/null +++ b/src/cite/ooo/ooohandler.h @@ -0,0 +1,54 @@ +/*************************************************************************** + copyright : (C) 2005-2006 by Robby Stephenson + email : [email protected] + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of version 2 of the GNU General Public License as * + * published by the Free Software Foundation; * + * * + ***************************************************************************/ + +#ifndef TELLICO_CITE_OOOHANDLER_H +#define TELLICO_CITE_OOOHANDLER_H + +#include "../handler.h" + +namespace rtl { + class OUString; +} + +namespace Tellico { + namespace Cite { + +/** + * @author Robby Stephenson + */ +class OOOHandler : public Handler { +public: + OOOHandler(); + + virtual State state() const; + virtual bool connect(); + virtual bool cite(Cite::Map& fields); + +private: +// static QString OUString2Q(const rtl::OUString& str); +// static rtl::OUString QString2OU(const QString& str); + static Cite::Map s_fieldsMap; + static void buildFieldsMap(); + + Cite::Map convertFields(Cite::Map& values); + + class Interface; + Interface* m_interface; + // mutable since I want to change it inside state() + mutable State m_state; +}; + + } // end namespace +} // end namespace + +#endif diff --git a/src/cite/openoffice.cpp b/src/cite/openoffice.cpp new file mode 100644 index 0000000..ced8b13 --- /dev/null +++ b/src/cite/openoffice.cpp @@ -0,0 +1,267 @@ +/*************************************************************************** + copyright : (C) 2005-2006 by Robby Stephenson + email : [email protected] + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of version 2 of the GNU General Public License as * + * published by the Free Software Foundation; * + * * + ***************************************************************************/ + +#include "openoffice.h" +#include "handler.h" +#include "../collections/bibtexcollection.h" +#include "../entry.h" +#include "../tellico_utils.h" +#include "../latin1literal.h" +#include "../statusbar.h" +#include "../tellico_kernel.h" +#include "../tellico_debug.h" + +#include <klibloader.h> +#include <kdialogbase.h> +#include <knuminput.h> +#include <kapplication.h> +#include <kconfig.h> +#include <klineedit.h> +#include <kiconloader.h> +#include <klocale.h> + +#include <qiconset.h> +#include <qlayout.h> +#include <qradiobutton.h> +#include <qbuttongroup.h> +#include <qfile.h> +#include <qvgroupbox.h> + +using Tellico::Cite::OpenOffice; + +class OpenOffice::Private { + friend class OpenOffice; + + Private() : handler(0), port(-1) { + KLibrary* library = Tellico::openLibrary(QString::fromLatin1("tellico_ooo")); + if(library) { + void* func = library->symbol("handler"); + if(func) { + handler = ((Handler* (*)())func)(); + } + } + } + + Handler* handler; + // empty pipe string indicates tcp should be used + QString host; + int port; + QString pipe; +}; + +OpenOffice::OpenOffice() : Action(), d(new Private()) { +} + +OpenOffice::~OpenOffice() { + delete d; +} + +Tellico::Cite::State OpenOffice::state() const { + if(!d->handler) { + return NoConnection; + } + return d->handler->state(); +} + +bool OpenOffice::connect() { + if(!d->handler) { + myDebug() << "OpenOffice::connect() - unable to open OpenOffice.org plugin" << endl; + return false; + } + + StatusBar::self()->setStatus(i18n("Connecting to OpenOffice.org...")); + + if(d->port == -1) { + KConfigGroup config(kapp->config(), "OpenOffice.org"); + d->host = config.readEntry("Host", QString::fromLatin1("localhost")); + d->port = config.readNumEntry("Port", 2083); + d->pipe = config.readPathEntry("Pipe"); + // the ooohandler will depend on pipe.isEmpty() to indicate the port should be used + d->handler->setHost(d->host); + d->handler->setPort(d->port); + if(!d->pipe.isEmpty()) { + d->handler->setPipe(QFile::encodeName(d->pipe)); + } + } + + bool success = d->handler->connect(); + bool needInput = !success; + while(needInput) { + switch(state()) { + case NoConnection: + myDebug() << "OpenOffice::connect() - NoConnection" << endl; + // try to reconnect + if(connectionDialog()) { + success = d->handler->connect(); + needInput = !success; + } else { + needInput = false; + } + break; + case NoDocument: + myDebug() << "OpenOffice::connect() - NoDocument" << endl; + break; + default: + myDebug() << "OpenOffice::connect() - weird state" << endl; + break; + } + } + StatusBar::self()->clearStatus(); + return success; +} + +bool OpenOffice::cite(Data::EntryVec entries_) { + if(!connect()) { + myDebug() << "OpenOffice::cite() - can't connect to OpenOffice" << endl; + return false; + } + if(entries_.isEmpty()) { + myDebug() << "OpenOffice::cite() - no entries" << endl; + return false; + } + + Data::CollPtr coll = entries_.front()->collection(); + if(!coll || coll->type() != Data::Collection::Bibtex) { + myDebug() << "OpenOffice::cite() - not a bibtex collection" << endl; + return false; + } + + const QString bibtex = QString::fromLatin1("bibtex"); + Data::FieldVec vec = coll->fields(); + for(Data::EntryVecIt entry = entries_.begin(); entry != entries_.end(); ++entry) { + Cite::Map values; + for(Data::FieldVec::Iterator it = vec.begin(); it != vec.end(); ++it) { + QString bibtexField = it->property(bibtex); + if(!bibtexField.isEmpty()) { + QString s = entry->field(it->name()); + if(!s.isEmpty()) { + values[bibtexField] = s.utf8(); // always utf8 + } + } else if(it->name() == Latin1Literal("isbn")) { + // OOO includes ISBN + QString s = entry->field(it->name()); + if(!s.isEmpty()) { + values[it->name()] = s.utf8(); + } + } + } + d->handler->cite(values); + } + return true; +} + +bool OpenOffice::connectionDialog() { + KDialogBase dlg(Kernel::self()->widget(), "ooo connection dialog", + true, i18n("OpenOffice.org Connection"), + KDialogBase::Ok|KDialogBase::Cancel|KDialogBase::Help); + + dlg.setHelp(QString::fromLatin1("openoffice-org")); + + QWidget* widget = new QWidget(&dlg); + QBoxLayout* topLayout = new QVBoxLayout(widget, KDialog::spacingHint()); + dlg.setMainWidget(widget); + // is there a better way to do a multi-line label than to insert newlines in the text? + QBoxLayout* blay = new QHBoxLayout(topLayout); + QLabel* l = new QLabel(widget); + l->setPixmap(DesktopIcon(QString::fromLatin1("ooo_writer"), 64)); + blay->addWidget(l); + l = new QLabel(widget); + l->setText(i18n("Tellico was unable to connect to OpenOffice.org. " + "Please verify the connection settings below, and " + "that OpenOffice.org Writer is currently running.")); + l->setTextFormat(Qt::RichText); + blay->addWidget(l); + blay->setStretchFactor(l, 10); + + QVGroupBox* gbox = new QVGroupBox(i18n("OpenOffice.org Connection"), widget); + topLayout->addWidget(gbox); + + QWidget* w2 = new QWidget(gbox); + QGridLayout* gl = new QGridLayout(w2, 2, 3, 0 /*margin*/, KDialog::spacingHint()); + QRadioButton* radioPipe = new QRadioButton(i18n("Pipe"), w2); + gl->addWidget(radioPipe, 0, 0); + QRadioButton* radioTCP = new QRadioButton(i18n("TCP/IP"), w2); + gl->addWidget(radioTCP, 1, 0); + QButtonGroup* btnGroup = new QButtonGroup(); + btnGroup->setRadioButtonExclusive(true); + btnGroup->insert(radioPipe, 0); + btnGroup->insert(radioTCP, 1); + + KLineEdit* pipeEdit = new KLineEdit(w2); + pipeEdit->setText(d->pipe); + gl->addMultiCellWidget(pipeEdit, 0, 0, 1, 2); + pipeEdit->connect(radioPipe, SIGNAL(toggled(bool)), SLOT(setEnabled(bool))); + + KLineEdit* hostEdit = new KLineEdit(w2); + hostEdit->setText(d->host); + gl->addWidget(hostEdit, 1, 1); + hostEdit->connect(radioTCP, SIGNAL(toggled(bool)), SLOT(setEnabled(bool))); + KIntSpinBox* portSpin = new KIntSpinBox(w2); + portSpin->setMaxValue(99999); + portSpin->setValue(d->port); + gl->addWidget(portSpin, 1, 2); + portSpin->connect(radioTCP, SIGNAL(toggled(bool)), SLOT(setEnabled(bool))); + + if(d->pipe.isEmpty()) { + radioTCP->setChecked(true); + hostEdit->setEnabled(true); + portSpin->setEnabled(true); + pipeEdit->setEnabled(false); + } else { + radioPipe->setChecked(true); + hostEdit->setEnabled(false); + portSpin->setEnabled(false); + pipeEdit->setEnabled(true); + } + topLayout->addStretch(10); + + if(dlg.exec() != QDialog::Accepted) { + return false; + } + + int p = d->port; + QString h = d->host; + QString s; + if(radioTCP->isChecked()) { + h = hostEdit->text(); + if(h.isEmpty()) { + h = QString::fromLatin1("localhost"); + } + p = portSpin->value(); + } else { + s = pipeEdit->text(); + } + d->host = h; + d->port = p; + d->pipe = s; + + if(!d->host.isEmpty()) { + d->handler->setHost(d->host); + } + d->handler->setPort(d->port); + if(!d->pipe.isEmpty()) { + d->handler->setPipe(QFile::encodeName(d->pipe)); + } + + KConfigGroup config(kapp->config(), "OpenOffice.org"); + config.writeEntry("Host", d->host); + config.writeEntry("Port", d->port); + config.writePathEntry("Pipe", d->pipe); + return true; +} + +bool OpenOffice::hasLibrary() { + QString path = KLibLoader::findLibrary("tellico_ooo"); + if(!path.isEmpty()) myDebug() << "OpenOffice::hasLibrary() - Found OOo plugin: " << path << endl; + return !path.isEmpty(); +} diff --git a/src/cite/openoffice.h b/src/cite/openoffice.h new file mode 100644 index 0000000..a5204ac --- /dev/null +++ b/src/cite/openoffice.h @@ -0,0 +1,47 @@ +/*************************************************************************** + copyright : (C) 2005-2006 by Robby Stephenson + email : [email protected] + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of version 2 of the GNU General Public License as * + * published by the Free Software Foundation; * + * * + ***************************************************************************/ + +#ifndef TELLICO_CITE_OPENOFFICE_H +#define TELLICO_CITE_OPENOFFICE_H + +#include "actionmanager.h" + +namespace Tellico { + namespace Cite { + +/** + * @author Robby Stephenson + */ +class OpenOffice : public Action { +public: + OpenOffice(); + ~OpenOffice(); + + virtual CiteAction type() const { return CiteOpenOffice; } + + virtual bool connect(); + virtual bool cite(Data::EntryVec entries); + virtual State state() const; + + static bool hasLibrary(); + +private: + bool connectionDialog(); + class Private; + Private* d; +}; + + } +} + +#endif |