Update of /cvsroot/mahogany/M/src/gui
In directory usw-pr-cvs1:/tmp/cvs-serv15792/src/gui

Modified Files:
        wxMApp.cpp wxOptionsDlg.cpp 
Log Message:
implemented "alweays run only one instance" option and the remote control:
launching Mahogany will simply pass control and the command line options to
the previous instance, if any (and if this option is on)


Index: wxMApp.cpp
===================================================================
RCS file: /cvsroot/mahogany/M/src/gui/wxMApp.cpp,v
retrieving revision 1.227
retrieving revision 1.228
diff -b -u -2 -r1.227 -r1.228
--- wxMApp.cpp  29 Mar 2002 20:42:22 -0000      1.227
+++ wxMApp.cpp  13 Apr 2002 23:34:31 -0000      1.228
@@ -1,10 +1,14 @@
-/*-*- c++ -*-********************************************************
- * wxMApp class: do all GUI specific  application stuff             *
- *                                                                  *
- * (C) 1997-2000 by Karsten Ball�der ([EMAIL PROTECTED])         *
- *                                                                  *
- * $Id$
- *
- *******************************************************************/
+///////////////////////////////////////////////////////////////////////////////
+// Project:     M - cross platform e-mail GUI client
+// File name:   gui/wxMApp.cpp - GUI-specific part of application logic
+// Purpose:     program application, startup, non-portable hooks to implement
+//              the functionality needed by MApplication, also log window impl
+// Author:      Karsten Ball�der, Vadim Zeitlin
+// Modified by:
+// Created:     1997
+// CVS-ID:      $Id$
+// Copyright:   (c) 1997-2002 M-Team
+// Licence:     M license
+///////////////////////////////////////////////////////////////////////////////
 
 // ============================================================================
@@ -52,4 +56,20 @@
 #include <wx/fontmap.h>
 #include <wx/encconv.h>
+#include <wx/tokenzr.h>
+
+#include <wx/snglinst.h>
+#ifdef OS_WIN
+   #define wxConnection    wxDDEConnection
+   #define wxServer        wxDDEServer
+   #define wxClient        wxDDEClient
+
+   #include <wx/dde.h>
+#else // !Windows
+   #define wxConnection    wxTCPConnection
+   #define wxServer        wxTCPServer
+   #define wxClient        wxTCPClient
+
+   #include <wx/sckipc.h>
+#endif // Windows/!Windows
 
 #include "MObject.h"
@@ -448,6 +468,14 @@
 #endif // USE_DIALUP
 
+   m_PrintData = NULL;
+   m_PageSetupData = NULL;
+
    m_logWindow = NULL;
    m_logChain = NULL;
+
+   m_snglInstChecker = NULL;
+   m_serverIPC = NULL;
+
+   m_topLevelFrame = NULL;
 }
 
