Support some dynamic special phrases
authorPeng Huang <shawn.p.huang@gmail.com>
Wed, 14 Apr 2010 03:04:28 +0000 (11:04 +0800)
committerPeng Huang <shawn.p.huang@gmail.com>
Wed, 14 Apr 2010 03:04:28 +0000 (11:04 +0800)
src/PinyinEditor.cc
src/SpecialTable.cc

index 1e5c1a4..78eca69 100644 (file)
@@ -464,16 +464,7 @@ PinyinEditor::updateLookupTable (void)
     m_lookup_table.setPageSize (Config::pageSize ());
     m_lookup_table.setOrientation (Config::orientation ());
 
-    if (m_selected_special_phrase.empty ()) {
-        for (guint i = 0; i < m_special_phrases.size (); i++) {
-            Text text (m_special_phrases[i].c_str ());
-            text.appendAttribute (IBUS_ATTR_TYPE_FOREGROUND, 0x0000ef00, 0, -1);
-            m_lookup_table.appendCandidate (text);
-        }
-
-        fillLookupTableByPage ();
-    }
-
+    fillLookupTableByPage ();
     if (m_lookup_table.size ()) {
         Editor::updateLookupTable (m_lookup_table, TRUE);
     }
@@ -489,39 +480,43 @@ PinyinEditor::fillLookupTableByPage (void)
         return FALSE;
     }
 
-    guint candidate_nr = m_phrase_editor.candidates ().size ();
-    guint candidate_in_table = m_lookup_table.size () - m_special_phrases.size ();
+    guint filled_nr = m_lookup_table.size ();
+    guint page_size = m_lookup_table.pageSize ();
 
-    if (candidate_nr < candidate_in_table + m_lookup_table.pageSize ()) {
-        if (m_phrase_editor.fillCandidates ()) {
-            candidate_nr = m_phrase_editor.candidates ().size ();
-        }
-    }
+    if (m_special_phrases.size () + m_phrase_editor.candidates ().size () < filled_nr + page_size)
+        m_phrase_editor.fillCandidates ();
 
