[gnote] Implement org.gnome.Gnote.RemoteControl to mimic Tomboy DBus API. (Closes #581030)



commit 3700d2096b32eee80bf6a76a1286aed75508b601
Author: Hubert Figuiere <hub figuiere net>
Date:   Sat Jul 18 14:15:42 2009 -0400

    Implement org.gnome.Gnote.RemoteControl to mimic Tomboy DBus API. (Closes #581030)

 configure.ac                                       |   13 +-
 data/Makefile.am                                   |    8 +-
 ...GNote.service.in => org.gnome.Gnote.service.in} |    0
 src/Makefile.am                                    |   13 +-
 src/dbus/Makefile.am                               |   11 +
 src/dbus/gnote-introspect.xml                      |  120 ++++++
 src/dbus/iremotecontrol.hpp                        |   34 ++
 src/dbus/remotecontrol.cpp                         |  395 ++++++++++++++++++++
 src/dbus/remotecontrol.hpp                         |   84 +++++
 src/gnote.cpp                                      |   40 ++-
 src/gnote.hpp                                      |    3 +
 src/remotecontrolproxy.cpp                         |   54 +++
 src/remotecontrolproxy.hpp                         |   44 +++
 src/sharp/map.hpp                                  |   12 +
 tools/DBusClientTest.py                            |   53 +++
 15 files changed, 874 insertions(+), 10 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 032fba6..8981bd1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -166,13 +166,17 @@ AC_LANG_POP
 # Use DBus to export our remote control if available.
 #
 AC_ARG_ENABLE(dbus, 
-	      [  --enable-dbus[[=no/yes]]    compile with dbus support [[default: no]]],
-	      ENABLE_DBUS="$enableval", ENABLE_DBUS="no")
-AM_CONDITIONAL(ENABLE_DBUS, test "x$ENABLE_DBUS" != "xno")
+	      [  --enable-dbus[[=no/yes]]    compile with dbus support [[default: yes]]],
+	      ENABLE_DBUS="$enableval", ENABLE_DBUS="yes")
 if test "x$ENABLE_DBUS" != "xno"; then
-   AC_ERROR("DBus support not implemented yet");
+        PKG_CHECK_MODULES(DBUS, dbus-c++-1, [
+              have_dbus="yes";AC_DEFINE([ENABLE_DBUS], [1], [Define to 1 if DBus is enabled])
+           ], have_dbus="no")
+        AM_CONDITIONAL(HAVE_DBUS, test "$have_dbus" = "yes")
 fi
 