@@ -692,8 +720,24 @@
 wxMApp::OnInit()
 {
+   // in release build we handle any exceptions we generate (i.e. crashes)
+   // ourselves
 #ifndef DEBUG
    wxHandleFatalExceptions();
 #endif
 
+   // create a semaphore indicating that we're running - or check if another
+   // copy already is
+   m_snglInstChecker = new wxSingleInstanceChecker;
+
+   // note that we can't create the lock file in ~/.M because the directory
+   // might not have been created yet...
+   if ( !m_snglInstChecker->Create(".mahogany.lock") )
+   {
+      // this message is in English because translations were not loaded yet as
+      // the locale hadn't been set
+      wxLogWarning("Mahogany will not be able to detect if any other "
+                   "program instances are running.");
+   }
+
 #if wxCHECK_VERSION(2, 3, 2)
    // parse our command line options inside OnInit()
@@ -707,6 +751,4 @@
 #endif // OS_WIN
 
-   m_topLevelFrame = NULL;
-
 #ifdef USE_I18N
    // Set up locale first, so everything is in the right language.
@@ -823,7 +865,4 @@
    wxFileSystem::AddHandler(new wxMemoryFSHandler);
 
-   m_PrintData = NULL;
-   m_PageSetupData = NULL;
-
    // this is necessary to avoid that the app closes automatically when we're
    // run for the first time and show a modal dialog before opening the main
@@ -945,4 +984,14 @@
 int wxMApp::OnExit()
 {
+   // we won't be able to do anything more (i.e. another program copy can't ask
+   // us to execute any actions for it) so it's as if we were already not
+   // running at all
+   delete m_snglInstChecker;
+   m_snglInstChecker = NULL;
+
+   // no more IPC for us neither
+   delete m_serverIPC;
+   m_serverIPC = NULL;
+
    // disable timers for autosave and mail collection, won't need them any more
    StopTimer(Timer_Autosave);
@@ -2133,4 +2182,190 @@
 
    // we have either the requested encoding or an equivalent one
+   return true;
+}
+
+// ============================================================================
+// IPC and multiple program instances handling
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// IPC constants
+// ----------------------------------------------------------------------------
+
+#define IPC_SOCKET "/tmp/.mahogany.ipc"
+#define IPC_TOPIC  "MRemote"
+
+// ----------------------------------------------------------------------------
+// IPC classes
+// ----------------------------------------------------------------------------
+
+class MAppIPCConnection : public wxConnection
+{
+public:
+   MAppIPCConnection()
+      : wxConnection(m_buffer, WXSIZEOF(m_buffer))
+   {
+   }
+
+   virtual bool OnExecute(const wxString& WXUNUSED(topic),
+                          char *data,
+                          int WXUNUSED(size),
+                          wxIPCFormat WXUNUSED(format))
+   {
+      return wxGetApp().OnRemoteRequest(data);
+   }
+
+private:
+   char m_buffer[4096];
+};
+
+class MAppIPCServer : public wxServer
+{
+public:
+   virtual wxConnectionBase *OnAcceptConnection(const wxString& topic)
+   {
+      if ( topic != IPC_TOPIC )
+         return NULL;
+
+      return new MAppIPCConnection;
+   }
+};
+
+// ----------------------------------------------------------------------------
+// wxMApp IPC methods
+// ----------------------------------------------------------------------------
+
+bool wxMApp::OnRemoteRequest(const char *request)
+{
+   CmdLineOptions cmdLineOpts;
+   if ( !cmdLineOpts.FromString(request) )
+   {
+      wxLogError(_("Ignoring unrecognized remote request '%s'."),
+                 request);
+      return false;
+   }
+
+   if ( !ProcessSendCmdLineOptions(cmdLineOpts) )
+   {
+      // no composer windows were opened, bring the main frame to top to ensure
+      // that we have focus
+      if ( m_topLevelFrame )
+      {
+         m_topLevelFrame->Raise();
+      }
+   }
+
+   return true;
+}
+
+bool wxMApp::IsAnotherRunning() const
+{
+   // it's too early or too late to call us, normally we shouldn't try to do it
+   // then, i.e. this indicates an error in the caller logic
+   CHECK( m_snglInstChecker, false, "IsAnotherRunning() shouldn't be called" );
+
+   return m_snglInstChecker->IsAnotherRunning();
+}
+
+bool wxMApp::SetupRemoteCallServer()
+{
+   ASSERT_MSG( !m_serverIPC, "SetupRemoteCallServer() called twice?" );
+
+   m_serverIPC = new MAppIPCServer;
+   if ( !m_serverIPC->Create(IPC_SOCKET) )
+   {
+      delete m_serverIPC;
+      m_serverIPC = NULL;
+
+      return false;
+   }
+
+   return true;
+}
+
+bool wxMApp::CallAnother()
+{
+   CHECK( IsAnotherRunning(), false,
+          "can't call another copy when it doesn't run!" );
+
+   CHECK( m_cmdLineOptions, false,
+          "we need to parse the options before doing the remote call" );
+
+   wxClient client;
+   wxConnectionBase *conn = client.MakeConnection("", IPC_SOCKET, IPC_TOPIC);
+   if ( !conn )
+   {
+      // failed to connect to server at all
+      return false;
+   }
+
+   // pass m_cmdLineOptions to the other process
+   bool ok = conn->Execute(m_cmdLineOptions->ToString());
+
+   delete conn;
+
+   return ok;
+}
+
+// ----------------------------------------------------------------------------
+// CmdLineOptions
+// ----------------------------------------------------------------------------
+
+// the char to use as separator: don't use NUL as I'm not sure that wxIPC
+// code handlers it correctly
+#define CMD_LINE_OPTS_SEP '\1'
+
+// the version of the CmdLineOptions::ToString() format
+#define CMD_LINE_OPTS_VERSION 1.0
+
+// the positions of the individual members in the string produced by ToString()
+enum
+{
+   CmdLineOptions_Version,
+   CmdLineOptions_Config,
+   CmdLineOptions_Bcc,
+   CmdLineOptions_Body,
+   CmdLineOptions_Cc,
+   CmdLineOptions_Newsgroups,
+   CmdLineOptions_Subject,
+   CmdLineOptions_To,
+   CmdLineOptions_Max
+};
+
+String CmdLineOptions::ToString() const
+{
+   // only serialize the "interesting" options
+   String s;
+   s << s.Format("%f", CMD_LINE_OPTS_VERSION) << CMD_LINE_OPTS_SEP
+     << configFile << CMD_LINE_OPTS_SEP
+     << composer.bcc << CMD_LINE_OPTS_SEP
+     << composer.body << CMD_LINE_OPTS_SEP
+     << composer.cc << CMD_LINE_OPTS_SEP
+     << composer.newsgroups << CMD_LINE_OPTS_SEP
+     << composer.subject << CMD_LINE_OPTS_SEP
+     << composer.to;
+
+   return s;
+}
+
+bool CmdLineOptions::FromString(const String& s)
+{
+   wxArrayString
+      tokens = wxStringTokenize(s, CMD_LINE_OPTS_SEP, wxTOKEN_RET_EMPTY_ALL);
+
+   if ( tokens.GetCount() != CmdLineOptions_Max )
+      return false;
+
+   if ( atof(tokens[CmdLineOptions_Version]) != CMD_LINE_OPTS_VERSION )
+      return false;
+
+   configFile = tokens[CmdLineOptions_Config];
+   composer.bcc = tokens[CmdLineOptions_Bcc];
+   composer.body = tokens[CmdLineOptions_Body];
+   composer.cc = tokens[CmdLineOptions_Cc];
+   composer.newsgroups = tokens[CmdLineOptions_Newsgroups];
+   composer.subject = tokens[CmdLineOptions_Subject];
+   composer.to = tokens[CmdLineOptions_To];
+
    return true;
 }

Index: wxOptionsDlg.cpp
===================================================================
RCS file: /cvsroot/mahogany/M/src/gui/wxOptionsDlg.cpp,v
retrieving revision 1.325
retrieving revision 1.326
diff -b -u -2 -r1.325 -r1.326
--- wxOptionsDlg.cpp    28 Mar 2002 21:07:03 -0000      1.325
+++ wxOptionsDlg.cpp    13 Apr 2002 23:34:34 -0000      1.326
@@ -499,4 +499,5 @@
    ConfigField_AutosaveDelay,
    ConfigField_ConfirmExit,
+   ConfigField_RunOneOnly,
    ConfigField_HelpDir,
 #ifdef USE_SSL
@@ -1481,4 +1482,5 @@
    { gettext_noop("&Autosave delay"),              Field_Number, -1                   
   },
    { gettext_noop("Confirm &exit"),                Field_Bool | Field_Restart, -1     
                },
+   { gettext_noop("Always run only &one instance"),Field_Bool | Field_Restart, -1     
+                },
    { gettext_noop("Directory with the help files"), Field_Dir, -1 },
 
@@ -1886,4 +1888,5 @@
    CONFIG_ENTRY(MP_AUTOSAVEDELAY),
    CONFIG_ENTRY(MP_CONFIRMEXIT),
+   CONFIG_ENTRY(MP_RUNONEONLY),
    CONFIG_ENTRY(MP_HELPDIR),
 #ifdef USE_SSL


_______________________________________________
Mahogany-cvsupdates mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/mahogany-cvsupdates

Reply via email to