-    if (candidate_nr == candidate_in_table) {
+    guint need_nr = MIN (page_size, m_special_phrases.size () + m_phrase_editor.candidates ().size () - filled_nr);
+    g_assert (need_nr >= 0);
+    if (need_nr == 0) {
         return FALSE;
     }
 
-    guint end = MIN (candidate_nr, candidate_in_table + m_lookup_table.pageSize ());
-    if (G_LIKELY (m_props.modeSimp () || !Config::tradCandidate ())) {
-        for (guint i = candidate_in_table; i < end; i++) {
-            Text text (m_phrase_editor.candidate (i));
-            if (m_phrase_editor.candidateIsUserPhease (i))
-                text.appendAttribute (IBUS_ATTR_TYPE_FOREGROUND, 0x000000ef, 0, -1);
+    for (guint i = filled_nr; i < filled_nr + need_nr; i++) {
+        if (i < m_special_phrases.size ()) {
+            Text text (m_special_phrases[i].c_str ());
+            text.appendAttribute (IBUS_ATTR_TYPE_FOREGROUND, 0x0000ef00, 0, -1);
             m_lookup_table.appendCandidate (text);
         }
-    }
-    else {
-        for (guint i = candidate_in_table; i < end; i++ ) {
-            m_buffer.truncate (0);
-            SimpTradConverter::simpToTrad (m_phrase_editor.candidate (i), m_buffer);
-            Text text (m_buffer);
-            if (m_phrase_editor.candidateIsUserPhease (i))
-                text.appendAttribute (IBUS_ATTR_TYPE_FOREGROUND, 0x000000ef, 0, -1);
-            m_lookup_table.appendCandidate (text);
+        else {
+            if (G_LIKELY (m_props.modeSimp () || !Config::tradCandidate ())) {
+                Text text (m_phrase_editor.candidate (i - m_special_phrases.size ()));
+                if (m_phrase_editor.candidateIsUserPhease (i - m_special_phrases.size ()))
+                    text.appendAttribute (IBUS_ATTR_TYPE_FOREGROUND, 0x000000ef, 0, -1);
+                m_lookup_table.appendCandidate (text);
+            }
+            else {
+                m_buffer.truncate (0);
+                SimpTradConverter::simpToTrad (m_phrase_editor.candidate (i - m_special_phrases.size ()), m_buffer);
+                Text text (m_buffer);
+                if (m_phrase_editor.candidateIsUserPhease (i - m_special_phrases.size ()))
+                    text.appendAttribute (IBUS_ATTR_TYPE_FOREGROUND, 0x000000ef, 0, -1);
+                m_lookup_table.appendCandidate (text);
+            }
         }
     }
 
+
     return TRUE;
 }
 
index 20e57b5..4bce67b 100644 (file)
@@ -1,3 +1,5 @@
+#include <ctime>
+#include <cstdio>
 #include "SpecialTable.h"
 
 namespace PY {
@@ -7,8 +9,7 @@ SpecialTable SpecialTable::m_instance;
 class StaticPhrase : public SpecialPhrase {
 public:
     StaticPhrase (const std::string &text, guint pos) :
-        SpecialPhrase (pos), m_text (text) {
-    }
+        SpecialPhrase (pos), m_text (text) { }
 
     std::string text (void) { return m_text; }
 
@@ -16,13 +17,97 @@ private:
     std::string m_text;
 };
 
+class DynamicPhrase : public SpecialPhrase {
+public:
+    DynamicPhrase (const std::string &text, guint pos) :
+        SpecialPhrase (pos), m_text (text) { }
+
+    std::string text (void) {
+        std::time (&m_time);
+        std::string result;
+
+        size_t pos = 0;
+        size_t pnext;
+        gint s = 0;
+        while (s != 2) {
+            switch (s) {
+            case 0:
+                pnext = m_text.find ("%(", pos);
+                if (pnext == m_text.npos) {
+                    result += m_text.substr (pos);
+                    s = 2;
+                }
+                else {
+                    result += m_text.substr (pos, pnext - pos);
+                    pos = pnext + 2;
+                    s = 1;
+                }
+                break;
+            case 1:
+                pnext = m_text.find (")", pos);
+                if (pnext == m_text.npos) {
+                    result += "%(";
+                    result += m_text.substr (pos);
+                    s = 2;
+                }
+                else {
+                    result += variable (m_text.substr(pos, pnext - pos));
+                    pos = pnext + 1;
+                    s = 0;
+                }
+                break;
+            default:
+                g_assert_not_reached ();
+            }
+        }
+        return result;
+    }
+
+    const std::string dec (gint d) {
+        char string [32];
+        std::snprintf (string, sizeof (string), "%d", d);
+        return string;
+    }
+
+    const std::string variable (const std::string &name) {
+        if (name == "year") {
+            return dec (localtime (&m_time)->tm_year + 1900);
+        }
+        if (name == "month") {
+            return dec (localtime (&m_time)->tm_mon + 1);
+        }
+        if (name == "day") {
+            return dec (localtime (&m_time)->tm_mday + 1);
+        }
+        if (name == "hour_24") {
+            return dec (localtime (&m_time)->tm_hour + 1);
+        }
+        if (name == "minute") {
+            return dec (localtime (&m_time)->tm_min + 1);
+        }
+        if (name == "second") {
+            return dec (localtime (&m_time)->tm_sec + 1);
+        }
+        return name;
+    }
+
+private:
+    std::string m_text;
+    time_t m_time;
+
+};
+
 SpecialTable::SpecialTable (void)
 {
-    g_debug ("SpecialTable");
-    insert ("xixi", new StaticPhrase ("(*^__^*) 嘻嘻……", 0));
+    insert ("hehe", new StaticPhrase (":-)", 0));
     insert ("haha", new StaticPhrase ("^_^", 0));
     insert ("haha", new StaticPhrase ("o(∩∩)o...哈哈", 1));
+    insert ("xixi", new StaticPhrase ("(*^__^*) 嘻嘻……", 0));
     insert ("bsn", new StaticPhrase ("╭∩╮(︶︿︶)╭∩╮鄙视你!", 0));
+    insert ("rq", new DynamicPhrase ("%(year)年%(month)月%(day)日", 0));
+    insert ("rq", new DynamicPhrase ("%(year)-%(month)-%(day)", 1));
+    insert ("sj", new DynamicPhrase ("%(hour_24)时%(minute)分%(second)秒", 0));
+    insert ("sj", new DynamicPhrase ("%(hour_24):%(minute):%(second)", 1));
 }
 
 static bool