+
+
 AC_ARG_WITH(dbus_service_dir, [  --with-dbus-service-dir=DIR            Where to install Gnote's DBus service file.])
 AM_CONDITIONAL(WITH_DBUS_SERVICE_DIR, test "x$with_dbus_service_dir" != "x")
 if test "x$with_dbus_service_dir" != "x"; then
@@ -223,6 +227,7 @@ src/addins/inserttimestamp/Makefile
 src/addins/printnotes/Makefile
 src/addins/stickynoteimport/Makefile
 src/addins/tomboyimport/Makefile
+src/dbus/Makefile
 po/Makefile.in
 po/Makefile
 help/Makefile
diff --git a/data/Makefile.am b/data/Makefile.am
index 4809d48..d2fa0f7 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -28,14 +28,14 @@ install-data-local:
 endif
 
 
-if ENABLE_DBUS
+if HAVE_DBUS
 dbusservicedir       = $(DBUS_SERVICE_DIR)
-dbusservice_in_files = org.gnome.GNote.service.in
+dbusservice_in_files = org.gnome.Gnote.service.in
 dbusservice_DATA     = $(dbusservice_in_files:.service.in=.service)
 
 $(dbusservice_DATA): $(dbusservice_in_files) Makefile
-	sed -e "s|\ libexecdir\@|$(libexecdir)|g"	\
-	    -e "s|\ wrapper\@|gnote-applet|g"		\
+	sed -e "s|\ libexecdir\@|$(bindir)|g"	\
+	    -e "s|\ wrapper\@|gnote|g"		\
 	    < $< > $@
 endif
 
diff --git a/data/org.gnome.GNote.service.in b/data/org.gnome.Gnote.service.in
similarity index 100%
rename from data/org.gnome.GNote.service.in
rename to data/org.gnome.Gnote.service.in
diff --git a/src/Makefile.am b/src/Makefile.am
index 3f6d72d..0455b84 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -10,6 +10,7 @@ AM_CPPFLAGS= LIBGTKMM_CFLAGS@ @LIBGLIBMM_CFLAGS@ \
 	@GTKSPELL_CFLAGS@ @LIBXML_CFLAGS@ \
 	@LIBXSLT_CFLAGS@ \
 	@PCRE_CFLAGS@ \
+	@DBUS_CFLAGS@ \
 	-DGNOTE_LOCALEDIR=\"@GNOTE_LOCALEDIR \" \
 	-DDATADIR=\"$(datadir)\" -DLIBDIR=\"$(libdir)\"
 
@@ -20,6 +21,7 @@ GNOTE_LIBS = libgnote.a $(top_builddir)/libtomboy/libtomboy.la \
 	@GCONF_LIBS@ @BOOST_FILESYSTEM_LIBS@ @BOOST_SYSTEM_LIBS@ \
 	@LIBXSLT_LIBS@ \
 	@PCRE_LIBS@ \
+	@DBUS_LIBS@ \
 	@GTKSPELL_LIBS@ @GTK_LIBS@ \
 	-luuid
 
@@ -74,6 +76,14 @@ gnote-applet: gnote-applet.in Makefile
 CLEANFILES = gnote-applet
 endif
 
+
+if HAVE_DBUS
+SUBDIRS += dbus
+DBUS_SOURCES=remotecontrolproxy.hpp remotecontrolproxy.cpp \
+	dbus/remotecontrol.hpp dbus/remotecontrol.cpp \
+	$(NULL)
+endif
+
 libgnote_a_SOURCES = \
 	base/singleton.hpp \
 	base/macros.hpp \
@@ -140,7 +150,8 @@ libgnote_a_SOURCES = \
 	notebooks/notebooknewnotemenuitem.hpp notebooks/notebooknewnotemenuitem.cpp \
 	notebooks/notebooknoteaddin.hpp notebooks/notebooknoteaddin.cpp \
 	notebooks/notebookstreeview.hpp notebooks/notebookstreeview.cpp \
-	$(APPLET_SOURCES)
+	$(DBUS_SOURCES)   \
+	$(APPLET_SOURCES) \
 	$(NULL)
 
 gnote_LDADD = $(GNOTE_LIBS)
diff --git a/src/dbus/Makefile.am b/src/dbus/Makefile.am
new file mode 100644
index 0000000..28dbb6a
--- /dev/null
+++ b/src/dbus/Makefile.am
@@ -0,0 +1,11 @@
+
+
+remotecontrol-glue.hpp: gnote-introspect.xml
+	dbusxx-xml2cpp $^ --adaptor=$@
+
+BUILT_SOURCES = remotecontrol-glue.hpp
+CLEANFILES = $(BUILT_SOURCES)
+
+dist-hook:
+	cd $(distdir); rm -f $(BUILT_SOURCES)
+
diff --git a/src/dbus/gnote-introspect.xml b/src/dbus/gnote-introspect.xml
new file mode 100644
index 0000000..66ee335
--- /dev/null
+++ b/src/dbus/gnote-introspect.xml
@@ -0,0 +1,120 @@
+<?xml version="1.0" ?>
+<node name="/org/gnome/Gnote/RemoteControl">
+  <interface name="org.gnome.Gnote.RemoteControl">
+    <method name="AddTagToNote">
+      <arg type="s" name="uri" direction="in"/>
+      <arg type="s" name="tag_name" direction="in"/>
+      <arg type="b" name="ret" direction="out"/>
+    </method>
+    <method name="CreateNamedNote">
+      <arg type="s" name="linked_title" direction="in"/>
+      <arg type="s" name="ret" direction="out"/>
+    </method>
+    <method name="CreateNote">
+      <arg type="s" name="ret" direction="out"/>
+    </method>
+    <method name="DeleteNote">
+      <arg type="s" name="uri" direction="in"/>
+      <arg type="b" name="ret" direction="out"/>
+    </method>
+    <method name="DisplayNoteWithSearch">
+      <arg type="s" name="uri" direction="in"/>
+      <arg type="s" name="search" direction="in"/>
+      <arg type="b" name="ret" direction="out"/>
+    </method>
+    <method name="DisplaySearch">
+    </method>
+    <method name="DisplaySearchWithText">
+      <arg type="s" name="search_text" direction="in"/>
+    </method>
+    <method name="FindNote">
+      <arg type="s" name="linked_title" direction="in"/>
+      <arg type="s" name="ret" direction="out"/>
+    </method>
+    <method name="FindNoteStartHereNote">
+      <arg type="s" name="ret" direction="out"/>
+    </method>
+    <method name="GetAllNotesWithTag">
+      <arg type="s" name="tag_name" direction="in"/>
+      <arg type="as" name="ret" direction="out"/>
+    </method>
+    <method name="GetNoteChangeDate">
+      <arg type="s" name="uri" direction="in"/>
+      <arg type="i" name="ret" direction="out"/>
+    </method>
+    <method name="GetNoteCompleteXml">
+      <arg type="s" name="uri" direction="in"/>
+      <arg type="s" name="ret" direction="out"/>
+    </method>
+    <method name="GetNoteContents">
+      <arg type="s" name="uri" direction="in"/>
+      <arg type="s" name="ret" direction="out"/>
+    </method>
+    <method name="GetNoteContentsXml">
+      <arg type="s" name="uri" direction="in"/>
+      <arg type="s" name="ret" direction="out"/>
+    </method>
+    <method name="GetNoteCreateDate">
+      <arg type="s" name="uri" direction="in"/>
+      <arg type="i" name="ret" direction="out"/>
+    </method>
+    <method name="GetNoteTitle">
+      <arg type="s" name="uri" direction="in"/>
+      <arg type="s" name="ret" direction="out"/>
+    </method>
+    <method name="GetTagsForNote">
+      <arg type="s" name="uri" direction="in"/>
+      <arg type="as" name="ret" direction="out"/>
+    </method>
+    <method name="HideNote">
+      <arg type="s" name="uri" direction="in"/>
+      <arg type="b" name="ret" direction="out"/>
+    </method>
+    <method name="ListAllNotes">
+      <arg type="as" name="ret" direction="out"/>
+    </method>
+    <method name="NoteExists">
+      <arg type="s" name="uri" direction="in"/>
+      <arg type="b" name="ret" direction="out"/>
+    </method>
+    <method name="RemoveTagFromNote">
+      <arg type="s" name="uri" direction="in"/>
+      <arg type="s" name="tag_name" direction="in"/>
+      <arg type="b" name="ret" direction="out"/>      
+    </method>
+    <method name="SearchNotes">
+      <arg type="s" name="query" direction="in"/>
+      <arg type="b" name="case_sensitive" direction="in"/>
+      <arg type="as" name="ret" direction="out"/>
+    </method>
+    <method name="SetNoteCompleteXml">
+      <arg type="s" name="uri" direction="in"/>
+      <arg type="s" name="xml_contents" direction="in"/>
+      <arg type="b" name="ret" direction="out"/>      
+    </method>
+    <method name="SetNoteContents">
+      <arg type="s" name="uri" direction="in"/>
+      <arg type="s" name="text_contents" direction="in"/>
+      <arg type="b" name="ret" direction="out"/>      
+    </method>
+    <method name="SetNoteContentsXml">
+      <arg type="s" name="uri" direction="in"/>
+      <arg type="s" name="xml_contents" direction="in"/>
+      <arg type="b" name="ret" direction="out"/>      
+    </method>
+    <method name="Version">
+      <arg type="s" name="ret" direction="out"/>      
+    </method>
+
+    <signal name="NoteAdded">
+      <arg type="s" name="uri"/>
+    </signal>
+    <signal name="NoteDeleted">
+      <arg type="s" name="uri"/>
+      <arg type="s" name="title"/>
+    </signal>
+    <signal name="NoteSaved">
+      <arg type="s" name="uri"/>
+    </signal>
+  </interface>
+</node>
diff --git a/src/dbus/iremotecontrol.hpp b/src/dbus/iremotecontrol.hpp
new file mode 100644
index 0000000..269d86f
--- /dev/null
+++ b/src/dbus/iremotecontrol.hpp
@@ -0,0 +1,34 @@
+/*
+ * gnote
+ *
+ * Copyright (C) 2009 Hubert Figuiere
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef __IREMOTE_CONTROL_HPP_
+#define __IREMOTE_CONTROL_HPP_
+
+#include "dbus/remotecontrol-glue.hpp"
+
+
+namespace gnote {
+
+typedef org::gnome::Gnote::RemoteControl_adaptor IRemoteControl;
+
+}
+
+
+#endif
diff --git a/src/dbus/remotecontrol.cpp b/src/dbus/remotecontrol.cpp
new file mode 100644
index 0000000..9313fc1
--- /dev/null
+++ b/src/dbus/remotecontrol.cpp
@@ -0,0 +1,395 @@
+/*
+ * gnote
+ *
+ * Copyright (C) 2009 Hubert Figuiere
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "sharp/map.hpp"
+#include "debug.hpp"
+#include "notemanager.hpp"
+#include "notewindow.hpp"
+#include "recentchanges.hpp"
+#include "remotecontrolproxy.hpp"
+#include "search.hpp"
+#include "tag.hpp"
+#include "tagmanager.hpp"
+#include "dbus/remotecontrol.hpp"
+
+namespace gnote {
+
+
+  RemoteControl::RemoteControl(DBus::Connection& cnx, NoteManager& manager)
+    : DBus::ObjectAdaptor(cnx, RemoteControlProxy::GNOTE_SERVER_PATH)
+    , m_manager(manager)
+  {
+    DBG_OUT("initialized remote control");
+    m_manager.signal_note_added.connect(
+      sigc::mem_fun(*this, &RemoteControl::on_note_added));
+    m_manager.signal_note_deleted.connect(
+      sigc::mem_fun(*this, &RemoteControl::on_note_deleted));
+    m_manager.signal_note_saved.connect(
+      sigc::mem_fun(*this, &RemoteControl::on_note_saved));
+  }
+
+
+  RemoteControl::~RemoteControl()
+  {
+  }
+
+  bool RemoteControl::AddTagToNote(const std::string& uri, const std::string& tag_name)
+  {
+    Note::Ptr note = m_manager.find_by_uri (uri);
+    if (!note) {
+      return false;
+    }
+    Tag::Ptr tag = TagManager::obj().get_or_create_tag (tag_name);
+    note->add_tag (tag);
+    return true;
+  }
+
+
+  std::string RemoteControl::CreateNamedNote(const std::string& linked_title)
+  {
+    Note::Ptr note;
+
+    note = m_manager.find (linked_title);
+    if (!note)
+      return "";
+
+    try {
+      note = m_manager.create (linked_title);
+      return note->uri();
+    } 
+    catch (...) {
+    }
+    return "";
+  }
+
+  std::string RemoteControl::CreateNote()
+  {
+    try {
+      Note::Ptr note = m_manager.create ();
+      return note->uri();
+    } 
+    catch(...)
+    {
+    }
+    return "";
+  }
+
+  bool RemoteControl::DeleteNote(const std::string& uri)
+  {
+    Note::Ptr note;
+
+    note = m_manager.find_by_uri (uri);
+    if (!note) {
+      return false;
+    }
+
+    m_manager.delete_note (note);
+    return true;
+
+  }
+
+  bool RemoteControl::DisplayNoteWithSearch(const std::string& uri, const std::string& search)
+  {
+    Note::Ptr note;
+
+    note = m_manager.find_by_uri (uri);
+    if (!note) {
+      return false;
+    }
+
+    note->get_window()->present();
+
+    // Pop open the find-bar
+    NoteFindBar & findbar = note->get_window()->get_find_bar();
+    findbar.show_all ();
+    findbar.property_visible() = true;
+    findbar.set_search_text(search);
+
+    return true;
+  }
+
+
+  void RemoteControl::DisplaySearch()
+  {
+    NoteRecentChanges::get_instance(m_manager)->present();
+  }
+
+
+  void RemoteControl::DisplaySearchWithText(const std::string& search_text)
+  {
+    NoteRecentChanges* recent_changes =
+      NoteRecentChanges::get_instance (m_manager);
+    if (!recent_changes)
+				return;
+
+    recent_changes->set_search_text(search_text);
+    recent_changes->present ();
+  }
+
+
+  std::string RemoteControl::FindNote(const std::string& linked_title)
+  {
+    Note::Ptr note = m_manager.find (linked_title);
+    return (!note) ? "" : note->uri();
+  }
+
+
+  std::string RemoteControl::FindNoteStartHereNote()
+  {
+    Note::Ptr note = m_manager.find_by_uri (m_manager.start_note_uri());
+    return (!note) ? "" : note->uri();
+  }
+
+
+  std::vector< std::string > RemoteControl::GetAllNotesWithTag(const std::string& tag_name)
+  {
+    Tag::Ptr tag = TagManager::obj().get_tag (tag_name);
+    if (!tag)
+      return std::vector< std::string >();
+
+    std::vector< std::string > tagged_note_uris;
+    std::list<Note *> notes;
+    tag->get_notes(notes);
+    for (std::list<Note *>::const_iterator iter = notes.begin();
+         iter != notes.end(); ++iter) {
+      tagged_note_uris.push_back((*iter)->uri());
+    }
+    return tagged_note_uris;
+  }
+
+
+  int32_t RemoteControl::GetNoteChangeDate(const std::string& uri)
+  {
+    Note::Ptr note;
+    note = m_manager.find_by_uri (uri);
+    if (!note)
+      return -1;
+    return note->metadata_change_date().sec();
+  }
+
+
+  std::string RemoteControl::GetNoteCompleteXml(const std::string& uri)
+  {
+    Note::Ptr note;
+    note = m_manager.find_by_uri (uri);
+    if (!note)
+      return "";
+    return note->get_complete_note_xml();
+
+  }
+
+
+  std::string RemoteControl::GetNoteContents(const std::string& uri)
+  {
+    Note::Ptr note;
+    note = m_manager.find_by_uri (uri);
+    if (!note)
+      return "";
+    return note->text_content();
+  }
+
+
+  std::string RemoteControl::GetNoteContentsXml(const std::string& uri)
+  {
+    Note::Ptr note;
+    note = m_manager.find_by_uri (uri);
+    if (!note)
+      return "";
+    return note->xml_content();
+  }
+
+
+  int32_t RemoteControl::GetNoteCreateDate(const std::string& uri)
+  {
+    Note::Ptr note;
+    note = m_manager.find_by_uri (uri);
+    if (!note)
+      return -1;
+    return note->create_date().sec();
+  }
+
+
+  std::string RemoteControl::GetNoteTitle(const std::string& uri)
+  {
+    Note::Ptr note;
+    note = m_manager.find_by_uri (uri);
+    if (!note)
+      return "";
+    return note->get_title();
+  }
+
+
+  std::vector< std::string > RemoteControl::GetTagsForNote(const std::string& uri)
+  {
+    Note::Ptr note;
+    note = m_manager.find_by_uri (uri);
+    if (!note)
+      return std::vector< std::string >();
+
+    std::vector< std::string > tags;
+    std::list<Tag::Ptr> l;
+    note->get_tags(l);
+    for (std::list<Tag::Ptr>::const_iterator iter = l.begin();
+         iter != l.end(); ++iter) {
+      tags.push_back((*iter)->normalized_name());
+    }
+    return tags;
+  }
+
+
+bool RemoteControl::HideNote(const std::string& uri)
+{
+  Note::Ptr note;
+  note = m_manager.find_by_uri (uri);
+  if (!note)
+    return false;
+
+  note->get_window()->hide();
+  return true;
+}
+
+
+std::vector< std::string > RemoteControl::ListAllNotes()
+{
+  std::vector< std::string > uris;
+  for(Note::List::const_iterator iter = m_manager.get_notes().begin();
+      iter != m_manager.get_notes().end(); ++iter) {
+    uris.push_back((*iter)->uri());
+  }
+  return uris;
+}
+
+
+bool RemoteControl::NoteExists(const std::string& uri)
+{
+  Note::Ptr note = m_manager.find_by_uri (uri);
+  return note;
+}
+
+
+bool RemoteControl::RemoveTagFromNote(const std::string& uri, 
+                                      const std::string& tag_name)
+{
+  Note::Ptr note = m_manager.find_by_uri (uri);
+  if (!note)
+    return false;
+  Tag::Ptr tag = TagManager::obj().get_tag (tag_name);
+  if (tag) {
+    note->remove_tag (tag);
+  }
+  return true;
+}
+
+
+std::vector< std::string > RemoteControl::SearchNotes(const std::string& query,
+                                                      const bool& case_sensitive)
+{
+  if (query.empty())
+    return std::vector< std::string >();
+
+  Search search(m_manager);
+  std::vector< std::string > list;
+  Search::ResultsPtr results =
+    search.search_notes(query, case_sensitive, notebooks::Notebook::Ptr());
+
+  for(Search::Results::const_iterator iter = results->begin();
+      iter != results->end(); ++iter) {
+
+    list.push_back(iter->first->uri());
+  }
+
+  return list;
+}
+
+
+bool RemoteControl::SetNoteCompleteXml(const std::string& uri, 
+                                       const std::string& xml_contents)
+{
+  Note::Ptr note;
+  note = m_manager.find_by_uri(uri);
+  if(!note) {
+    return false;
+  }
+    
+  note->load_foreign_note_xml(xml_contents, Note::CONTENT_CHANGED);
+  return true;
+}
+
+
+bool RemoteControl::SetNoteContents(const std::string& uri, 
+                                    const std::string& text_contents)
+{
+  Note::Ptr note;
+  note = m_manager.find_by_uri(uri);
+  if(!note) {
+    return false;
+  }
+
+  note->set_text_content(text_contents);
+  return true;
+}
+
+
+bool RemoteControl::SetNoteContentsXml(const std::string& uri, 
+                                       const std::string& xml_contents)
+{
+  Note::Ptr note;
+  note = m_manager.find_by_uri(uri);
+  if(!note) {
+    return false;
+  }
+  note->set_xml_content(xml_contents);
+  return true;
+}
+
+
+std::string RemoteControl::Version()
+{
+  return VERSION;
+}
+
+
+
+void RemoteControl::on_note_added(const Note::Ptr & note)
+{
+  if(note) {
+    NoteAdded(note->uri());
+  }
+}
+
+
+void RemoteControl::on_note_deleted(const Note::Ptr & note)
+{
+  if(note) {
+    NoteDeleted(note->uri(), note->get_title());
+  }
+}
+
+
+void RemoteControl::on_note_saved(const Note::Ptr & note)
+{
+  if(note) {
+    NoteSaved(note->uri());
+  }
+}
+
+
+}
diff --git a/src/dbus/remotecontrol.hpp b/src/dbus/remotecontrol.hpp
new file mode 100644
index 0000000..149c3b6
--- /dev/null
+++ b/src/dbus/remotecontrol.hpp
@@ -0,0 +1,84 @@
+/*
+ * gnote
+ *
+ * Copyright (C) 2009 Hubert Figuiere
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __GNOTE_REMOTECONTROL_HPP_
+#define __GNOTE_REMOTECONTROL_HPP_
+
+#include <string>
+#include <vector>
+
+#include <dbus-c++/dbus.h>
+
+#include "dbus/iremotecontrol.hpp"
+#include "note.hpp"
+
+
+namespace gnote {
+
+class NoteManager;
+
+class RemoteControl
+  : public IRemoteControl
+  , public DBus::IntrospectableAdaptor
+  , public DBus::ObjectAdaptor
+{
+public:
+  RemoteControl(DBus::Connection&, gnote::NoteManager&);
+  virtual ~RemoteControl();
+
+  virtual bool AddTagToNote(const std::string& uri, const std::string& tag_name);
+  virtual std::string CreateNamedNote(const std::string& linked_title);
+  virtual std::string CreateNote();
+  virtual bool DeleteNote(const std::string& uri);
+  virtual bool DisplayNoteWithSearch(const std::string& uri, const std::string& search);
+  virtual void DisplaySearch();
+  virtual void DisplaySearchWithText(const std::string& search_text);
+  virtual std::string FindNote(const std::string& linked_title);
+  virtual std::string FindNoteStartHereNote();
+  virtual std::vector< std::string > GetAllNotesWithTag(const std::string& tag_name);
+  virtual int32_t GetNoteChangeDate(const std::string& uri);
+  virtual std::string GetNoteCompleteXml(const std::string& uri);
+  virtual std::string GetNoteContents(const std::string& uri);
+  virtual std::string GetNoteContentsXml(const std::string& uri);
+  virtual int32_t GetNoteCreateDate(const std::string& uri);
+  virtual std::string GetNoteTitle(const std::string& uri);
+  virtual std::vector< std::string > GetTagsForNote(const std::string& uri);
+  virtual bool HideNote(const std::string& uri);
+  virtual std::vector< std::string > ListAllNotes();
+  virtual bool NoteExists(const std::string& uri);
+  virtual bool RemoveTagFromNote(const std::string& uri, const std::string& tag_name);
+  virtual std::vector< std::string > SearchNotes(const std::string& query, const bool& case_sensitive);
+  virtual bool SetNoteCompleteXml(const std::string& uri, const std::string& xml_contents);
+  virtual bool SetNoteContents(const std::string& uri, const std::string& text_contents);
+  virtual bool SetNoteContentsXml(const std::string& uri, const std::string& xml_contents);
+  virtual std::string Version();
+
+private:
+  void on_note_added(const Note::Ptr &);
+  void on_note_deleted(const Note::Ptr &);
+  void on_note_saved(const Note::Ptr &);
+
+  NoteManager & m_manager;
+};
+
+
+}
+
+#endif
+
diff --git a/src/gnote.cpp b/src/gnote.cpp
index d3a1f56..509e6e6 100644
--- a/src/gnote.cpp
+++ b/src/gnote.cpp
@@ -54,6 +54,10 @@
 #include "applet.hpp"
 #endif
 
+#if ENABLE_DBUS
+#include "remotecontrolproxy.hpp"
+#endif
+
 namespace gnote {
 
   bool Gnote::s_tray_icon_showing = false;
@@ -104,7 +108,7 @@ namespace gnote {
 
     ActionManager & am(ActionManager::obj());
     am.load_interface();
-//    register_remote_control(m_manager);
+    register_remote_control(*m_manager);
     setup_global_actions();
     
     std::list<ApplicationAddin*> addins;
@@ -208,6 +212,40 @@ namespace gnote {
   }
 
 
+  void Gnote::register_remote_control(NoteManager & manager)
+  {
+#if ENABLE_DBUS
+    try {
+      m_remote_control = RemoteControlProxy::register_remote(manager);
+      if (m_remote_control) {
+        DBG_OUT("Gnote remote control active.");
+      } 
+      else {
+        // If Tomboy is already running, open the search window
+        // so the user gets some sort of feedback when they
+        // attempt to run Tomboy again.
+        IRemoteControl *m_remote;
+        try {
+          m_remote = RemoteControlProxy::get_instance();
+          m_remote->DisplaySearch();
+        } 
+        catch (...)
+        {
+        }
+
+        ERR_OUT ("Gnote is already running.  Exiting...");
+        ::exit(-1);
+      }
+    } 
+    catch (const std::exception & e) {
+      ERR_OUT("Gnote remote control disabled (DBus exception): %s",
+              e.what());
+    }
+#endif
+  }
+
+
+
   void Gnote::setup_global_actions()
   {
     ActionManager & am(ActionManager::obj());
diff --git a/src/gnote.hpp b/src/gnote.hpp
index be81648..209a7f0 100644
--- a/src/gnote.hpp
+++ b/src/gnote.hpp
@@ -39,6 +39,7 @@ namespace gnote {
 
 class PreferencesDialog;
 class NoteManager;
+class RemoteControl;
 
 class Gnote
   : public base::Singleton<Gnote>
@@ -85,6 +86,7 @@ private:
   void start_note_created(const Note::Ptr & start_note);
   static std::string conf_dir();
   std::string get_note_path(const std::string & override_path);
+  void register_remote_control(NoteManager & manager);
 
   NoteManager *m_manager;
   IKeybinder  *m_keybinder;
@@ -94,6 +96,7 @@ private:
   Tray::Ptr m_tray;
   bool m_is_panel_applet;
   PreferencesDialog *m_prefsdlg;
+  RemoteControl     *m_remote_control;
 };
 
 
diff --git a/src/remotecontrolproxy.cpp b/src/remotecontrolproxy.cpp
new file mode 100644
index 0000000..89f058a
--- /dev/null
+++ b/src/remotecontrolproxy.cpp
@@ -0,0 +1,54 @@
+/*
+ * gnote
+ *
+ * Copyright (C) 2009 Hubert Figuiere
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <dbus-c++/glib-integration.h>
+
+#include "dbus/remotecontrol.hpp"
+#include "remotecontrolproxy.hpp"
+
+
+namespace gnote {
+
+const char *RemoteControlProxy::GNOTE_SERVER_NAME = "org.gnome.Gnote";
+const char *RemoteControlProxy::GNOTE_SERVER_PATH = "/org/gnome/Gnote/RemoteControl";
+
+IRemoteControl *RemoteControlProxy::get_instance()
+{
+  return NULL;
+}
+
+
+DBus::Glib::BusDispatcher dispatcher;
+
+RemoteControl *RemoteControlProxy::register_remote(NoteManager & manager)
+{
+  DBus::default_dispatcher = &dispatcher;
+	dispatcher.attach(NULL);
+
+	DBus::Connection conn = DBus::Connection::SessionBus();
+	conn.request_name(GNOTE_SERVER_NAME);
+
+  RemoteControl *remote_control = new RemoteControl (conn, manager);
+
+  return remote_control;
+}
+
+
+}
+
diff --git a/src/remotecontrolproxy.hpp b/src/remotecontrolproxy.hpp
new file mode 100644
index 0000000..49a8ba5
--- /dev/null
+++ b/src/remotecontrolproxy.hpp
@@ -0,0 +1,44 @@
+/*
+ * gnote
+ *
+ * Copyright (C) 2009 Hubert Figuiere
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _REMOTECONTROL_PROXY_HPP_
+#define _REMOTECONTROL_PROXY_HPP_
+
+#include "dbus/iremotecontrol.hpp"
+
+namespace gnote {
+
+class RemoteControl;
+class NoteManager;
+
+class RemoteControlProxy 
+{
+public:
+  static const char *GNOTE_SERVER_PATH;
+  static const char *GNOTE_SERVER_NAME;
+
+  static IRemoteControl *get_instance();
+
+  static RemoteControl *register_remote(NoteManager & manager);
+};
+
+}
+
+#endif
diff --git a/src/sharp/map.hpp b/src/sharp/map.hpp
index 1276cc8..97ad87b 100644
--- a/src/sharp/map.hpp
+++ b/src/sharp/map.hpp
@@ -28,10 +28,22 @@
 #define __SHARP_MAP_HPP_
 
 #include <list>
+#include <vector>
 #include <map>
 
 namespace sharp {
 
+  /** get all the keys from the map. */
+  template <typename _Map>
+  void map_get_keys(const _Map & m, std::vector<typename _Map::mapped_type> & l) 
+  {
+    l.clear();
+    for(typename _Map::const_iterator iter = m.begin();
+        iter != m.end(); ++iter) {
+      l.push_back(iter->first);
+    }
+  }
+
 
   /** get all the mapped elements from the map. */
   template <typename _Map>
diff --git a/tools/DBusClientTest.py b/tools/DBusClientTest.py
new file mode 100644
index 0000000..22076d7
--- /dev/null
+++ b/tools/DBusClientTest.py
@@ -0,0 +1,53 @@
+import dbus
+import dbus.glib
+import gtk
+import gobject
+import os
+
+GNOTE_DBUS_PATH = "/org/gnome/Gnote/RemoteControl"
+GNOTE_DBUS_IFACE = "org.gnome.Gnote"
+
+def freeze():
+    # Burn some CPU..
+    while True:
+        pass
+
+def crash():
+   # Dump some core
+   os.abort()
+
+class TestApp(object):
+    def __init__(self):
+        self.bus = dbus.SessionBus()
+
+        tomboy_obj = self.bus.get_object(GNOTE_DBUS_IFACE, GNOTE_DBUS_PATH)
+        self.tomboy = dbus.Interface(tomboy_obj, "org.gnome.Gnote.RemoteControl")
+        self.tomboy.connect_to_signal("NoteAdded", self.note_added_cb)
+        self.tomboy.connect_to_signal("NoteSaved", self.note_saved_cb)
+        self.tomboy.connect_to_signal("NoteDeleted", self.note_deleted_cb)
+
+        notif_obj = self.bus.get_object("org.freedesktop.Notifications", "/org/freedesktop/Notifications")
+        self.notify = dbus.Interface(notif_obj, "org.freedesktop.Notifications")
+
+        # Uncomment one of these to test crash behaviour when app is connected to tomboy, but not mid signal
+        #gobject.idle_add(crash)
+        #gobject.idle_add(freeze)
+
+    def note_added_cb(self, uid):
+        self.doMessage("Note added", uid)
+
+    def note_saved_cb(self, uid):
+        self.doMessage("Note saved", uid)
+
+    def note_deleted_cb(self, uid, title):
+        self.doMessage("Note deleted", uid + "\n" + title) 
+
+    def doMessage(self, msg, uid):
+        self.notify.Notify("Conduit Devs Rock", 0, "", msg, uid, [], {}, 3000)
+
+        # Uncomment one of these to test crash behaviour when app is connected to tomboy and mid signal
+        #crash()
+        #freeze()
+
+TestApp()
+gtk.main()



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]