From 8e96ffb74b98b08ac35dcd1c861421c65a55cbe6 Mon Sep 17 00:00:00 2001
From: Mark Tiefenbruck <mark@fluxbox.org>
Date: Fri, 28 Dec 2007 01:19:33 -0800
Subject: moved DelayedCmd from Screen.cc to FbTk/Timer.cc, added it to the
 keys file

---
 ChangeLog              |  4 ++++
 src/FbTk/StringUtil.hh |  8 ++++++++
 src/FbTk/Timer.cc      | 38 +++++++++++++++++++++++++++++++++++++-
 src/FbTk/Timer.hh      | 16 +++++++++++++---
 src/Screen.cc          | 24 +-----------------------
 5 files changed, 63 insertions(+), 27 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 94cd8ce..687ef64 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
  (Format: Year/Month/Day)
 Changes for 1.0.1:
+*07/12/28:
+   * Added new key command :Delay {<command>} [<int>], which runs the command
+     after a delay of <int> microseconds (default is 200 milliseconds) (Mark)
+     FbTk/Timer.cc/hh
 *07/12/25:
    * Updated german translations for maximization menu (thanks Christian Loosli)
      nls/de_*/Translation.m
diff --git a/src/FbTk/StringUtil.hh b/src/FbTk/StringUtil.hh
index bca48bc..416db0d 100644
--- a/src/FbTk/StringUtil.hh
+++ b/src/FbTk/StringUtil.hh
@@ -26,6 +26,8 @@
 
 #include <string>
 
+#include "stringstream.hh"
+
 namespace FbTk {
 
 namespace StringUtil {
@@ -67,6 +69,12 @@ std::string::size_type removeTrailingWhitespace(std::string &str);
 /// splits input at first non-leading whitespace and returns both parts
 void getFirstWord(const std::string &in, std::string &first, std::string &rest);
 
+template <typename T>
+void fromString(const char *in, T &out) {
+    FbTk_istringstream iss(in);
+    iss >> out;
+}
+
 template <typename Container>
 static void stringTokensBetween(Container &container, const std::string &in,
         std::string &rest, char first, char last,
diff --git a/src/FbTk/Timer.cc b/src/FbTk/Timer.cc
index 9492ac6..ff568dc 100644
--- a/src/FbTk/Timer.cc
+++ b/src/FbTk/Timer.cc
@@ -24,7 +24,8 @@
 
 #include "Timer.hh"
 
-#include "Command.hh"
+#include "ObjectRegistry.hh"
+#include "StringUtil.hh"
 
 //use GNU extensions
 #ifndef	_GNU_SOURCE
@@ -246,6 +247,41 @@ void Timer::addTimer(Timer *timer) {
 
 }
 
+Command *DelayedCmd::parse(const std::string &command,
+                           const std::string &args, bool trusted) {
+
+    std::string cmd_str;
+    int err = StringUtil::getStringBetween(cmd_str, args.c_str(), '{', '}');
+    if (err == 0)
+        return 0;
+
+    RefCount<Command> cmd(ObjectRegistry<Command>::instance().parse(cmd_str, trusted));
+    if (*cmd == 0)
+        return 0;
+
+    int delay = 200000;
+    StringUtil::fromString<int>(args.c_str() + err, delay);
+
+    return new DelayedCmd(cmd, delay);
+}
+
+REGISTER_OBJECT_PARSER(delay, DelayedCmd::parse, Command);
+
+DelayedCmd::DelayedCmd(RefCount<Command> &cmd, unsigned int timeout) {
+    timeval to; // defaults to 200ms
+    to.tv_sec = timeout/1000000;
+    to.tv_usec = timeout % 1000000;
+    m_timer.setTimeout(to);
+    m_timer.setCommand(cmd);
+    m_timer.fireOnce(true);
+}
+
+void DelayedCmd::execute() {
+    if (m_timer.isTiming())
+        m_timer.stop();
+    m_timer.start();
+}
+
 void Timer::removeTimer(Timer *timer) {
     assert(timer);
     m_timerlist.remove(timer);
diff --git a/src/FbTk/Timer.hh b/src/FbTk/Timer.hh
index bd55435..4b5be95 100644
--- a/src/FbTk/Timer.hh
+++ b/src/FbTk/Timer.hh
@@ -26,6 +26,7 @@
 #define	 FBTK_TIMER_HH
 
 #include "RefCount.hh"
+#include "Command.hh"
 
 #ifdef HAVE_CTIME
   #include <ctime>
@@ -33,6 +34,7 @@
   #include <time.h>
 #endif
 #include <list>
+#include <string>
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -49,8 +51,6 @@
 
 namespace FbTk {
 
-class Command;
-
 /**
 	Handles Timeout
 */
@@ -107,7 +107,17 @@ private:
     timeval m_timeout; ///< time length
 };
 
+/// executes a command after a specified timeout
+class DelayedCmd: public Command {
+public:
+    DelayedCmd(RefCount<Command> &cmd, unsigned int timeout = 200000);
+    void execute();
+    static Command *parse(const std::string &command,
+                          const std::string &args, bool trusted);
+private:
+    Timer m_timer;
+};
+
 } // end namespace FbTk
 
 #endif // FBTK_TIMER_HH
-
diff --git a/src/Screen.cc b/src/Screen.cc
index a09f4d1..2d214eb 100644
--- a/src/Screen.cc
+++ b/src/Screen.cc
@@ -196,28 +196,6 @@ private:
     FbWinFrame::TabPlacement m_place;
 };
 
-// this might be useful elsewhere, but I'll leave it here for now
-class DelayedCmd: public FbTk::Command {
-public:
-    DelayedCmd(FbTk::RefCount<FbTk::Command> &cmd) {
-        timeval to;
-        to.tv_sec = 0;
-        to.tv_usec = 500000; // 1/2 second
-        m_timer.setTimeout(to);
-        m_timer.setCommand(cmd);
-        m_timer.fireOnce(true);
-    }
-    void execute() {
-        // if it's already started, restart it; otherwise, just start it
-        // we want this to execute 1/2 second after the last click
-        if (m_timer.isTiming())
-            m_timer.stop();
-        m_timer.start();
-    }
-private:
-    FbTk::Timer m_timer;
-};
-
 } // end anonymous namespace
 
 
@@ -1724,7 +1702,7 @@ void BScreen::setupConfigmenu(FbTk::Menu &menu) {
         // in order to save system resources, don't save or reconfigure alpha
         // settings until after the user is done changing them
         FbTk::RefCount<FbTk::Command> delayed_save_and_reconf(
-            new ::DelayedCmd(save_and_reconfigure));
+            new FbTk::DelayedCmd(save_and_reconfigure));
 
         FbTk::MenuItem *focused_alpha_item =
             new FbTk::IntMenuItem(_FB_XTEXT(Configmenu, FocusedAlpha,
-- 
cgit v0.11.2