Imported Upstream version 0.2.85+hg33 upstream/0.2.85+hg33
authorJulien Valroff <julien@kirya.net>
Sun, 6 Mar 2011 15:54:28 +0000 (16:54 +0100)
committerJulien Valroff <julien@kirya.net>
Sun, 6 Mar 2011 15:54:28 +0000 (16:54 +0100)
24 files changed:
CMakeLists.txt
config.h.in
img/group.svg [new file with mode: 0644]
src/account_abstract.vala
src/avatar.vala
src/content_view.vala [deleted file]
src/identica_account.vala
src/identica_create_dialog.vala
src/identica_stream_group.vala [new file with mode: 0644]
src/img_cache.vala
src/main_window.vala
src/pino_enums.vala
src/status_delegate.vala
src/streams_types.vala
src/template.vala [deleted file]
src/thumb.vala [new file with mode: 0644]
src/tree_widget.vala
src/twitter_account.vala
src/twitter_create_dialog.vala
src/twitter_stream_abstract.vala
src/twitter_stream_mentions.vala
src/twitter_stream_public.vala
src/twitter_stream_search.vala
src/vapi/config.vapi

index 4df6e0f..11880d8 100644 (file)
@@ -187,6 +187,7 @@ set(pino_IMAGES
   img/service-identica.png
   img/mentions_fresh.svg
   img/mentions.svg
+  img/group.svg
   img/reply.png
   img/timeline_fresh.svg
   img/timeline.svg
index 45a5db7..801bc05 100644 (file)
@@ -19,6 +19,7 @@
 #define LOGO_PATH "${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/scalable/apps/pino.svg"
 #define LOGO_FRESH_PATH "${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/scalable/apps/pino_fresh.svg"
 #define MENTIONS_PATH "${CMAKE_INSTALL_PREFIX}/share/pino/icons/mentions.svg"
+#define GROUP_PATH "${CMAKE_INSTALL_PREFIX}/share/pino/icons/group.svg"
 #define MENTIONS_FRESH_PATH "${CMAKE_INSTALL_PREFIX}/share/pino/icons/mentions_fresh.svg"
 #define TIMELINE_PATH "${CMAKE_INSTALL_PREFIX}/share/pino/icons/timeline.svg"
 #define TIMELINE_FRESH_PATH "${CMAKE_INSTALL_PREFIX}/share/pino/icons/timeline_fresh.svg"
diff --git a/img/group.svg b/img/group.svg
new file mode 100644 (file)
index 0000000..dd5e7ff
--- /dev/null
@@ -0,0 +1,275 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   version="1.0"
+   width="48"
+   height="48"
+   id="svg2655">
+  <defs
+     id="defs2657">
+    <linearGradient
+       id="linearGradient3484-169">
+      <stop
+         id="stop2489"
+         style="stop-color:#bdbdbd;stop-opacity:1"
+         offset="0" />
+      <stop
+         id="stop2491"
+         style="stop-color:#d0d0d0;stop-opacity:1"
+         offset="1" />
+    </linearGradient>
+    <radialGradient
+       cx="3"
+       cy="5.01718"
+       r="21"
+       fx="3"
+       fy="5.01718"
+       id="radialGradient2788-375"
+       xlink:href="#linearGradient3484-169"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(-1.274898e-8,1.7142916,-2.159331,-1.4599595e-8,12.809361,2.8570011)" />
+    <linearGradient
+       id="linearGradient6404-919">
+      <stop
+         id="stop2483"
+         style="stop-color:#f9f9f9;stop-opacity:1"
+         offset="0" />
+      <stop
+         id="stop2485"
+         style="stop-color:#c9c9c9;stop-opacity:1"
+         offset="1" />
+    </linearGradient>
+    <linearGradient
+       x1="62.988873"
+       y1="13.182598"
+       x2="62.988873"
+       y2="16.19013"
+       id="linearGradient2786-306"
+       xlink:href="#linearGradient6404-919"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-50.940898,0)" />
+    <linearGradient
+       id="linearGradient5060-820-843">
+      <stop
+         id="stop2509"
+         style="stop-color:black;stop-opacity:1"
+         offset="0" />
+      <stop
+         id="stop2511"
+         style="stop-color:black;stop-opacity:0"
+         offset="1" />
+    </linearGradient>
+    <radialGradient
+       cx="605.71429"
+       cy="486.64789"
+       r="117.14286"
+       fx="605.71429"
+       fy="486.64789"
+       id="radialGradient7600-312-677"
+       xlink:href="#linearGradient5060-820-843"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(-0.03212956,0,0,0.03705882,23.363215,25.412461)" />
+    <linearGradient
+       id="linearGradient5060-179-146">
+      <stop
+         id="stop2503"
+         style="stop-color:black;stop-opacity:1"
+         offset="0" />
+      <stop
+         id="stop2505"
+         style="stop-color:black;stop-opacity:0"
+         offset="1" />
+    </linearGradient>
+    <radialGradient
+       cx="605.71429"
+       cy="486.64789"
+       r="117.14286"
+       fx="605.71429"
+       fy="486.64789"
+       id="radialGradient7598-526-522"
+       xlink:href="#linearGradient5060-179-146"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.03212956,0,0,0.03705882,24.636785,25.412461)" />
+    <linearGradient
+       id="linearGradient5048-585-940">
+      <stop
+         id="stop2495"
+         style="stop-color:black;stop-opacity:0"
+         offset="0" />
+      <stop
+         id="stop2497"
+         style="stop-color:black;stop-opacity:1"
+         offset="0.5" />
+      <stop
+         id="stop2499"
+         style="stop-color:black;stop-opacity:0"
+         offset="1" />
+    </linearGradient>
+    <linearGradient
+       x1="302.85715"
+       y1="366.64789"
+       x2="302.85715"
+       y2="609.50507"
+       id="linearGradient7596-975-255"
+       xlink:href="#linearGradient5048-585-940"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.08284024,0,0,0.03705882,-5.9408285,25.412461)" />
+    <linearGradient
+       id="linearGradient3390-178-986-453-929">
+      <stop
+         id="stop2521"
+         style="stop-color:#666;stop-opacity:1"
+         offset="0" />
+      <stop
+         id="stop2523"
+         style="stop-color:gray;stop-opacity:1"
+         offset="1" />
+    </linearGradient>
+    <linearGradient
+       x1="82.453476"
+       y1="45.114193"
+       x2="65.340263"
+       y2="15.943953"
+       id="linearGradient2779-731"
+       xlink:href="#linearGradient3390-178-986-453-929"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-53.765393,-0.1141929)" />
+    <linearGradient
+       id="linearGradient7012-661-145-733-759-865-745-661-970-94-935">
+      <stop
+         id="stop2515"
+         style="stop-color:#a8a8a8;stop-opacity:1"
+         offset="0" />
+      <stop
+         id="stop2517"
+         style="stop-color:#818181;stop-opacity:1"
+         offset="1" />
+    </linearGradient>
+    <radialGradient
+       cx="63.969177"
+       cy="14.113381"
+       r="23.097054"
+       fx="63.969177"
+       fy="14.113381"
+       id="radialGradient2777-429"
+       xlink:href="#linearGradient7012-661-145-733-759-865-745-661-970-94-935"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.5646925,-9.5143002e-8,6.1772287e-8,1.015888,-86.212573,8.1461173)" />
+    <linearGradient
+       id="linearGradient6129-963-697-142-998-580-273-793">
+      <stop
+         id="stop2527"
+         style="stop-color:#0a0a0a;stop-opacity:0.498"
+         offset="0" />
+      <stop
+         id="stop2529"
+         style="stop-color:#0a0a0a;stop-opacity:0"
+         offset="1" />
+    </linearGradient>
+    <linearGradient
+       x1="22.934725"
+       y1="49.629246"
+       x2="22.809399"
+       y2="36.657963"
+       id="linearGradient2774-916"
+       xlink:href="#linearGradient6129-963-697-142-998-580-273-793"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.1446925,0,0,0.9977536,-3.4661413,1.0988425)" />
+    <linearGradient
+       id="linearGradient6087-437-184-795-110-662-495-280">
+      <stop
+         id="stop2533"
+         style="stop-color:white;stop-opacity:0.40000001"
+         offset="0" />
+      <stop
+         id="stop2535"
+         style="stop-color:white;stop-opacity:0"
+         offset="1" />
+    </linearGradient>
+    <radialGradient
+       cx="7.2646537"
+       cy="8.3021259"
+       r="20.979567"
+       fx="7.2646537"
+       fy="8.3021259"
+       id="radialGradient2771-545"
+       xlink:href="#linearGradient6087-437-184-795-110-662-495-280"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0,1.2079744,-1.6271642,0,26.371748,8.2664685)" />
+    <linearGradient
+       id="linearGradient8265-821-176-38-919-66-249-54">
+      <stop
+         id="stop2539"
+         style="stop-color:white;stop-opacity:0.27450982"
+         offset="0" />
+      <stop
+         id="stop2541"
+         style="stop-color:white;stop-opacity:0.07843138"
+         offset="1" />
+    </linearGradient>
+    <linearGradient
+       x1="11.566265"
+       y1="22.292103"
+       x2="15.214532"
+       y2="33.95525"
+       id="linearGradient2768-174"
+       xlink:href="#linearGradient8265-821-176-38-919-66-249-54"
+       gradientUnits="userSpaceOnUse" />
+  </defs>
+  <g
+     id="layer1">
+    <path
+       d="m 3.5062498,8.4999995 c -0.690271,0.00767 -1.0004418,0.3421461 -1.0004418,1 0,5.5144545 0.026278,9.7395765 -0.00581,14.7504305 1.4354706,0 42.999998,-3.699732 42.999998,-5.292264 l 0,-6.451519 c 0,-0.657853 -0.554204,-1.007671 -1.244479,-1 l -20.255519,0 c -2.047483,0 -3.498891,-3.0066475 -5,-3.0066475 l -15.4937503,0 z"
+       id="path3468"
+       style="fill:url(#linearGradient2786-306);fill-opacity:1;stroke:url(#radialGradient2788-375);stroke-width:1.00000012;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline" />
+    <g
+       transform="matrix(0.9583333,0,0,0.6666667,1.0000008,15)"
+       id="g7591"
+       style="opacity:0.4">
+      <rect
+         width="40"
+         height="9"
+         x="4"
+         y="39"
+         id="rect4173"
+         style="fill:url(#linearGradient7596-975-255);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible" />
+      <path
+         d="m 44,39.00031 c 0,0 0,8.999504 0,8.999504 1.654593,0.01694 4.000001,-2.016333 4,-4.500331 0,-2.483999 -1.846402,-4.499173 -4,-4.499173 z"
+         id="path5058"
+         style="fill:url(#radialGradient7598-526-522);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible" />
+      <path
+         d="m 4,39.00031 c 0,0 0,8.999504 0,8.999504 C 2.3454068,48.016755 0,45.983481 0,43.499483 0,41.015484 1.8464008,39.00031 4,39.00031 z"
+         id="path5018"
+         style="fill:url(#radialGradient7600-312-677);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible" />
+    </g>
+    <path
+       d="m 2.1628556,16.525193 c -1.072707,0.123694 -0.49977,1.402118 -0.585297,2.121012 0.392532,8.47009 0.788932,16.769455 1.179047,25.239602 0.341836,0.965693 1.594435,0.47116 2.388117,0.59375 13.1935444,0 26.3870894,0 39.5806354,0 1.08938,-0.106651 0.63646,-1.407681 0.7897,-2.152262 0.39254,-8.47009 0.78894,-16.769455 1.17905,-25.239602 -0.25117,-0.954289 -1.51951,-0.424014 -2.263123,-0.5625 -14.089374,0 -28.178751,0 -42.2681294,0 z"
+       id="path3388"
+       style="fill:url(#radialGradient2777-429);fill-opacity:1;stroke:url(#linearGradient2779-731);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0" />
+    <path
+       d="m 2.0582428,16.065146 43.8964752,4.03e-4 c 0.63416,0 1.045155,0.444611 1.045155,0.997367 L 45.755637,44.002247 C 45.755637,44.555002 45.245105,45 44.610947,45 L 3.4020122,45 C 2.7678523,45 2.2573195,44.555002 2.2573195,44.002247 L 1.0130886,17.0629 c 0,-0.552757 0.4109943,-0.997754 1.0451542,-0.997754 z"
+       id="path6127"
+       style="opacity:0.4;fill:url(#linearGradient2774-916);fill-opacity:1;stroke:none" />
+    <path
+       d="m 46.5,17.5 c -13.53125,0 -30.46875,0 -44,0 0.3854167,8.177083 0.7708333,16.354167 1.15625,24.53125"
+       id="path2435"
+       style="fill:none;stroke:url(#radialGradient2771-545);stroke-width:0.99999976;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+    <path
+       d="M 45.75,16 C 31.20041,16.073348 16.645416,15.978851 2.09375,16 0.28698984,16.411117 1.2593433,18.46661 1.1213236,19.771525 1.3433531,23.934872 1.4443903,28.116464 1.7417851,32.268407 16.742298,29.905609 31.66833,27.661153 46.40625,25.21875 47.187241,22.632172 47.193628,19.548156 47.063607,16.789526 46.834471,16.284964 46.276599,15.988682 45.75,16 z"
+       id="path3455"
+       style="fill:url(#linearGradient2768-174);fill-opacity:1;stroke:none" />
+    <rect
+       width="13"
+       height="2"
+       rx="1"
+       ry="1"
+       x="5"
+       y="10"
+       id="rect3562"
+       style="fill:#b0b0b0;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible;enable-background:accumulate" />
+  </g>
+</svg>
index 1bdaf20..ef72740 100644 (file)
@@ -37,7 +37,7 @@ public abstract class AAccount : GLib.Object {
        public abstract StatusMenuItems[] status_popup_items {owned get;}
        
        /** All streams wich can be added to this account */
-       public abstract HashMap<StreamEnum, GLib.Type> avaliable_streams {owned get;}
+       public abstract HashMap<StreamEnum, GLib.Type> avaliable_streams();// {owned get;}
 
        /** Default number of streams for account */
        protected abstract StreamEnum[] default_streams {owned get;}
@@ -118,7 +118,7 @@ public abstract class AAccount : GLib.Object {
                HashMap<string, string>? props = null) {
                
                Type? stype = null;
-               stype = avaliable_streams.get(stream_type);//streams_types.get_type_by_string(state.stream_type);
+               stype = avaliable_streams().get(stream_type);//streams_types.get_type_by_string(state.stream_type);
                        
                if(stype == null) {
                        warning("Stream type is not supported");
@@ -371,6 +371,8 @@ public abstract class AAccount : GLib.Object {
        
        public virtual void go_hashtag(string tag) {}
        
+       public virtual void go_group(string group_name) {}
+       
        /** Virtual context menu actions */
        protected virtual void menu_do_reply(Status status) {}
        
index 26490d4..4a1ebf4 100644 (file)
@@ -10,6 +10,8 @@ public class Avatar : Image {
        private const double M_PI = 3.1415926535;
        private const double MAX_RGB = (double) uint16.MAX;
        
+       private unowned Thread? thread = null;
+       
        public Avatar() {
                GLib.Object();
        }
@@ -17,6 +19,9 @@ public class Avatar : Image {
        public Avatar.from_url(string url, int pix_size) {
                this.url = url;
                this.pix_size = pix_size;
+               
+               set_size_request(pix_size, pix_size);
+               
                load_pic();
        }
        
@@ -96,7 +101,7 @@ public class Avatar : Image {
     
     public void load_pic() {
                try {
-                       unowned Thread thread = Thread.create<void*>(load_pic_thread, true);
+                       thread = Thread.create<void*>(load_pic_thread, true);
                } catch(GLib.Error e) {
                        debug(e.message); //TODO
                }
@@ -104,10 +109,12 @@ public class Avatar : Image {
        
        private void* load_pic_thread() {
                string? img_path = img_cache.download(url);
-               
+               debug("something loaded");
                if(img_path != null) {
                        //debug("%s, %s", img_path, status.user.pic);
+                       
                        Idle.add(() => {
+                               thread.join();
                                try {
                                        this.set_file_name(img_path);
                                } catch(GLib.Error e) {
diff --git a/src/content_view.vala b/src/content_view.vala
deleted file mode 100644 (file)
index d9f3986..0000000
+++ /dev/null
@@ -1,186 +0,0 @@
-using Gtk;
-using WebKit;
-using Gee;
-
-public class ContentView : GLib.Object {
-       
-       private WebView? view;
-       private ScrolledWindow scroll;
-       protected VScrollbar slider;
-       public Frame frame;
-       private Accounts accounts;
-       private VisualStyle visual_style;
-       private Template tpl;
-       
-       private HashMap<string, string> content_map;
-       private HashMap<string, string> scroll_map;
-       
-       private string current_stream = "";
-       
-       private bool not_more = false;
-       
-       public ContentView(Accounts accounts, VisualStyle visual_style) {
-               view = new WebView();
-               view.set_size_request(250, 350);
-               view.navigation_policy_decision_requested.connect(event_route);
-               view.settings.enable_default_context_menu = false;
-               
-               scroll = new ScrolledWindow(null, null);
-               scroll.set_policy(PolicyType.AUTOMATIC, PolicyType.AUTOMATIC);
-               scroll.add(view);
-               
-               slider = (VScrollbar)scroll.get_vscrollbar();
-               
-               frame = new Frame(null);
-               frame.add(scroll);
-               
-               content_map = new HashMap<string, string>(str_hash, str_equal);
-               scroll_map = new HashMap<string, string>(str_hash, str_equal);
-               
-               view.load_finished.connect((f) => {
-                       update_style();
-                       
-               });
-               
-               //when scroll to the bottom
-               slider.value_changed.connect(slider_move);
-               
-               this.accounts = accounts;
-               this.visual_style = visual_style;
-               this.visual_style.changed.connect(update_style);
-               
-               tpl = new Template(this.visual_style);
-               
-               view.load_string(tpl.render_body(), "text/html", "utf8", "file:///");
-               
-               this.accounts.stream_was_updated.connect(generate_list);
-               
-               this.accounts.insert_reply.connect(insert_reply);
-       }
-       
-       private void insert_reply(string stream_hash, string status_id, Status status) {
-               if(stream_hash != current_stream) {
-                       debug("not this stream");
-                       return;
-               }
-               
-               AStream? stream = accounts.stream_from_hash(stream_hash);
-               if(stream == null) {
-                       debug("can't find this stream");
-                       return;
-               }
-               
-               string result = tpl.render_small_status(status, stream);
-               result = result.replace("'", "\\'");
-               debug(result);
-               
-               string script = """insert_reply('%s', '%s');""".printf(status_id, result);
-               script = script.replace("\n", " ");
-               view.execute_script(script);
-       }
-       
-       private void slider_move() {
-               double max = slider.adjustment.upper;
-               double current = slider.get_value();
-               double scroll_size = slider.adjustment.page_size;
-               
-               if(!not_more && current != 0 && current + scroll_size == max) {
-                       debug("need more");
-                       AStream? stream = accounts.stream_from_hash(current_stream);
-                       
-                       if(stream == null)
-                               return;
-                       
-                       stream.menu_more();
-               }
-       }
-       
-       private void generate_list(string hash, AStream stream) {
-               debug(hash);
-               
-               if(stream.statuses.size == 0 && stream.statuses_fresh.size == 0)
-                       return;
-               
-               string data = tpl.stream_to_list(stream, hash);
-               data = data.replace("\n", " ");
-               data = data.replace("'", "\\'");
-               content_map.set(hash, data);
-               
-               if(hash == current_stream)
-                       set_current_list(hash);
-       }
-       
-       public void set_current_list(string? hash) {
-               if(hash == null)
-                       return;
-               
-               not_more = true;
-               
-               if(current_stream != "")
-                       scroll_map[current_stream] = slider.get_value().to_string();
-               
-               current_stream = hash;
-               
-               if(content_map.has_key(hash)) {
-                       //view.load_string(content_map.get(hash), "text/html", "utf8", "file:///");
-                       load_content(content_map.get(hash));
-               } else {
-                       load_content("empty");
-               }
-               
-               if(scroll_map.has_key(current_stream)) {
-                       slider.set_value(scroll_map[current_stream].to_double());
-               }
-               
-               not_more = false;
-       }
-       
-       protected void load_content(owned string data) {
-               string script = """set_content('%s');""".printf(data);
-               view.execute_script(script);
-       }
-       
-       private void update_style() {
-               view.settings.set_property("default-font-size", visual_style.font_size);
-               view.settings.set_property("default-font-family", visual_style.font_family);
-               
-               string header = tpl.render_header();
-               
-               /*
-               accounts.update_all_streams();
-               
-               set_current_list(current_stream);
-               */
-               
-               string script = """change_style("%s");""".printf(header);
-               script = script.replace("\n", " ");
-               view.execute_script(script);
-               
-               debug("style changed");
-       }
-       
-       private bool event_route(WebFrame p0, NetworkRequest request,
-               WebNavigationAction action, WebPolicyDecision decision) {
-               if(request.uri == "")
-                       return false;
-               
-               string prot = request.uri.split("://")[0];
-               string path = request.uri.split("://")[1];
-               debug(prot);
-               debug(path);
-               
-               if(prot == "file")
-                       return false;
-               
-               if(prot == "http" || prot == "https" || prot == "ftp") {
-                       GLib.Pid pid;
-                       GLib.Process.spawn_async(".", {"/usr/bin/xdg-open", request.uri}, null,
-                               GLib.SpawnFlags.STDOUT_TO_DEV_NULL, null, out pid);
-                       return true;
-               }
-               
-               accounts.new_content_action(prot, path);
-               
-               return true;
-       }
-}
index 674f191..7eb443e 100644 (file)
@@ -1,4 +1,5 @@
 using PinoEnums;
+using Gee;
 
 namespace Identica {
 
@@ -13,6 +14,47 @@ public class Account : Twitter.Account {
        
        protected override string root_url {get; set; default = "http://identi.ca/api/";}
        protected override string search_url {get; set; default = "http://identi.ca/api/";}
+       
+       construct {
+               //base;
+               //avaliable_streams.set(StreamEnum.GROUP, typeof(Identica.StreamGroup));
+       }
+       
+       protected override void init_stream(AStream stream) {
+               if(stream.get_type() == typeof(Identica.StreamGroup)) { //init group stream
+                       if(((StreamGroup) stream).s_group_name == "") {
+                               SearchDialog s_dialog = new SearchDialog();
+                               if(s_dialog.run() == Gtk.ResponseType.OK) {
+                                       ((StreamGroup) stream).s_group_name = s_dialog.input.get_text();
+                                       s_dialog.close();
+                                       ((Twitter.StreamAbstract) stream).set_proxy(proxy, s_name);
+                               } else { //remove stream
+                                       int index = streams.index_of(stream);
+                                       streams_actions_tracker(index, MenuItems.REMOVE);
+                                       s_dialog.close();
+                                       return;
+                               }
+                               return;
+                       }
+               }
+               
+               base.init_stream(stream);
+       }
+       
+       protected override HashMap<StreamEnum, GLib.Type> avaliable_streams() {
+               HashMap<StreamEnum, GLib.Type> map = base.avaliable_streams();
+               map.set(StreamEnum.GROUP, typeof(Identica.StreamGroup));
+               return map;
+       }
+       
+       public override void go_group(string group_name) {
+               HashMap<string, string> map = new HashMap<string, string>();
+               map["s-group-name"] = group_name;
+               
+               debug(avaliable_streams().size.to_string());
+               add_stream(StreamEnum.GROUP, true, map);
+       }
+       
        //private Rest.Proxy proxy;
        /*
        protected override void init_stream(AStream stream) {
index 663ce95..7aaa7e0 100644 (file)
@@ -22,7 +22,7 @@ public class CreateDialog : CreateDialogGeneric {
        private weak Thread thread = null;
        
        public CreateDialog(Window parent) {
-               base(parent, _("Create Identica account"),  Config.SERVICE_IDENTICA_ICON);
+               base(parent, _("Link with Identica account"),  Config.SERVICE_IDENTICA_ICON);
                
                login = new Entry();
                password = new Entry();
diff --git a/src/identica_stream_group.vala b/src/identica_stream_group.vala
new file mode 100644 (file)
index 0000000..23bb2c7
--- /dev/null
@@ -0,0 +1,27 @@
+using Gee;
+using PinoEnums;
+
+namespace Identica {
+       
+public class StreamGroup : Twitter.StreamHome {
+
+       public override StreamEnum stream_type {get { return StreamEnum.GROUP; } }
+       
+       protected override string func {get; set; default = "";}
+       
+       public override string id {get; set; default = "group";}
+       
+       public string s_group_name {get; set; default = "";}
+       
+       construct {
+               debug("identica group stream was created");
+       }
+       
+       protected override void set_call_params(bool more = false) {
+               base.set_call_params(more);
+               
+               func = "statusnet/groups/timeline/" + s_group_name + ".xml";
+               call.set_function(func);
+       }
+}
+}
index 11d88ed..83107eb 100644 (file)
@@ -34,9 +34,10 @@ public class ImgCache : Object {
                        map[path] = new Gdk.Pixbuf.from_file(path);
                }
                
+               /*
                if(map[path].width > 48 || map[path].height > 48) {
                        map[path] = map[path].scale_simple(48, 48, Gdk.InterpType.BILINEAR);
-               }
+               }*/
        }
        
        public Gdk.Pixbuf? from_cache(string path) {
@@ -53,6 +54,7 @@ public class ImgCache : Object {
                        return false;
                else
                        return true;
+               
        }
        
        public string? download(string url) {
index 75cb048..a6ee439 100644 (file)
@@ -95,8 +95,8 @@ public class MainWindow : Window {
                Action view_menu = new Action("ViewMenu", "View", null, null);
                Action help_menu = new Action("HelpMenu", "Help", null, null);
                
-               Action create_account_act = new Action("CreateAccount", _("New account"),
-                       _("Create new account"), null);
+               Action create_account_act = new Action("CreateAccount", _("Add account"),
+                       _("Add account"), null);
                
                //setup all account types
                string accounts_string = "";
index e7ec9f7..ddf28d6 100644 (file)
@@ -6,7 +6,8 @@ namespace PinoEnums {
                PUBLIC,
                FAVORITES,
                DIRECT,
-               SEARCH
+               SEARCH,
+               GROUP
        }
 
        public enum MenuItems {
index b925548..f7d867e 100644 (file)
@@ -1,5 +1,6 @@
 using Gtk;
 using Cairo;
+using Gee;
 
 /** Separate class for status */
 public class StatusDelegate : EventBox {
@@ -18,6 +19,7 @@ public class StatusDelegate : EventBox {
        private bool already_expanded = false;
        private ConversationView? con_view = null;
        private VBox vb_right;
+       private HBox hb_thumbs;
        
        private SmartTimer timer;
        
@@ -32,12 +34,22 @@ public class StatusDelegate : EventBox {
        private Regex urls;
        private Regex clear_notice;
        
+       private Regex twitpic_regex;
+       private Regex imgly_regex;
+       
+       private enum ImageHostings {
+               TWITPIC, IMGLY
+       }
+       
        public StatusDelegate(Status status, AStream stream) {
                nicks = new Regex("(^|\\s|['\"+&!/\\(-])@([A-Za-z0-9_]+)");
                tags = new Regex("(^|\\s|['\"+&!/\\(-])#([A-Za-z0-9_.-\\p{Latin}\\p{Greek}]+)");
                groups = new Regex("(^|\\s|['\"+&!/\\(-])!([A-Za-z0-9_]+)"); //for identi.ca groups
                urls = new Regex("((https?|ftp)://([A-Za-z0-9+&@#/%?=~_|!:,.;-]*)([A-Za-z0-9+&@#/%=~_|$]))"); // still needs to be improved for urls containing () such as wikipedia's
                
+               twitpic_regex = new Regex("(http://twitpic.com/([a-z0-9]+))");
+               imgly_regex = new Regex("(http://img.ly/([a-z0-9]+))");
+               
                // characters must be cleared to know direction of text
                clear_notice = new Regex("[: \n\t\r♻♺]+|@[^ ]+");
                
@@ -138,7 +150,6 @@ public class StatusDelegate : EventBox {
                                vb_right.pack_start(re_label, false, false, 4);
                                
                                status.new_reply.connect(add_new_reply);
-                               
                                status.end_reply.connect(end_reply);
                                
                        } else {
@@ -162,6 +173,22 @@ public class StatusDelegate : EventBox {
                        hb_header.pack_end(nick, false, false, 0);
                }
                
+               //search for thumbs
+               HashMap<string, string>? map = search_for_thumbs(status.content);
+               if(map != null) {
+                       hb_thumbs = new HBox(false, 4);
+                       vb_right.pack_start(hb_thumbs, false, false, 0);
+                       
+                       //add thumbs to the layout
+                       foreach(string key in map.keys) {
+                               debug(map[key]);
+                               //Avatar thumb = new Avatar.from_url(map[key], 75);
+                               Thumb thumb = new Thumb(map[key], 75, key);
+                               hb_thumbs.pack_start(thumb, false, false, 0);
+                               thumb.show_all();
+                       }
+               }
+               
                add(vb_main);
                
                //set bg color
@@ -259,6 +286,10 @@ public class StatusDelegate : EventBox {
                        stream.account.go_hashtag(uri);
                        break;
                
+               case "group":
+                       stream.account.go_group(uri);
+                       break;
+               
                case "userinfo":
                        debug("not implemented");
                        break;
@@ -364,8 +395,46 @@ public class StatusDelegate : EventBox {
                //data.printf("foreground='#ccc'");
                data = tags.replace(data, -1, 0, "\\1<b><a href='search://\\2'>#\\2</a></b>");
                
-               data = groups.replace(data, -1, 0, "\\1<b>!<a href='http://identi.ca/group/\\2'>\\2</a></b>");
+               data = groups.replace(data, -1, 0, "\\1<b>!<a href='group://\\2'>\\2</a></b>");
                data = data.replace("=fg-color=", visual_style.fg_color);
                return data;
        }
+       
+       /** Return hashmap with urls and urls of thumbs or null */
+       private HashMap<string, string>? search_for_thumbs(string text) {
+               HashMap<string, string> map = new HashMap<string, string>();
+               
+               extract_thumbs(text, map, twitpic_regex, ImageHostings.TWITPIC);
+               extract_thumbs(text, map, imgly_regex, ImageHostings.IMGLY);
+               
+               if(map.size == 0)
+                       return null;
+               
+               return map;
+       }
+       
+       private void extract_thumbs(string text, HashMap<string, string> map,
+               Regex regex, ImageHostings hosting_type) {
+               
+               int pos = 0;
+               while(true) {
+                       MatchInfo match_info;
+                       bool bingo = regex.match_all_full(text, -1, pos, GLib.RegexMatchFlags.NEWLINE_ANY, out match_info);
+                       if(bingo) {
+                               foreach(string s in match_info.fetch_all()) {
+                                       switch(hosting_type) {
+                                       case ImageHostings.TWITPIC:
+                                               map[s] = "http://twitpic.com/show/mini/" + s.split("twitpic.com/")[1];
+                                               break;
+                                       case ImageHostings.IMGLY:
+                                               map[s] = "http://img.ly/show/mini/" + s.split("img.ly/")[1];
+                                               break;
+                                       }
+                                       
+                                       match_info.fetch_pos(0, null, out pos);
+                                       break;
+                               }
+                       } else break;
+               }
+       }
 }
index 0d0bffe..2b0313d 100644 (file)
@@ -26,6 +26,10 @@ public class StreamsTypes : HashMap<StreamEnum, StreamMeta> {
                Gdk.Pixbuf search_icon = theme.load_icon("gtk-find", 24, 0);
                StreamMeta search = new StreamMeta("Search", search_icon);
                set(StreamEnum.SEARCH, search);
+               
+               Gdk.Pixbuf group_icon = new Gdk.Pixbuf.from_file(Config.GROUP_PATH);
+               StreamMeta group = new StreamMeta("Group", group_icon);
+               set(StreamEnum.GROUP, group);
        }
        
        /** Return type by a string value */
diff --git a/src/template.vala b/src/template.vala
deleted file mode 100644 (file)
index f27d42d..0000000
+++ /dev/null
@@ -1,628 +0,0 @@
-using Gee;
-using PinoEnums;
-
-public class Template : Object {
-       
-       private VisualStyle visual_style;
-       
-       private string main_tpl = """
-               <html>
-                       <head>
-                       <script type="text/javascript">
-                       function insertAfter(newElement,targetElement) {
-                               var parent = targetElement.parentNode;
-                               if(parent.lastchild == targetElement) {
-                                       parent.appendChild(newElement);
-                               } else {
-                                       parent.insertBefore(newElement, targetElement.nextSibling);
-                               }
-                       }
-                       function insert_reply(status_id, data) {
-                               var footer = document.getElementById("footer" + status_id);
-                               footer.removeAttribute("href");
-                               
-                               var reply = document.getElementById("reply" + status_id);
-                               
-                               if(reply == null) {
-                                       reply = document.createElement("div");
-                                       reply.setAttribute("class", "reply-box");
-                                       reply.setAttribute("id", "reply" + status_id);
-                               }
-                               
-                               reply.innerHTML += data;
-                               
-                               var status = document.getElementById("status" + status_id);
-                               //alert(status);
-                               insertAfter(reply, status);
-                       }
-                       function change_style(data) {
-                               document.getElementById("style").innerHTML = data;
-                       }
-                       function set_content(data) {
-                               document.getElementById("body").innerHTML = data;
-                       }
-                       function menu(e, data) {
-                               if(e.button == 2) {
-                                       location.href="contextmenu://" + data;
-                                       return true;
-                               }
-                       }
-                       function reply(e, data) {
-                               var sel = window.getSelection();
-                               sel.removeAllRanges();
-                               location.href="reply://" + data;
-                               return true;
-                       }
-                       </script>
-                       <style type="text/css" id="style">
-                       </style>
-                       </head>
-                       <body id="body">
-                       %s
-                       </body>
-               </html>
-       """;
-       
-       /*
-       private string header_tpl = """
-               <style type="text/css">
-       body {
-               color: {{fg_color}};
-               #font-family: Droid Sans;
-               #font-size: 9pt;
-       }
-       .status, .status-fresh {
-               margin-bottom: 10px;
-       }
-       .tri {
-               z-index: 3;
-               position: absolute;
-               top: 16px;
-               left: 0px;
-               width: 14px;
-               height: 14px;
-               background-color: {{bg_color}};
-               border: 1px solid #ddd;
-               border-right-style: none;
-               border-top-style: none;
-               -webkit-transform: rotate(45deg);
-               -webkit-border-radius: 0px 0px 0px 2px;
-               -webkit-box-shadow: 0px 1px 1px  #ccc;
-       }
-       .line {
-               z-index: 5;
-               position: absolute;
-               background-color: {{bg_color}};
-               top: 14px;
-               left: 7px;
-               width: 1px;
-               height: 19px;
-               -webkit-border-radius: 3px;
-       }
-       .status-content {
-               z-index: 4;
-               position: relative;
-               background-color: {{bg_color}};
-               border: 1px solid #ddd;
-               -webkit-border-radius: 3px;
-               padding: 6px;
-               margin-left: 7px;
-               -webkit-box-shadow: 1px 1px 1px  #ccc;
-               cursor: default;
-       }
-       a {
-               color: {{lk_color}};
-       }
-       .tags {
-               font-weight: bold;
-               text-decoration: none;
-       }
-       .status-fresh .status-content {
-               border-width: 2px;
-               border-color: #478bde;
-       }
-       .status-fresh .tri {
-               border-width: 2px;
-               border-color: #478bde;
-       }
-       .status-fresh .line {
-               top: 16px;
-               height: 16px;
-               width: 2px;
-       }
-       .status-own .tri {
-               position: relative;
-               float: right;
-               -webkit-border-radius: 0px 2px 0px 0px;
-               -webkit-box-shadow: 1px 0px 1px  #ccc;
-       }
-       .status-own .line {
-               position: relative;
-               float: right;
-               width: 3px;
-               left: 10px;
-               #background-color: red;
-       }
-       .status-own .status-content {
-               margin-left: 0px;
-               margin-right: 7px;
-       }
-       .status-own .right {
-               margin-left: 0px;
-               margin-right: 58px;
-       }
-       .status-own .left {
-               float: right;
-       }
-       .right {
-               position:relative;
-               margin-bottom: 10px;
-               margin-left: 58px;
-       }
-       .left {
-               float: left;
-               width: 48px;
-               height: 48px;
-               backgrond-color: #fff;
-               -webkit-border-radius: 3px;
-               -webkit-background-size: 48px 48px;
-               -webkit-box-shadow: 1px 1px 1px  #ccc;
-       }
-       .header {
-               margin-bottom: 3px;
-       }
-       .header a, .re_nick {
-               font-weight: bold;
-               text-decoration: none;
-               color: {{fg_color}};
-               text-shadow: 1px 1px 0 #fff;
-       }
-       .date, .footer {
-               font-size: smaller;
-               font-weight: bold;
-               text-shadow: 1px 1px 0 #fff;
-               opacity: 0.6;
-               float: right;
-       }
-       .footer {
-               float: none;
-               display: block;
-               text-decoration: none;
-               margin-top: 3px;
-               color: {{fg_color}};
-       }
-       .rt {
-               background-color: {{fg_color}};
-               color: {{bg_color}};
-               opacity: 0.6;
-               margin-right: 2px;
-               font-weight: bold;
-               padding-left: 3px;
-               padding-right: 3px;
-               -webkit-border-radius: 3px;
-       }
-       .menu {
-               background-color: {{fg_color}};
-               opacity: 0.0;
-               width: 15px;
-               height: 15px;
-               float: right;
-               #margin-left: 3px;
-               margin-top: -9px;
-               #margin-bottom: 5px;
-               margin-right: -6px;
-               -webkit-border-radius: 3px 0 3px 0;
-       }
-       @-webkit-keyframes menu-hover {
-               from {
-                       opacity: 0.0;
-               }
-               to {
-                       opacity: 0.6;
-               }
-       }
-       .status-content:hover .menu {
-               opacity: 0.6;
-               -webkit-animation-name: menu-hover;
-               -webkit-animation-duration: 1s;
-       }
-               </style>
-       """;
-       */
-       
-       private string header_tpl = """
-       body {
-               color: {{fg_color}};
-               background: {{bg_color}};
-               #font-family: Droid Sans;
-               #font-size: 9pt;
-               margin: 0px;
-       }
-       .status, .status-fresh, .status-own, .status-small {
-               background: {{bg_light_color}};
-               padding: 6px;
-               position: relative;
-               min-height: 50px;
-               border: 0px solid #edeceb;
-               border-bottom-width: 1px;
-       }
-       .status-small {
-               border-left-width: 1px;
-               -webkit-border-radius: 3px 0px 0px 3px;
-               min-height: 30px;
-       }
-       .status-content {
-               z-index: 4;
-               position: relative;
-               margin-left: 7px;
-               cursor: default;
-       }
-       a {
-               color: {{lk_color}};
-       }
-       .tags {
-               font-weight: bold;
-               text-decoration: none;
-       }
-       .reply-box {
-               margin-left: 24px;
-       }
-       .status-fresh {
-               #background: #c3dff7;
-               background: -webkit-gradient(linear, 0 -75, 0 bottom, from({{bg_light_color}}), to(#c6ebb1));
-               border: 0px;
-       }
-       .status-own .status-content {
-               margin-left: 0px;
-               margin-right: 7px;
-       }
-       .status-own .right {
-               margin-left: 0px;
-               margin-right: 50px;
-       }
-       .status-own .left {
-               float: right;
-       }
-       .right {
-               position:relative;
-               margin-left: 50px;
-       }
-       .status-small .right {
-                       margin-left: 24px;
-       }
-       .left {
-               float: left;
-               width: 48px;
-               height: 48px;
-               backgrond-color: #fff;
-               -webkit-border-radius: 3px;
-               -webkit-background-size: 48px 48px;
-               -webkit-box-shadow: 1px 1px 1px  #ccc;
-       }
-       .status-small .left {
-               width: 24px;
-               height: 24px;
-               -webkit-background-size: 24px 24px;
-       }
-       .header {
-               margin-bottom: 3px;
-       }
-       .header a, .re_nick {
-               font-weight: bold;
-               text-decoration: none;
-               color: #404040;
-               text-shadow: 1px 1px 0 #fff;
-       }
-       .date, .footer {
-               font-size: smaller;
-               font-weight: bold;
-               text-shadow: 1px 1px 0 #fff;
-               opacity: 0.6;
-               float: right;
-       }
-       .status-own .header a {
-               float: right;
-       }
-       .status-own .header .date {
-               float: none;
-       }
-       .footer {
-               float: none;
-               #display: block;
-               text-decoration: none;
-               padding-top: 5px;
-               color: #404040;
-       }
-       .sep{
-               height: 6px;
-       }
-       .rt {
-               background-color: #404040;
-               color: #FCFBFA;
-               opacity: 0.6;
-               margin-right: 2px;
-               font-weight: bold;Goldman Sachs
-               padding-left: 3px;
-               padding-right: 3px;
-               -webkit-border-radius: 3px;
-       }
-       .menu {
-               background-color: #404040;
-               opacity: 0.0;
-               width: 15px;
-               height: 15px;
-               float: right;
-               margin-top: -9px;
-               margin-right: -6px;
-               -webkit-border-radius: 3px 0 3px 0;
-       }
-       .clear {
-               clear: both;
-       }
-       @-webkit-keyframes menu-hover {
-               from {
-                       opacity: 0.0;
-               }
-               to {
-                       opacity: 0.6;
-               }
-       }
-       .status-content:hover .menu {
-               opacity: 0.6;
-               -webkit-animation-name: menu-hover;
-               -webkit-animation-duration: 1s;
-       }
-       """;
-       
-       /*
-       private string status_tpl = """
-       <div class="status{{status_state}}">
-               <div class="left" style="background-image:url('{{user_pic}}');"></div>
-               <div class="right">
-                       <div class="tri"></div>
-                       <div class="line"></div>
-                       <div class="status-content">
-                       <div class="header">
-                               {{retweet}} <a href="">{{user_name}}</a>
-                               <span class="date">about one hour ago</span>
-                       </div>
-                       <div>{{content}}</div>
-                       {{footer}}
-                       <a href=""><div class="menu"></div></a>
-                       </div>
-               </div>
-       </div>
-       """;
-       */
-       
-       private string status_tpl = """
-       <div class="status{{status_state}}" id="status{{status_id}}" onmouseup="menu(event, '{{account_hash}}##{{stream_hash}}##{{status_id}}');" ondblclick="reply(event, '{{account_hash}}##{{stream_hash}}##{{status_id}}');">
-               <div class="left" style="background-image:url('{{user_pic}}');"></div>
-               <div class="right">
-                       <div class="status-content">
-                               <div class="header">
-                                       {{retweet}} <a href="">{{user_name}}</a>
-                                       <span class="date">{{created}}</span>
-                               </div>
-                               <div>{{content}}</div>
-                               {{footer}}
-                       </div>
-               </div>
-               <div class="clear"></div>
-       </div>
-       """;
-       
-       private string status_small_tpl = """
-       <div class="status-small">
-               <div class="left" style="background-image:url({{user_pic}});"></div>
-               <div class="right">
-                       <div class="status-content">
-                               <a class="re_nick" href="">{{user_name}}</a>: {{content}}
-                       </div>
-               </div>
-               <div class="clear"></div>
-       </div>
-       """;
-       
-       private string retweet_tpl = """<span class="rt">Rt:</span>""";
-       private string footer_tpl = """<div class="sep"></div><a class="footer" id="footer{{status_id}}" href="context://{{account_hash}}##{{stream_hash}}##{{status_id}}">%s</a>""";
-       
-       private string header;
-       
-       private Regex nicks;
-       private Regex tags;
-       private Regex groups;
-       private Regex urls;
-       private Regex clear_notice;
-       
-       public Template(VisualStyle visual_style) {
-               this.visual_style = visual_style;
-               
-               render_header();
-               
-               nicks = new Regex("(^|\\s|['\"+&!/\\(-])@([A-Za-z0-9_]+)");
-               tags = new Regex("(^|\\s|['\"+&!/\\(-])#([A-Za-z0-9_.-\\p{Latin}\\p{Greek}]+)");
-               groups = new Regex("(^|\\s|['\"+&!/\\(-])!([A-Za-z0-9_]+)"); //for identi.ca groups
-               urls = new Regex("((https?|ftp)://([A-Za-z0-9+&@#/%?=~_|!:,.;-]*)([A-Za-z0-9+&@#/%=~_|$]))"); // still needs to be improved for urls containing () such as wikipedia's
-               
-               // characters must be cleared to know direction of text
-               clear_notice = new Regex("[: \n\t\r♻♺]+|@[^ ]+");
-       }
-       
-       public string stream_to_list(AStream stream, string hash) {
-               //changing locale to C
-               string currentLocale = GLib.Intl.setlocale(GLib.LocaleCategory.TIME, null);
-               GLib.Intl.setlocale(GLib.LocaleCategory.TIME, "C");
-               
-               string result = "";
-               
-               foreach(Status status in stream.statuses_fresh) {
-                       result += render_fresh_status(status, stream);
-               }
-               
-               foreach(Status status in stream.statuses) {
-                       result += render_status(status, stream);
-               }
-               
-               //string main_result = main_tpl.printf(header, result);
-               //debug(main_result);
-               
-               //back to the normal locale
-               GLib.Intl.setlocale(GLib.LocaleCategory.TIME, currentLocale);
-               
-               return result;
-       }
-       
-       public string render_body() {
-               return main_tpl.printf("");
-       }
-       
-       public string render_header() {
-               HashMap<string, string> map = new HashMap<string, string>();
-               map["fg_color"] = visual_style.fg_color;
-               map["bg_color"] = visual_style.bg_color;
-               map["bg_light_color"] = visual_style.bg_light_color;
-               map["lk_color"] = visual_style.lk_color;
-               header = render(header_tpl, map);
-               return header;
-       }
-       
-       public string render_fresh_status(Status status, AStream stream) {
-               HashMap<string, string> map = new HashMap<string, string>();
-               map["status_state"] = "-fresh";
-               return render_status(status,stream,  map);
-       }
-       
-       public string render_status(Status status,
-               AStream stream, HashMap<string, string> map = new HashMap<string, string>()) {
-               
-               Status wstatus = status;
-               map["retweet"] = "";
-               map["footer"] = "";
-               
-               if(status.retweet != null) { //if this status is retweet
-                       wstatus = status.retweet;
-                       map["retweet"] = retweet_tpl;
-                       
-                       string re_by = _("retweeted by ") + status.user.name;
-                       map["footer"] = footer_tpl.printf(re_by);
-               }
-               
-               if(status.reply != null) { //if we have reply here
-                       string reply_to = _("in reply to ") + status.reply.name;
-                       map["footer"] = footer_tpl.printf(reply_to);
-               }
-               
-               if(!map.has_key("status_state")) //if not fresh
-                       map["status_state"] = "";
-               
-               if(wstatus.own) //if it your own status
-                       map["status_state"] = "-own";
-               
-               if(img_cache.exist(wstatus.user.pic)) //load from cache, if exist
-                       map["user_pic"] = img_cache.download(wstatus.user.pic);
-               else
-                       map["user_pic"] = wstatus.user.pic;
-               
-               map["user_name"] = wstatus.user.name;
-               
-               bool is_search = false;
-               if(stream.stream_type == StreamEnum.SEARCH)
-                       is_search = true;
-               
-               map["created"] = time_to_human_delta(wstatus.created, is_search);
-               
-               map["content"] = format_content(wstatus.content, stream);
-               
-               //context menu data
-               map["account_hash"] = stream.account.get_hash();
-               map["stream_hash"] = stream.account.get_stream_hash(stream);
-               map["status_id"] = status.id;
-               
-               return render(status_tpl, map);
-       }
-       
-       public string render_small_status(Status status, AStream stream) {
-               HashMap<string, string> map = new HashMap<string, string>();
-               if(img_cache.exist(status.user.pic)) //load from cache, if exist
-                       map["user_pic"] = img_cache.download(status.user.pic);
-               else
-                       map["user_pic"] = status.user.pic;
-               
-               
-               map["user_name"] = status.user.name;
-               map["content"] = format_content(status.content, stream);
-               
-               return render(status_small_tpl, map);
-       }
-       
-       private string render(string text, HashMap<string, string> map) {
-               string result = text;
-               
-               foreach(string key in map.keys) {
-                       var pat = new Regex("{{" + key + "}}");
-                       result = pat.replace(result, -1, 0, map[key]);
-               }
-               //debug(result);
-               return result;
-       }
-       
-       /* Performaing to show in html context */
-       private string strip_tags_plus(owned string content) {
-               content = content.replace("\\", "&#92;");
-               //content = Markup.escape_text(content);
-               content = content.replace("<", "&lt;");
-               content = content.replace(">", "&gt;");
-               
-               return content;
-       }
-       
-       private string format_content(owned string data, AStream stream) {
-               data = strip_tags_plus(data);
-               
-               string tmp = data;
-               
-               int pos = 0;
-               while(true) {
-                       //url cutting
-                       MatchInfo match_info;
-                       bool bingo = urls.match_all_full(tmp, -1, pos, GLib.RegexMatchFlags.NEWLINE_ANY, out match_info);
-                       if(bingo) {
-                               foreach(string s in match_info.fetch_all()) {
-                                       if(s.length > 30) {
-                                               data = data.replace(s, """<a href="%s" title="%s">%s...</a>""".printf(s, s, s.substring(0, 30)));
-                                       } else {
-                                               data = data.replace(s, """<a href="%s">%s</a>""".printf(s, s));
-                                       }
-                                       
-                                       match_info.fetch_pos(0, null, out pos);
-                                       break;
-                               }
-                       } else break;
-               }
-               
-               data = nicks.replace(data, -1, 0, "\\1@<a class='re_nick' href='userinfo://\\2'>\\2</a>");
-               data = tags.replace(data, -1, 0, "\\1#<a class='tags' href='search://%s::\\2'>\\2</a>".printf(stream.account.get_stream_hash(stream)));
-               
-               data = groups.replace(data, -1, 0, "\\1!<a class='tags' href='http://identi.ca/group/\\2'>\\2</a>");
-               
-               return data;
-       }
-       
-       private string time_to_human_delta(string created, bool is_search = false) {
-               int delta = TimeParser.time_to_diff(created, is_search);
-               
-               if(delta < 30)
-                       return _("a few seconds ago");
-               if(delta < 120)
-                       return _("1 minute ago");
-               if(delta < 3600)
-                       return _("%i minutes ago").printf(delta / 60);
-               if(delta < 7200)
-                       return _("about 1 hour ago");
-               if(delta < 86400)
-                       return _("about %i hours ago").printf(delta / 3600);
-               
-               return TimeUtils.str_to_time(created).format("%k:%M %b %d %Y");
-       }
-}
diff --git a/src/thumb.vala b/src/thumb.vala
new file mode 100644 (file)
index 0000000..759b213
--- /dev/null
@@ -0,0 +1,26 @@
+using Gtk;
+
+public class Thumb : EventBoxTr {
+       
+       private string full_url;
+       
+       public Thumb(string url, int size, string? full_url) {
+               this.full_url = full_url;
+               
+               Avatar img = new Avatar.from_url(url, size);
+               add(img);
+               
+               button_release_event.connect(on_click);
+               
+               if(full_url != null)
+                       img.set_tooltip_text(full_url);
+       }
+       
+       private bool on_click(Gdk.EventButton event) {
+               GLib.Pid pid;
+               GLib.Process.spawn_async(".", {"/usr/bin/xdg-open", full_url},
+                       null, GLib.SpawnFlags.STDOUT_TO_DEV_NULL, null, out pid);
+               
+               return true;
+       }
+}
index 0350ab9..ff79409 100644 (file)
@@ -170,7 +170,7 @@ public class TreeWidget : TreeView {
 
                        Menu streams_menu = new Menu(); //for streams
                        
-                       foreach(StreamEnum stream in account.avaliable_streams.keys) {
+                       foreach(StreamEnum stream in account.avaliable_streams().keys) {
                                string label = streams_types.get(stream).name;
                                ImageMenuItem menu_item = new ImageMenuItem.with_label(label);
                                Image img = streams_types.get(stream).get_menu_image();
@@ -317,10 +317,19 @@ public class TreeWidget : TreeView {
                }
                
                string stream_name;
-               if(stream.stream_type == StreamEnum.SEARCH)
+               
+               switch(stream.stream_type) {
+               case StreamEnum.SEARCH:
                        stream_name = ((ISearch) stream).s_keyword;
-               else
+                       break;
+               case StreamEnum.GROUP:
+                       stream_name = "!" + ((Identica.StreamGroup) stream).s_group_name;
+                       break;
+               default:
                        stream_name = streams_types.get(stream.stream_type).name;
+                       break;
+               }
+               
                //MetaIcon meta_icon = new MetaIcon(stream_icon);
                store.set(iter, 0, new MetaRow(stream_icon, status_icon, stream_name,
                        false, stream.fresh_items));
index 007002e..3bc24ac 100644 (file)
@@ -39,8 +39,7 @@ public class Account : AAccount {
                }
        }
        
-       protected override HashMap<StreamEnum, GLib.Type> avaliable_streams {
-               owned get {
+       protected override HashMap<StreamEnum, GLib.Type> avaliable_streams() {
                        HashMap<StreamEnum, GLib.Type> map = new HashMap<StreamEnum, GLib.Type>();
 
                        map.set(StreamEnum.HOME, typeof(Twitter.StreamHome));
@@ -49,7 +48,7 @@ public class Account : AAccount {
                        map.set(StreamEnum.FAVORITES, typeof(Twitter.StreamFavorites));
                        map.set(StreamEnum.SEARCH, typeof(Twitter.StreamSearch));
                        return map;
-               }
+               
        }
        
        protected override StreamEnum[] default_streams {
index db60709..ca7644c 100644 (file)
@@ -25,7 +25,7 @@ public class CreateDialog : CreateDialogGeneric {
        public CreateDialog(Window parent, string root_url, string consumer_key,
                string consumer_secret, string icon_name, string service_name) {
                
-               base(parent, _("Create %s account").printf(service_name), icon_name);
+               base(parent, _("Link with %s account").printf(service_name), icon_name);
                
                debug(this.root_url);
                this.root_url = root_url;
index 29356f2..0b53c96 100644 (file)
@@ -13,7 +13,7 @@ public abstract class StreamAbstract : AStream {
        
        private unowned GLib.Thread thread;
        
-       private abstract string func {get; set;}
+       protected abstract string func {get; set;}
        
        protected virtual void set_call_params(bool more = false) {}
        
@@ -49,6 +49,7 @@ public abstract class StreamAbstract : AStream {
                } catch(ThreadError e) {
                        debug(e.message);
                }*/
+               debug(func);
                debug("start updating");
                status = StreamStatus.UPDATING;
                
index 3595714..0f4a306 100644 (file)
@@ -7,7 +7,7 @@ public class StreamMentions : Twitter.StreamHome {
 
        public override StreamEnum stream_type {get { return StreamEnum.MENTIONS; } }
        
-       private override string func {get; set; default = "statuses/mentions.xml";}
+       protected override string func {get; set; default = "statuses/mentions.xml";}
        
        public override string id {get; set; default = "mentions";}
        
index 6ec6fe6..eef1940 100644 (file)
@@ -7,7 +7,7 @@ public class StreamPublic : Twitter.StreamHome {
 
        public override StreamEnum stream_type {get { return StreamEnum.PUBLIC; } }
        
-       private override string func {get; set; default = "statuses/public_timeline.xml";}
+       protected override string func {get; set; default = "statuses/public_timeline.xml";}
        
        public override string id {get; set; default = "public";}
        
index 45b1bf2..2eaeb39 100644 (file)
@@ -7,7 +7,7 @@ public class StreamSearch : Twitter.StreamHome, ISearch {
 
        public override StreamEnum stream_type {get { return StreamEnum.SEARCH; } }
        
-       private override string func {get; set; default = "search.atom";}
+       protected override string func {get; set; default = "search.atom";}
        
        public override string id {get; set; default = "search";}
        
index 1cb501d..7c0f93c 100644 (file)
@@ -29,6 +29,7 @@ namespace Config
        public const string LOGO_PATH;
        public const string LOGO_FRESH_PATH;
        public const string MENTIONS_PATH;
+       public const string GROUP_PATH;
        public const string MENTIONS_FRESH_PATH;
        public const string TIMELINE_PATH;
        public const string TIMELINE_FRESH_PATH;