~ubuntu-branches/ubuntu/saucy/cairo-dock-plug-ins/saucy-proposed

« back to all changes in this revision

Viewing changes to clock/src/applet-digital.c

  • Committer: Jamie Strandboge
  • Author(s): Matthieu Baerts (matttbe)
  • Date: 2012-03-26 14:35:01 UTC
  • mfrom: (25.1.1 cairo-dock-plug-ins)
  • Revision ID: jamie@canonical.com-20120326143501-r3c8mq6n2vyc0e2j
* New upstream release. (LP: #961579)
* Upstream ChangeLog: (main changes)
 - Updated translations
 - MusicPlayer:
  + When choosing the player the first time, launch it and set the name
  + It seems the latest stable version of rhythmbox now re-uses this DBus
     address: org.mpris.MediaPlayer2.rhythmbox
 - Use the default bg color for always visible icons
 - GMenu: check if kde4-applications.menu and lxde-applications.menu
    are available
 - Dbus:
  + Bash interface: fixed a typo
  + Changed the third-party applets dir on the server for the 3.0
  + Enabling threads on the Python Interface
  + Modified the old SetEmblem method to use the new overlays
 - Enable GVFS if detected
 - Indicators: handle the case where the service crashes
 - Status-Notifier:
  + Indicator 0.4.90 (and newer) has a new variable (Title)
  + Display Label first if it's available instead of Title first
  + Fixed a bug with empty labels
  + KDE's watcher: if ItemIsMenu is true (e.g. Klipper) and if we only show
     the menu on left click, we emit a signal to the application to show
     its own menu
  + checked if the menu path is different that '/NO_DBUSMENU'
  + IAS: checked if an item is not already available in the systray
     (workaround) and fixed a few typos
  + Added a space between icons and fixed the wrong drawing of the icon
     on a vertical dock if the icon can be resized
  + Used cairo_dock_add_path_to_icon_theme
 - Sound control:
  + Fixed a small bug on reload (invisible icon)
  + Updated the Dbus names to match with Ubuntu 12.04
  + Backported the latest version of Ubuntu's indicator-sound into the
     Sound-Control applet
  + Make some items in the menu invisible if not available
  + Worked around a bug in libindicator, which keeps internally
     the service pointer
 - Logout:
  + Fixed a tiny memory leak
  + Look for a different icon's size if we want to display this icon in
     a menu/a dock/an emblem
 - PowerManager:
  + Removed an extraseparators in the menu
 - Clock:
  + Used the logical rectangle in order to fix the position of the text
  + Removed unused files
  + Removed useless translations (log.x and log.y = 0)
  + Only used this ratio to limit the deformation with the height
  + Fixed a problem with the ratio if this applet is displayed in
     a vertical dock
 - Remote Control: fixed a crash during the 'click' signal
 - Slider:
  + When reloading, display the changes immediately
  + Added the possibility to refresh the images list from the menu
  + Fixed the loading of the image on startup, when the applet's size is
     not yet stable
  + Code cleaning
 - Fixed an error when compiling without libindicator
 - A few minor changes (comments, factorisation, etc)
 - Recent-Events: if zeitgeist is not yet running on first search,
    try 3 times before giving up.
* debian/control:
 - Updated the version of cairo-dock-[core;data;dev].

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/**
2
 
* This file is a part of the Cairo-Dock project
3
 
*
4
 
* Copyright : (C) see the 'copyright' file.
5
 
* E-mail    : see the 'copyright' file.
6
 
*
7
 
* This program is free software; you can redistribute it and/or
8
 
* modify it under the terms of the GNU General Public License
9
 
* as published by the Free Software Foundation; either version 3
10
 
* of the License, or (at your option) any later version.
11
 
*
12
 
* This program is distributed in the hope that it will be useful,
13
 
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 
* GNU General Public License for more details.
16
 
* You should have received a copy of the GNU General Public License
17
 
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
 
*/
19
 
 
20
 
#include <stdlib.h>
21
 
#include <math.h>
22
 
 
23
 
#include "applet-struct.h"
24
 
#include "applet-config.h"
25
 
#include "applet-digital.h"
26
 
 
27
 
 
28
 
#define CD_CLOCK_DATE_BUFFER_LENGTH 50
29
 
static char s_cDateBuffer[CD_CLOCK_DATE_BUFFER_LENGTH+1];
30
 
 
31
 
void cd_clock_configure_digital (CairoDockModuleInstance *myApplet) {
32
 
        cd_debug ("%s", __func__);
33
 
        
34
 
        GError *erreur = NULL;
35
 
        GKeyFile *pKeyFile = g_key_file_new (); //On ouvre le fichier de conf
36
 
        if (myConfig.cDigital == NULL)
37
 
                myConfig.cDigital = g_strdup ("default");
38
 
        
39
 
        gchar *cConfPath = g_strdup_printf ("%s/digital/%s/config", MY_APPLET_SHARE_DATA_DIR, myConfig.cDigital);
40
 
        cd_debug ("Clock: Using %s digital theme", cConfPath);
41
 
        g_key_file_load_from_file (pKeyFile, cConfPath, G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS, &erreur);
42
 
        
43
 
        if (erreur != NULL) {
44
 
                cd_warning ("Attention : %s", erreur->message);
45
 
                g_error_free (erreur);
46
 
                erreur = NULL;
47
 
                return;
48
 
        }
49
 
        
50
 
        myData.pDigitalClock.bSecondCapable = cairo_dock_get_boolean_key_value (pKeyFile, "configuration", "seconds", FALSE, FALSE, NULL, NULL);
51
 
        myData.pDigitalClock.iFrameSpacing = cairo_dock_get_integer_key_value (pKeyFile, "configuration", "framespacing", FALSE, 2, NULL, NULL);
52
 
        
53
 
        myData.pDigitalClock.i12modeWidth = cairo_dock_get_integer_key_value (pKeyFile, "configuration", "12width", FALSE, 6, NULL, NULL);
54
 
        myData.pDigitalClock.i12modeHeight = cairo_dock_get_integer_key_value (pKeyFile, "configuration", "12height", FALSE, 6, NULL, NULL);
55
 
        myData.pDigitalClock.i12modeXOffset = cairo_dock_get_integer_key_value (pKeyFile, "configuration", "12offsetX", FALSE, 4, NULL, NULL);
56
 
        myData.pDigitalClock.i12modeYOffset = cairo_dock_get_integer_key_value (pKeyFile, "configuration", "12offsetY", FALSE, 1, NULL, NULL);
57
 
        myData.pDigitalClock.i12modeFrame = cairo_dock_get_integer_key_value (pKeyFile, "configuration", "12frame", FALSE, 4, NULL, NULL);
58
 
        
59
 
        int i = 0, j = (myData.pDigitalClock.bSecondCapable == TRUE ? 3 : 4);
60
 
        //Avec secondes 3 frames, une par unités (hh : mm : ss)
61
 
        //Sans secondes 4 frames, une par nombre (1|2:4|5)
62
 
        for (i = 0; i < j; i++) {
63
 
                gchar *cGroupName = g_strdup_printf ("frame_%d", i);
64
 
                myData.pDigitalClock.pFrame[i].iWidth = cairo_dock_get_integer_key_value (pKeyFile, cGroupName, "width", FALSE, 4, NULL, NULL);
65
 
                myData.pDigitalClock.pFrame[i].iHeight = cairo_dock_get_integer_key_value (pKeyFile, cGroupName, "height", FALSE, 4, NULL, NULL);
66
 
                myData.pDigitalClock.pFrame[i].iXOffset = cairo_dock_get_integer_key_value (pKeyFile, cGroupName, "offsetX", FALSE, 0, NULL, NULL);
67
 
                myData.pDigitalClock.pFrame[i].iYOffset = cairo_dock_get_integer_key_value (pKeyFile, cGroupName, "offsetY", FALSE, 0, NULL, NULL);
68
 
                g_free (cGroupName);
69
 
                
70
 
                cGroupName = g_strdup_printf ("text_%d", i);
71
 
                myData.pDigitalClock.pText[i].iXOffset = cairo_dock_get_integer_key_value (pKeyFile, cGroupName, "offsetX", FALSE, -1, NULL, NULL);
72
 
                myData.pDigitalClock.pText[i].iYOffset = cairo_dock_get_integer_key_value (pKeyFile, cGroupName, "offsetY", FALSE, -1, NULL, NULL);
73
 
                g_free (cGroupName);
74
 
        }
75
 
        
76
 
        g_key_file_free (pKeyFile);
77
 
        g_free (cConfPath);
78
 
        
79
 
        cd_clock_digital_load_frames (myApplet);
80
 
}
81
 
 
82
 
void cd_clock_digital_load_frames (CairoDockModuleInstance *myApplet) {
83
 
        cd_debug ("%s", __func__);
84
 
        
85
 
        int i = 0, j = (myData.pDigitalClock.bSecondCapable == TRUE ? 3 : 4);
86
 
        double fFrameWidth = 1, fFrameHeight = 1;
87
 
        //Avec secondes 3 frames, une par unités (hh : mm : ss)
88
 
        //Sans secondes 4 frames, une par nombre (1|2:4|5)
89
 
        for (i = 0; i < j; i++) {
90
 
                fFrameWidth = myIcon->fWidth / (double) myData.pDigitalClock.pFrame[i].iWidth;
91
 
                cd_debug ("Clock: frame %d width %.02f (%.02f %d)", i+1, fFrameWidth, myIcon->fWidth, myData.pDigitalClock.pFrame[i].iWidth);
92
 
                fFrameWidth = fFrameWidth - myData.pDigitalClock.iFrameSpacing;
93
 
                fFrameHeight = myIcon->fHeight; /// myData.pDigitalClock.pFrame[i].iHeight;
94
 
                double fImgW=0, fImgH=0;
95
 
                
96
 
                if (myConfig.cDigital == NULL)
97
 
                        myConfig.cDigital = g_strdup ("default");
98
 
                        
99
 
                gchar *cImagePath = g_strdup_printf ("%s/digital/%s/frame_%d.svg", MY_APPLET_SHARE_DATA_DIR, myConfig.cDigital, i);
100
 
                cd_debug ("Clock: Loading %s frame (%.02fx%.02f)", cImagePath, fFrameWidth, fFrameHeight);
101
 
                cairo_t *pCairoContext = cairo_dock_create_context_from_window (myContainer);
102
 
                myData.pDigitalClock.pFrame[i].pFrameSurface = cairo_dock_create_surface_from_image (cImagePath,
103
 
                        1.,
104
 
                        fFrameWidth, fFrameHeight,
105
 
                        FALSE,
106
 
                        &fImgW, &fImgH,
107
 
                        NULL, NULL);
108
 
                cairo_destroy (pCairoContext);
109
 
                g_free (cImagePath);
110
 
        }
111
 
}
112
 
 
113
 
void cd_clock_draw_frames (CairoDockModuleInstance *myApplet) {
114
 
        cd_debug ("%s", __func__);
115
 
        
116
 
        cairo_set_source_rgba (myDrawContext, 0., 0., 0., 0.);
117
 
        cairo_set_operator (myDrawContext, CAIRO_OPERATOR_SOURCE);
118
 
        cairo_paint (myDrawContext);
119
 
        cairo_set_operator (myDrawContext, CAIRO_OPERATOR_OVER);
120
 
        
121
 
        int i = 0, j = (myData.pDigitalClock.bSecondCapable == TRUE ? 3 : 4);
122
 
        double fX, fY;
123
 
        //Avec secondes 3 frames, une par unité (hh | mm | ss)
124
 
        //Sans secondes 4 frames, une par nombre (1|2 | 4|5)
125
 
        for (i = 0; i < j; i++) {
126
 
                fX = (myIcon->fWidth / j) * i + myData.pDigitalClock.pFrame[i].iXOffset;
127
 
                fY = myData.pDigitalClock.pFrame[i].iYOffset;
128
 
                cd_debug ("Clock: frame:%d ; fX:%.02f ; fY:%.02f", i+1, fX, fY);
129
 
                cairo_set_source_surface (myDrawContext, myData.pDigitalClock.pFrame[i].pFrameSurface, fX, fY);
130
 
                cairo_paint (myDrawContext);
131
 
        }
132
 
        
133
 
        CD_APPLET_REDRAW_MY_ICON;
134
 
}
135
 
 
136
 
void cd_clock_put_text_on_frames (CairoDockModuleInstance *myApplet, int width, int height, double fMaxScale, struct tm *pTime) {
137
 
        cd_debug ("%s", __func__);
138
 
        
139
 
        cairo_t *pSourceContext = myDrawContext;
140
 
        GString *sFormat = g_string_new ("");
141
 
        
142
 
        if (myConfig.b24Mode) {
143
 
                if (myData.pDigitalClock.bSecondCapable)
144
 
                        g_string_printf (sFormat, "%%T");
145
 
                else
146
 
                        g_string_printf (sFormat, " %%R");
147
 
        }
148
 
        else {
149
 
                if (myData.pDigitalClock.bSecondCapable)
150
 
                        g_string_printf (sFormat, "%%r%%s");
151
 
                else
152
 
                        g_string_printf (sFormat, "%%I:%%M");
153
 
        }
154
 
 
155
 
        if (myConfig.iShowDate == CAIRO_DOCK_INFO_ON_ICON)
156
 
                cd_clock_draw_date_on_frame (myApplet);
157
 
                //Erf! Comment bien gérer ca ...
158
 
        
159
 
        strftime (s_cDateBuffer, CD_CLOCK_DATE_BUFFER_LENGTH, sFormat->str, pTime);
160
 
        g_string_free (sFormat, TRUE);
161
 
        
162
 
        /// Attention : soit on passe un char a cd_clock_fill_text_surface(), soit un char *, il faut choisir.
163
 
        /// Ne pas modifier le pointeur d'une chaine ! utiliser un pointeur secondaire qu'on balade dessus, sinon au free ca fait mal ;-)
164
 
        gchar *cTime = g_strdup (s_cDateBuffer), *cT1 = NULL;
165
 
        if (myData.pDigitalClock.bSecondCapable) { //On coupe aux ':' donc on arrive a 12|45|32
166
 
                cT1 = g_strdup (cTime);
167
 
                gchar *str = strchr (cT1, ':'); //On récupère [12]:45:32
168
 
                if (str != NULL)
169
 
                        *str = '\0';
170
 
                cd_clock_fill_text_surface (myApplet, cT1, 0);
171
 
                
172
 
                cT1 = g_strdup (cTime);
173
 
                str = strrchr (cT1, ':'); //On récupère [12:45]:32
174
 
                if (str != NULL)
175
 
                        *str = '\0';
176
 
                str = strchr (cT1, ':'); //On récupère 12:[45]:32
177
 
                str++;
178
 
                cd_clock_fill_text_surface (myApplet, str, 1);
179
 
                
180
 
                cT1 = g_strdup (cTime);
181
 
                str = strrchr (cT1, ':'); //On récupère 12:45:[32]
182
 
                str++;
183
 
                cd_clock_fill_text_surface (myApplet, str, 2);
184
 
        }
185
 
        else { //On coupe au ':' puis on sépare les chiffres donc on arrive a 1|2 | 4|5
186
 
                cT1 = g_strdup (cTime);
187
 
                gchar *str = strchr (cT1, ':'); //On récupère [12]:45
188
 
                if (str != NULL)
189
 
                        *str = '\0';
190
 
                cd_clock_fill_text_surface (myApplet, *cT1, 0);
191
 
                cT1++; /// GLUPS !
192
 
                cd_clock_fill_text_surface (myApplet, *cT1, 1);
193
 
                
194
 
                cT1 = g_strdup (cTime);
195
 
                str = strrchr (cT1, ':'); //On récupère 12:[45]
196
 
                str++;
197
 
                cd_clock_fill_text_surface (myApplet, *str, 2);
198
 
                str++;
199
 
                cd_clock_fill_text_surface (myApplet, *str, 3);
200
 
        }
201
 
        g_free (cTime);
202
 
        g_free (cT1);
203
 
        
204
 
        int i = 0, j = (myData.pDigitalClock.bSecondCapable == TRUE ? 3 : 4);
205
 
        for (i = 0; i < j; i++) {
206
 
                //On dessine le texte dans les frames
207
 
                cd_clock_draw_text_from_surface (myApplet, i);
208
 
        }
209
 
        
210
 
        //On ajoute le am/pm s'il le faut
211
 
        if (! myConfig.b24Mode) {
212
 
                if (pTime->tm_hour > 12)
213
 
                        cd_clock_draw_ampm (myApplet, "PM");
214
 
                else
215
 
                        cd_clock_draw_ampm (myApplet, "AM");
216
 
        }
217
 
}
218
 
 
219
 
void cd_clock_draw_ampm (CairoDockModuleInstance *myApplet, gchar *cMark) {
220
 
        cd_debug ("Adding %s to the last frame", cMark);
221
 
        //Ca s'est gérer dans la config.
222
 
        //Vérifier les structures necessaires.
223
 
}
224
 
 
225
 
void cd_clock_draw_text_from_surface (CairoDockModuleInstance *myApplet, int iNumber) {
226
 
        cd_debug ("Printing text #%d on corresponding frame", iNumber);
227
 
        //Il faudra surment scale down la surface avant de cairo_print
228
 
        //TODO prendre le code sur slider.
229
 
}
230
 
 
231
 
void cd_clock_fill_text_surface (CairoDockModuleInstance *myApplet, gchar *cStr, int iNumber) {
232
 
        cd_debug ("Filling the #%d surface with %s", iNumber, cStr);
233
 
        //Aucune idée de comment faire!
234
 
        //TODO demander a fabounet des indices ici.
235
 
}
236
 
 
237
 
void cd_clock_draw_date_on_frame (CairoDockModuleInstance *myApplet) {
238
 
        cd_debug ("Add date on frame");
239
 
}