summaryrefslogtreecommitdiffstats
path: root/src/cite
diff options
context:
space:
mode:
Diffstat (limited to 'src/cite')
-rw-r--r--src/cite/Makefile.am20
-rw-r--r--src/cite/actionmanager.cpp85
-rw-r--r--src/cite/actionmanager.h64
-rw-r--r--src/cite/clipboard.cpp51
-rw-r--r--src/cite/clipboard.h36
-rw-r--r--src/cite/handler.h61
-rw-r--r--src/cite/lyxpipe.cpp92
-rw-r--r--src/cite/lyxpipe.h36
-rw-r--r--src/cite/ooo/Makefile.am88
-rw-r--r--src/cite/ooo/interface.cpp430
-rw-r--r--src/cite/ooo/interface.h62
-rw-r--r--src/cite/ooo/ooohandler.cpp159
-rw-r--r--src/cite/ooo/ooohandler.h54
-rw-r--r--src/cite/openoffice.cpp267
-rw-r--r--src/cite/openoffice.h47
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 : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 : robby@periapsis.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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