static gboolean _timer (gpointer data) { CD_APPLET_ENTER; time_t t_cur = (time_t) time (NULL); if (t_cur >= myConfig.iShutdownTime) { cd_debug ("shutdown !\n"); if (g_iDesktopEnv == CAIRO_DOCK_KDE) cairo_dock_launch_command ("dbus-send --session --type=method_call --dest=org.kde.ksmserver /KSMServer org.kde.KSMServerInterface.logout int32:0 int32:2 int32:2"); else cairo_dock_launch_command ("dbus-send --system --print-reply --dest=org.freedesktop.ConsoleKit /org/freedesktop/ConsoleKit/Manager org.freedesktop.ConsoleKit.Manager.Stop"); myData.iSidTimer = 0; CD_APPLET_LEAVE (FALSE); // inutile de faire quoique ce soit d'autre, puisque l'ordi s'eteint. } else { cd_debug ("shutdown in %d minutes", (int) (myConfig.iShutdownTime - t_cur) / 60); CD_APPLET_SET_QUICK_INFO_ON_MY_ICON_PRINTF ("%dmn", (int) ceil ((double)(myConfig.iShutdownTime - t_cur) / 60.)); CD_APPLET_REDRAW_MY_ICON; if (t_cur >= myConfig.iShutdownTime - 60) gldi_dialog_show_temporary_with_icon (D_("Your computer will shut-down in 1 minute."), myIcon, myContainer, 8000, "same icon"); } CD_APPLET_LEAVE (TRUE); }
static gboolean _fill_submenu_idle (CDQuickBrowserItem *pItem) { GldiModuleInstance *myApplet = pItem->pApplet; CD_APPLET_ENTER; if (pItem->pLocalItemList == NULL) { _init_fill_menu_from_dir (pItem); if (pItem->pLocalItemList == NULL) // cas particulier d'un repertoire vide, inutile de revenir ici pour rien faire. pItem->bMenuBuilt = TRUE; } else { _fill_submenu_with_items (pItem, myConfig.iNbSubItemsAtOnce); if (pItem->pCurrentItem == NULL) pItem->bMenuBuilt = TRUE; } if (pItem->bMenuBuilt) { GldiModuleInstance *myApplet = pItem->pApplet; myData.iSidFillDirIdle = 0; /* force to compute the size of the menu before displaying it * -> avoid big menu that are out of the screen */ gtk_widget_set_size_request (pItem->pSubMenu, -1, -1); gtk_widget_show_all (pItem->pSubMenu); CD_APPLET_LEAVE (FALSE); } CD_APPLET_LEAVE (TRUE); }
/* Fonction executee à chaque changement de musique. */ static void onChangeSong(DBusGProxy *player_proxy, GHashTable *metadata, gpointer data) { CD_APPLET_ENTER; cd_debug ("MP : %s ()", __func__); if (metadata != NULL) { _extract_metadata (metadata); } else { g_free (myData.cPlayingUri); myData.cPlayingUri = NULL; g_free (myData.cArtist); myData.cArtist = NULL; g_free (myData.cAlbum); myData.cAlbum = NULL; g_free (myData.cTitle); myData.cTitle = NULL; g_free (myData.cCoverPath); myData.cCoverPath = NULL; myData.iSongLength = 0; myData.iTrackNumber = 0; myData.cover_exist = FALSE; } cd_musicplayer_update_icon (); CD_APPLET_LEAVE (); }
static gboolean _render_step_cairo (Icon *pIcon, GldiModuleInstance *myApplet) { CD_APPLET_ENTER; double f = CD_APPLET_GET_TRANSITION_FRACTION (); int iWidth, iHeight; CD_APPLET_GET_MY_ICON_EXTENT (&iWidth, &iHeight); CD_APPLET_LEAVE_IF_FAIL (iHeight != 0, TRUE); CD_APPLET_START_DRAWING_MY_ICON_OR_RETURN_CAIRO (FALSE); // image precedente. if (myData.pOldImage != NULL) { cairo_dock_apply_image_buffer_surface_with_offset (myData.pOldImage, myDrawContext, 0, 0, 1. - f); } // image courante. if (myData.pCurrentImage != NULL) { int x = (iWidth - myData.pCurrentImage->iWidth) / 2; int y = (iHeight - myData.pCurrentImage->iHeight) / 2; cairo_dock_apply_image_buffer_surface_with_offset (myData.pCurrentImage, myDrawContext, x, y, f); } CD_APPLET_FINISH_DRAWING_MY_ICON_CAIRO; CD_APPLET_LEAVE (TRUE); }
CD_APPLET_ON_CLICK_END //\___________ Define here the entries you want to add to the menu when the user right-clicks on your icon or on its subdock or your desklet. The icon and the container that were clicked are available through the macros CD_APPLET_CLICKED_ICON and CD_APPLET_CLICKED_CONTAINER. CD_APPLET_CLICKED_ICON may be NULL if the user clicked in the container but out of icons. The menu where you can add your entries is available throught the macro CD_APPLET_MY_MENU; you can add sub-menu to it if you want. #ifdef HAVE_X11 #ifdef HAVE_XRANDR static void _on_select_resolution (GtkMenuItem *menu_item, gpointer data) /// TODO: put that in the core... { CD_APPLET_ENTER; int iNumRes = GPOINTER_TO_INT (data); Display *dpy; Window root; XRRScreenConfiguration *conf; short *rates; int num_rates; dpy = gdk_x11_get_default_xdisplay (); root = RootWindow(dpy, 0); conf = XRRGetScreenInfo(dpy, root); CD_APPLET_LEAVE_IF_FAIL (conf != NULL); //g_return_if_fail (conf != NULL); rates = XRRRates(dpy, 0, iNumRes, &num_rates); CD_APPLET_LEAVE_IF_FAIL (num_rates > 0); //g_return_if_fail (num_rates > 0); cd_debug ("available rates : from %d to %d Hz", rates[0], rates[num_rates-1]); XRRSetScreenConfigAndRate(dpy, conf, root, iNumRes, RR_Rotate_0, rates[num_rates-1], CurrentTime); XRRFreeScreenConfigInfo (conf); // restore original conf : XRRSetScreenConfigAndRate(dpy, conf, root, original_size_id, original_rotation, original_rate, CurrentTime); CD_APPLET_LEAVE(); }
static gboolean _render_step_opengl (Icon *pIcon, GldiModuleInstance *myApplet) { g_return_val_if_fail (myData.pCurrentImage != NULL, FALSE); CD_APPLET_ENTER; double f = CD_APPLET_GET_TRANSITION_FRACTION (); int iWidth, iHeight; CD_APPLET_GET_MY_ICON_EXTENT (&iWidth, &iHeight); _cairo_dock_enable_texture (); _cairo_dock_set_blend_alpha (); // image precedente. if (myData.pOldImage != NULL) { _cairo_dock_set_alpha (1. - f); cairo_dock_apply_image_buffer_texture_with_offset (myData.pOldImage, 0, 0); } // image courante. if (myData.pCurrentImage != NULL) { _cairo_dock_set_alpha (f); cairo_dock_apply_image_buffer_texture_with_offset (myData.pCurrentImage, 0, 0); } _cairo_dock_disable_texture (); CD_APPLET_LEAVE (TRUE); }
static void _on_got_playing_status (DBusGProxy *proxy, DBusGProxyCall *call_id, GldiModuleInstance *myApplet) { cd_debug ("=== %s ()", __func__); CD_APPLET_ENTER; s_pGetStatusCall = NULL; gchar *cStatus = NULL; GValue v = G_VALUE_INIT; GError *erreur = NULL; dbus_g_proxy_end_call (proxy, call_id, &erreur, G_TYPE_VALUE, &v, G_TYPE_INVALID); if (erreur != NULL) { cd_warning ("couldn't get MPRIS status (%s)\n", erreur->message); g_error_free (erreur); } else { if (G_VALUE_HOLDS_STRING (&v)) { cStatus = (gchar*)g_value_get_string (&v); myData.iPlayingStatus = _extract_status (cStatus); g_free (cStatus); // since we don't destroy the value, we destroy its content. } } cd_mpris2_getSongInfos_async (); CD_APPLET_LEAVE (); }
static void on_change_volume (GtkRange *range, gpointer data) { CD_APPLET_ENTER; int iNewVolume = (int) gtk_range_get_value (GTK_RANGE (range)); cd_debug ("%s (%d)", __func__, iNewVolume); cd_set_volume (iNewVolume); CD_APPLET_LEAVE(); }
static gboolean _unthreaded_task (GldiModuleInstance *myApplet) { CD_APPLET_ENTER; cd_sysmonitor_get_data (myApplet); cd_sysmonitor_update_from_data (myApplet); CD_APPLET_LEAVE (TRUE); //return TRUE; }
static void _on_got_song_infos (DBusGProxy *proxy, DBusGProxyCall *call_id, GldiModuleInstance *myApplet) { cd_debug ("=== %s ()", __func__); CD_APPLET_ENTER; s_pGetSongInfosCall = NULL; GHashTable *pMetadata = NULL; GValue v = G_VALUE_INIT; GError *erreur = NULL; dbus_g_proxy_end_call (proxy, call_id, &erreur, G_TYPE_VALUE, &v, G_TYPE_INVALID); if (erreur != NULL) { cd_warning ("couldn't get MPRIS song infos (%s)\n", erreur->message); g_error_free (erreur); pMetadata = NULL; } else { if (G_VALUE_HOLDS_BOXED (&v)) { pMetadata = g_value_get_boxed (&v); // since we don't destroy the value, we'll take care of the hash-table when we're done with it. } } if (pMetadata != NULL) { _extract_metadata (pMetadata); g_hash_table_destroy (pMetadata); } else { cd_warning (" can't get song properties"); g_free (myData.cPlayingUri); myData.cPlayingUri = NULL; g_free (myData.cTitle); myData.cTitle = NULL; g_free (myData.cAlbum); myData.cAlbum = NULL; g_free (myData.cArtist); myData.cArtist = NULL; g_free (myData.cCoverPath); myData.cCoverPath = NULL; myData.iSongLength = 0; myData.iTrackNumber = 0; myData.cover_exist = FALSE; } cd_musicplayer_update_icon (); cd_musicplayer_relaunch_handler (); CD_APPLET_LEAVE (); }
static gboolean _on_got_cover (CDSharedMemory *pSharedMemory) { CD_APPLET_ENTER; if (pSharedMemory->bSuccess) { myData.cover_exist = TRUE; cd_musiplayer_apply_cover (); } gldi_task_discard (myData.pCoverTask); myData.pCoverTask = NULL; CD_APPLET_LEAVE (FALSE); }
static void _show_desktop (GtkMenuItem *menu_item, gpointer data) { CD_APPLET_ENTER; int iIndex = GPOINTER_TO_INT (data); int iNumDesktop, iNumViewportX, iNumViewportY; cd_switcher_compute_desktop_from_index (iIndex, &iNumDesktop, &iNumViewportX, &iNumViewportY); if (iNumViewportX != myData.switcher.iCurrentViewportX || iNumViewportY != myData.switcher.iCurrentViewportY || iNumDesktop != myData.switcher.iCurrentDesktop) gldi_desktop_set_current (iNumDesktop, iNumViewportX, iNumViewportY); CD_APPLET_LEAVE (); }
// only use to catch new state of the indicator gboolean cd_xkbd_keyboard_state_changed (GldiModuleInstance *myApplet, Window *pWindow) { CD_APPLET_ENTER; ///if (pWindow == NULL) /// return GLDI_NOTIFICATION_LET_PASS; // Get the current state XklState *state = xkl_engine_get_current_state (myData.pEngine); guint32 indicators = _get_state_indicators (); cd_debug ("group : %d -> %d ; indic : %d -> %d (%d)", myData.iCurrentGroup, state->group, myData.iCurrentIndic, indicators, state->indicators); if (myData.iCurrentIndic == indicators) CD_APPLET_LEAVE (GLDI_NOTIFICATION_LET_PASS); // Remember the current state myData.iCurrentIndic = indicators; cd_xkbd_update_icon (NULL, NULL, FALSE); // redraw only the indicators CD_APPLET_LEAVE (GLDI_NOTIFICATION_LET_PASS); }
/* Fonction executee à chaque changement "unpaused". */ static void on_unpaused (DBusGProxy *player_proxy, gpointer data) // unpaused { CD_APPLET_ENTER; cd_debug ("MP : %s ()", __func__); myData.iPlayingStatus = PLAYER_PLAYING; cd_musicplayer_relaunch_handler (); if(! myData.cover_exist && (myData.cPlayingUri != NULL || myData.cTitle != NULL)) { cd_musicplayer_apply_status_surface (myData.iPlayingStatus); } else { CD_APPLET_REDRAW_MY_ICON; } CD_APPLET_LEAVE (); }
static void _cd_crypt_delete_stash_item (GtkMenuItem *menu_item, gpointer data) { CD_APPLET_ENTER; int selection = cairo_dock_show_dialog_and_wait ( D_("Are you sure that you want delete selected stash?"), myIcon, myContainer, NULL, NULL); if (selection == STASH_NAME_BUTTON_OK) { // user select Ok check mark gboolean passed = crypt_delete_stash_from_list(data); if (passed==FALSE) { crypt_show_notification_dialog (D_("Operation failed.")); } else { g_ptr_array_remove (myData.pStashArray, data); crypt_free_stashitem (data); crypt_show_notification_dialog (D_("Stash removed. Note actual encfs folder still remain at the disk.")); } } CD_APPLET_LEAVE(); }
static void _on_activate_item (GtkWidget *pMenuItem, CDQuickBrowserItem *pItem) { g_return_if_fail (pItem != NULL); GldiModuleInstance *myApplet = pItem->pApplet; CD_APPLET_ENTER; if (pItem->pSubMenu != NULL) { if (! pItem->bMenuBuilt) { if (myData.iSidFillDirIdle != 0) g_source_remove (myData.iSidFillDirIdle); myData.iSidFillDirIdle = g_idle_add ((GSourceFunc) _fill_submenu_idle, pItem); } } else // left click, no drag { cairo_dock_fm_launch_uri (pItem->cPath); cd_quick_browser_destroy_menu (myApplet); } CD_APPLET_LEAVE (); }
CD_APPLET_ON_CLICK_END //\___________ Same as ON_CLICK, but with middle-click. CD_APPLET_ON_MIDDLE_CLICK_BEGIN CD_APPLET_ON_MIDDLE_CLICK_END //\___________ Same as ON_CLICK, but with scroll. Moreover, CD_APPLET_SCROLL_UP tels you is the user scrolled up, CD_APPLET_SCROLL_DOWN the opposite. CD_APPLET_ON_SCROLL_BEGIN CD_APPLET_ON_SCROLL_END static void _cd_crypt_create_new_stash (GtkMenuItem *menu_item, gpointer data) { CD_APPLET_ENTER; crypt_dock_create_new_stash (); CD_APPLET_LEAVE(); }
void cd_switcher_draw_desktops_bounding_box (CairoDesklet *pDesklet) { CD_APPLET_ENTER; //g_print ("%s (%.2Fx%.2f)\n", __func__, myData.switcher.fOneViewportWidth, myData.switcher.fOneViewportHeight); double x, y, w, h; glTranslatef (-pDesklet->container.iWidth/2, -pDesklet->container.iHeight/2, 0.); w = myData.switcher.fOneViewportWidth/2; h = myData.switcher.fOneViewportHeight/2; int i, j; int k = 0, N = g_desktopGeometry.iNbDesktops * g_desktopGeometry.iNbViewportX * g_desktopGeometry.iNbViewportY; for (j = 0; j < myData.switcher.iNbLines; j ++) // lignes horizontales. { y = myConfig.iLineSize + j * (myData.switcher.fOneViewportHeight + myConfig.iInLineSize) - .5*myConfig.iInLineSize; y = pDesklet->container.iHeight - (y + h + myData.switcher.fOffsetY); for (i = 0; i < myData.switcher.iNbColumns; i ++) // lignes verticales. { x = myConfig.iLineSize + i * (myData.switcher.fOneViewportWidth + myConfig.iInLineSize) - .5*myConfig.iInLineSize; x += w + myData.switcher.fOffsetX; glLoadName(i * myData.switcher.iNbLines + j + 1); // +1 pour ne pas avoir 0. glBegin(GL_QUADS); glVertex3f(x-w, y+h, 0.); glVertex3f(x+w, y+h, 0.); glVertex3f(x+w, y-h, 0.); glVertex3f(x-w, y-h, 0.); glEnd(); k ++; if (k == N) break; } } CD_APPLET_LEAVE (); }
static void _on_program_shutdown (int iClickedButton, GtkWidget *pInteractiveWidget, gpointer data, CairoDialog *pDialog) { CD_APPLET_ENTER; if (iClickedButton == 0 || iClickedButton == -1) // ok button or Enter. { int iDeltaT = 60 * gtk_range_get_value (GTK_RANGE (pInteractiveWidget)); if (iDeltaT > 0) // set the new time { //g_print ("iShutdownTime <- %ld + %d\n", t_cur, iDeltaT); time_t t_cur = (time_t) time (NULL); myConfig.iShutdownTime = (int) (t_cur + iDeltaT); } else if (iDeltaT == 0) // cancel any previous shutdown { myConfig.iShutdownTime = 0; } cairo_dock_update_conf_file (CD_APPLET_MY_CONF_FILE, G_TYPE_INT, "Configuration", "shutdown time", myConfig.iShutdownTime, G_TYPE_INVALID); cd_logout_set_timer (); } CD_APPLET_LEAVE (); }
/* Fonction executee à chaque changement "paused". */ static void on_pause (DBusGProxy *player_proxy, gpointer data) // paused { CD_APPLET_ENTER; cd_debug ("MP : %s ()", __func__); myData.iPlayingStatus = PLAYER_PAUSED; if(! myData.cover_exist && (myData.cPlayingUri != NULL || myData.cTitle != NULL)) { if(myData.iPlayingStatus == PLAYER_PLAYING) { cd_musicplayer_apply_status_surface (PLAYER_PLAYING); } else { cd_musicplayer_apply_status_surface (PLAYER_PAUSED); } } else { CD_APPLET_REDRAW_MY_ICON; } CD_APPLET_LEAVE (); }
static void _on_dialog_destroyed (GldiModuleInstance *myApplet) { CD_APPLET_ENTER; myData.pDialog = NULL; CD_APPLET_LEAVE(); }
static gboolean _update_from_feeds (CDSharedMemory *pSharedMemory) { GldiModuleInstance *myApplet = pSharedMemory->pApplet; CD_APPLET_ENTER; if (! myData.bInit) // pas encore initialise, on vire le message d'attente. { cd_rssreader_free_item_list (myApplet); myData.pItemList = NULL; myData.bInit = TRUE; } // On parse le flux XML. if (pSharedMemory->cTaskBridge == NULL || *pSharedMemory->cTaskBridge == '\0') { cd_warning ("RSSresader : no data"); const gchar *cErrorMessage = (myConfig.cUrl == NULL ? D_("No URL is defined.") : D_("No data (no connection?)")); _insert_error_message (myApplet, cErrorMessage); if (myDesklet) { cd_applet_update_my_icon (myApplet); } myData.bUpdateIsManual = FALSE; if (myData.pTask->iPeriod > 20) { cd_message ("no data, will re-try in 20s"); gldi_task_change_frequency (myData.pTask, 20); // on re-essaiera dans 20s. } CD_APPLET_LEAVE (TRUE); } if (myData.pTask->iPeriod != myConfig.iRefreshTime) { cd_message ("revert to normal frequency"); gldi_task_change_frequency (myData.pTask, myConfig.iRefreshTime); } //g_print (" --> RSS: '%s'\n", myData.cTaskBridge); xmlDocPtr doc = xmlParseMemory (pSharedMemory->cTaskBridge, strlen (pSharedMemory->cTaskBridge)); g_free (pSharedMemory->cTaskBridge); pSharedMemory->cTaskBridge = NULL; if (doc == NULL) { cd_warning ("RSSresader : got invalid XML data"); const gchar *cErrorMessage = D_("Invalid data (invalid RSS/Atom feed?)"); _insert_error_message (myApplet, cErrorMessage); if (myDesklet) { cd_applet_update_my_icon (myApplet); } g_free (myData.PrevFirstTitle); myData.PrevFirstTitle = NULL; myData.bUpdateIsManual = FALSE; CD_APPLET_LEAVE (TRUE); } xmlNodePtr rss = xmlDocGetRootElement (doc); if (rss == NULL || (xmlStrcmp (rss->name, BAD_CAST "rss") != 0 && xmlStrcmp (rss->name, BAD_CAST "feed") != 0 && xmlStrcmp (rss->name, BAD_CAST "RDF") != 0)) { cd_warning ("RSSresader : got invalid XML data"); ///xmlCleanupParser (); xmlFreeDoc (doc); const gchar *cErrorMessage = D_("Invalid data (invalid RSS/Atom feed?)"); _insert_error_message (myApplet, cErrorMessage); if (myDesklet) { cd_applet_update_my_icon (myApplet); } g_free (myData.PrevFirstTitle); myData.PrevFirstTitle = NULL; myData.bUpdateIsManual = FALSE; CD_APPLET_LEAVE (TRUE); } // on extrait chaque item. GList *pNewItemList = NULL; CDRssItem *pItem = g_new0 (CDRssItem, 1); // on commence au debut de la liste (c'est le titre). pNewItemList = g_list_prepend (pNewItemList, pItem); if (myConfig.cUserTitle != NULL) pItem->cTitle = g_strdup (myConfig.cUserTitle); // ne sera pas ecrase par les donnees du flux. if (xmlStrcmp (rss->name, BAD_CAST "rss") == 0) // RSS { xmlAttrPtr attr = xmlHasProp (rss, BAD_CAST "version"); if (attr && attr->children) { cd_debug ("RSS version : %s", attr->children->content); } xmlNodePtr channel; for (channel = rss->children; channel != NULL; channel = channel->next) { if (xmlStrcmp (channel->name, BAD_CAST "channel") == 0) { pNewItemList = _parse_rss_item (channel, pItem, pNewItemList); // on parse le channel comme un item, ce qui fait que le titre du flux est considere comme un simple item. break; // un seul channel. } } } else if (xmlStrcmp (rss->name, BAD_CAST "RDF") == 0) // RDF { pNewItemList = _parse_rss_item (rss, pItem, pNewItemList); // on parse le premier groupe "channel" comme un item, ce qui fait que le titre du flux est considere comme un simple item. } else // Atom { xmlNodePtr feed = rss; gchar *cBaseUrl = NULL; // on recupere la base de l'URL, pour le cas ou les link seraient exprimes relativement a elle. gchar *str = g_strstr_len(myConfig.cUrl, 10, "://"); if (str) { str = strchr (str + 3, '/'); if (str) cBaseUrl = g_strndup (myConfig.cUrl, (gpointer)str-(gpointer)myConfig.cUrl); } pNewItemList = _parse_atom_item (feed, pItem, pNewItemList, cBaseUrl); // on parse le feed comme un item, ce qui fait que le titre du flux est considere comme un simple item. g_free (cBaseUrl); } pNewItemList = g_list_reverse (pNewItemList); xmlFreeDoc (doc); // ne pas utiliser xmlCleanupParser dans un thread ! // si aucune donnee, on l'affiche et on quitte. if (pNewItemList == NULL) { cd_debug ("RSS: aucune donnee"); const gchar *cErrorMessage = D_("No data"); _insert_error_message (myApplet, cErrorMessage); if (myDesklet) { cd_applet_update_my_icon (myApplet); } g_free (myData.PrevFirstTitle); myData.PrevFirstTitle = NULL; myData.bUpdateIsManual = FALSE; CD_APPLET_LEAVE (TRUE); } // si on est arrive a ce point, c'est qu'il n'y a pas eu d'erreur. // on vide l'ancienne liste d'items. cd_rssreader_free_item_list (myApplet); myData.pItemList = pNewItemList; // on met a jour le titre. if (myIcon->cName == NULL) // il faut mettre a jour le titre { if (myDock && myConfig.cUserTitle == NULL) // en mode desklet inutile, le titre sera redessine avec le reste. { pItem = myData.pItemList->data; if (pItem != NULL && pItem->cTitle != NULL) CD_APPLET_SET_NAME_FOR_MY_ICON (pItem->cTitle); } } // si aucun changement, on le signale, et si aucune erreur precedente, on quitte. pItem = (myData.pItemList && myData.pItemList->next ? myData.pItemList->next->data : NULL); gchar *cFirstTitle = (pItem ? pItem->cTitle : NULL); if (! cairo_dock_strings_differ (myData.PrevFirstTitle, cFirstTitle)) { cd_debug ("RSS: aucune modif"); if (myData.bUpdateIsManual) // L'update a ete manuel -> On affiche donc un dialogue meme s'il n'y a pas eu de changement { gldi_dialogs_remove_on_icon (myIcon); gldi_dialog_show_temporary_with_icon (D_("No modification"), myIcon, myContainer, 2000, // Suffisant vu que la MaJ est manuelle myDock ? "same icon" : MY_APPLET_SHARE_DATA_DIR"/"MY_APPLET_ICON_FILE); myData.bUpdateIsManual = FALSE; } if (! myData.bError) CD_APPLET_LEAVE (TRUE); } // on dessine le texte. if (myDesklet) { cd_applet_update_my_icon (myApplet); } // on avertit l'utilisateur. if (myData.PrevFirstTitle != NULL && myConfig.iNotificationType != 0) { if (myConfig.iNotificationType != 1) { gldi_dialogs_remove_on_icon (myIcon); gldi_dialog_show_temporary_with_icon (D_("This RSS feed has been modified..."), myIcon, myContainer, 1000*myConfig.iNotificationDuration, myDock ? "same icon" : MY_APPLET_SHARE_DATA_DIR"/"MY_APPLET_ICON_FILE); } if (myConfig.iNotificationType != 2) { CD_APPLET_DEMANDS_ATTENTION (myConfig.cNotificationAnimation, 3); /// myConfig.iNotificationDuration ?... } } g_free (myData.PrevFirstTitle); myData.PrevFirstTitle = g_strdup (cFirstTitle); myData.bUpdateIsManual = FALSE; myData.bError = FALSE; CD_APPLET_LEAVE (TRUE); }
static void _show_window (GtkMenuItem *menu_item, Icon *pIcon) { CD_APPLET_ENTER; gldi_window_show (pIcon->pAppli); CD_APPLET_LEAVE (); }
void cd_shortcuts_on_drive_event (CairoDockFMEventType iEventType, const gchar *cURI, GldiModuleInstance *myApplet) { g_return_if_fail (cURI != NULL); CD_APPLET_ENTER; //\________________ Manage event about this mount point GList *pIconsList = CD_APPLET_MY_ICONS_LIST; GldiContainer *pContainer = CD_APPLET_MY_ICONS_LIST_CONTAINER; CD_APPLET_LEAVE_IF_FAIL (pContainer != NULL); _manage_event_on_drive (iEventType, cURI, pIconsList, pContainer, myApplet); //\________________ Update bookmarks which are linked to this mount point if (!myConfig.bListBookmarks || pIconsList == NULL) { CD_APPLET_LEAVE(); } GList *ic; Icon *icon; gboolean bIsMounted; gchar *cTargetURI = cairo_dock_fm_is_mounted (cURI, &bIsMounted); if (cTargetURI != NULL) // optimized version. { //g_print ("test bookmarks in '%s'...\n", cTargetURI); pIconsList = CD_APPLET_MY_ICONS_LIST; for (ic = pIconsList; ic != NULL; ic = ic->next) { icon = ic->data; if (icon->iGroup == (CairoDockIconGroup) CD_BOOKMARK_GROUP) { if (strncmp (cTargetURI, icon->cBaseURI, strlen (cTargetURI)) == 0) { //g_print ("bookmark '%s' is located in a mount point which has changed (%s)\n", icon->cBaseURI, cTargetURI); gchar *cName = NULL, *cRealURI = NULL, *cIconName = NULL; int iVolumeID = 0; gboolean bIsDirectory = FALSE; double fOrder; if (cairo_dock_fm_get_file_info (icon->cBaseURI, &cName, &cRealURI, &cIconName, &bIsDirectory, &iVolumeID, &fOrder, CAIRO_DOCK_FM_SORT_BY_NAME)) { //g_print (" -> %s (%d)\n", cIconName, bIsMounted); if (bIsMounted/** || cIconName == NULL*/) { gchar *str; /* if it was previously an unmounted bookmark, just * remove the 'unmounted' part to avoid changing the * name (when mounted, gvfs returns the path whereas * we want to display the bookmark name). Note that * the icon might also changes (it was NULL when the * bookmark was not mounted), and we can use this * new one which is probably more accurate. */ if ((str = strchr (icon->cName, '\n')) != NULL) *str = '\0'; else { g_free (icon->cName); icon->cName = cName; } } else { g_free (icon->cName); icon->cName = g_strdup_printf ("%s\n[%s]", cName, D_("Unmounted")); g_free (cName); } g_free (icon->cCommand); icon->cCommand = cRealURI; g_free (icon->cFileName); icon->cFileName = cIconName; icon->iVolumeID = iVolumeID; cairo_dock_load_icon_buffers (icon, pContainer); } } } } g_free (cTargetURI); } CD_APPLET_LEAVE(); }
gboolean cd_xkbd_render_step_cairo (Icon *pIcon, GldiModuleInstance *myApplet) { CD_APPLET_ENTER; double f = CD_APPLET_GET_TRANSITION_FRACTION (); //g_print ("%s (%.2f)\n", __func__, f); int iWidth, iHeight; CD_APPLET_GET_MY_ICON_EXTENT (&iWidth, &iHeight); CD_APPLET_LEAVE_IF_FAIL (iHeight != 0, TRUE); ///cairo_dock_erase_cairo_context (myDrawContext); CD_APPLET_START_DRAWING_MY_ICON_OR_RETURN_CAIRO (FALSE); if (myData.bgImage.pSurface != NULL) { cairo_set_source_surface ( myDrawContext, myData.bgImage.pSurface, 0., 0.); cairo_paint (myDrawContext); } double dx, dy, fScale; if (myData.pOldImage != NULL && 1-f > .01) { fScale = (double)iWidth / myData.pOldImage->iWidth; // scale to fill the icon horizontally if (fScale * myData.pOldImage->iHeight > iHeight) // if the text is too height, scale down { fScale = (double)iHeight / myData.pOldImage->iHeight; // that's smaller than the previous value. } dx = (iWidth - fScale * myData.pOldImage->iWidth)/2; // center horizontally dy = iHeight - fScale * myData.pOldImage->iHeight; // bottom (we draw the caps/num lock on top). cairo_save (myDrawContext); cairo_translate (myDrawContext, dx, dy); cairo_scale (myDrawContext, fScale, fScale); // keep ratio cairo_set_source_surface ( myDrawContext, myData.pOldImage->pSurface, 0, 0); cairo_paint_with_alpha (myDrawContext, 1-f); cairo_restore (myDrawContext); } if (myData.pCurrentImage != NULL) { fScale = (double)iWidth / myData.pCurrentImage->iWidth; // scale to fill the icon horizontally if (fScale * myData.pCurrentImage->iHeight > iHeight) // if the text is too height, scale down { fScale = (double)iHeight / myData.pCurrentImage->iHeight; // that's smaller than the previous value. } dx = (iWidth - fScale * myData.pCurrentImage->iWidth)/2; // center horizontally dy = iHeight - fScale * myData.pCurrentImage->iHeight; // bottom (we draw the caps/num lock on top). cairo_save (myDrawContext); cairo_translate (myDrawContext, dx, dy); cairo_scale (myDrawContext, fScale, fScale); // keep ratio cairo_set_source_surface ( myDrawContext, myData.pCurrentImage->pSurface, 0, 0); cairo_paint_with_alpha (myDrawContext, f); cairo_restore (myDrawContext); } CD_APPLET_FINISH_DRAWING_MY_ICON_CAIRO; CD_APPLET_LEAVE (TRUE); }
gboolean cd_xkbd_render_step_opengl (Icon *pIcon, GldiModuleInstance *myApplet) { g_return_val_if_fail (myData.pCurrentImage != NULL, FALSE); CD_APPLET_ENTER; double f = CD_APPLET_GET_TRANSITION_FRACTION (); cd_debug ("%s (%.2f; %.2fx%.2f)", __func__, f, myIcon->fWidth, myIcon->fHeight); int iWidth, iHeight; CD_APPLET_GET_MY_ICON_EXTENT (&iWidth, &iHeight); gldi_gl_container_set_perspective_view_for_icon (myIcon); glScalef (1., -1., 1.); _cairo_dock_enable_texture (); _cairo_dock_set_blend_alpha (); _cairo_dock_set_alpha (1.); // fond if (myData.bgImage.iTexture != 0) cairo_dock_apply_texture_at_size (myData.bgImage.iTexture, iWidth, iHeight); double fTheta = - 45. + f * 90.; // -45 -> 45 glTranslatef (0., 0., - iWidth * sqrt(2)/2 * cos (fTheta/180.*G_PI)); // pour faire tenir le cube dans la fenetre. glEnable (GL_DEPTH_TEST); // image precedente. int w=0, h; if (fTheta < 25 && myData.pOldImage != NULL) // inutile de dessiner si elle est derriere l'image courante, par l'effet de perspective (en fait 22.5, mais bizarrement ca a l'air un peu trop tot). { w = iWidth * myConfig.fTextRatio; // fill horizontally h = myData.pOldImage->iHeight * (double)w/myData.pOldImage->iWidth; // keep ratio if (h > iHeight * myConfig.fTextRatio) { w *= iHeight * myConfig.fTextRatio / h; h = iHeight * myConfig.fTextRatio; } glPushMatrix (); glRotatef (45. + fTheta, 0., 1., 0.); // 0 -> 90 glTranslatef (0., (-iHeight + h)/2, w/2); // H center, V bottom cairo_dock_apply_texture_at_size (myData.pOldImage->iTexture, w, h); glPopMatrix (); } // image courante a 90deg. w = iWidth * myConfig.fTextRatio; // fill horizontally h = myData.pCurrentImage->iHeight * (double)w/myData.pCurrentImage->iWidth; // keep ratio if (h > iHeight * myConfig.fTextRatio) { w *= iHeight * myConfig.fTextRatio / h; h = iHeight * myConfig.fTextRatio; } /**glRotatef (45. + fTheta, 0., 1., 0.); // 0 -> 90 glTranslatef (- (w ? w : iWidth)/2, 0., 0.); glRotatef (-90., 0., 1., 0.);*/ glRotatef (-45. + fTheta, 0., 1., 0.); // -90 -> 0 glTranslatef (0., (-iHeight + h)/2, w/2); // H center, V bottom cairo_dock_apply_texture_at_size (myData.pCurrentImage->iTexture, w, h); glDisable (GL_DEPTH_TEST); _cairo_dock_disable_texture (); if (myDock) { gldi_gl_container_set_ortho_view (myContainer); } CD_APPLET_LEAVE (TRUE); }
void cd_shortcuts_on_bookmarks_event (CairoDockFMEventType iEventType, const gchar *cURI, GldiModuleInstance *myApplet) { static int iTime = 0; iTime ++; CD_APPLET_ENTER; //g_print ("%s (%d)\n", __func__, iEventType); GList *pIconsList = CD_APPLET_MY_ICONS_LIST; GList *pOldBookmarkList; Icon *icon; GList *ic; // optimization: skip the disks and networks, and point on the first bookmark. for (ic = pIconsList; ic != NULL; ic = ic->next) { icon = ic->data; if (icon->iGroup == (CairoDockIconGroup) CD_BOOKMARK_GROUP) break; } /* Note that since the first bookmark is always the Home Folder, * 'pIconsList' will never change when inserting/removing a bookmark. */ pIconsList = ic; GldiContainer *pContainer = CD_APPLET_MY_ICONS_LIST_CONTAINER; CD_APPLET_LEAVE_IF_FAIL (pContainer != NULL); // split the list: items can have been removed pOldBookmarkList = pIconsList->next; pIconsList->next = NULL; pOldBookmarkList->prev = NULL; // Bookmarks file has been modified if (iEventType == CAIRO_DOCK_FILE_CREATED || iEventType == CAIRO_DOCK_FILE_MODIFIED) { cd_message ("The bookmarks list has changed"); //\____________________ Read bookmarks file gchar *cContent = NULL; gsize length=0; GError *erreur = NULL; g_file_get_contents (myData.cBookmarksURI, &cContent, &length, &erreur); if (erreur != NULL) { cd_warning ("when trying to get the bookmarks : %s", erreur->message); g_error_free (erreur); } else { gchar **cBookmarksList = g_strsplit (cContent, "\n", -1); g_free (cContent); //\____________________ Read the content. /* Bookmarks are listed in the order of the file; we need to * reorder each icon in case a bookmark has changed its place, or * if a new one appeared (the first one is always the Home Folder). */ double fCurrentOrder = 1.; gchar *cOneBookmark; Icon *pNewIcon, *pExistingIcon; GList *pExistingIconNode; const gchar *cUserName; int i; for (i = 0; cBookmarksList[i] != NULL; i ++) { cOneBookmark = cBookmarksList[i]; if (*cOneBookmark == '\0' || *cOneBookmark == '#') { g_free (cOneBookmark); continue; } // Grab the custom name if any cUserName = _get_custom_name_and_uri (cBookmarksList[i], &cOneBookmark); // Check if the icon already exists and has changed pExistingIconNode = _get_item_with_base_uri_icon (pOldBookmarkList, cOneBookmark); if (pExistingIconNode != NULL) { pExistingIcon = pExistingIconNode->data; // move this node to the subdock icons list pOldBookmarkList = g_list_delete_link (pOldBookmarkList, pExistingIconNode); pIconsList = g_list_insert (pIconsList, pExistingIcon, 1); // after the home, will be sorted later if (cUserName && g_strcmp0 (pExistingIcon->cName, cUserName) != 0) { CD_APPLET_REMOVE_ICON_FROM_MY_ICONS_LIST (pExistingIcon); // will destroy it pExistingIcon = NULL; } else { fCurrentOrder++; g_free (cOneBookmark); } } else pExistingIcon = NULL; if (pExistingIcon == NULL) { pNewIcon = _cd_shortcuts_get_icon (cOneBookmark, cUserName, fCurrentOrder); if (pNewIcon) { CD_APPLET_ADD_ICON_IN_MY_ICONS_LIST (pNewIcon); fCurrentOrder++; } else { cd_warning ("couldn't get info on bookmark '%s'", cOneBookmark); g_free (cOneBookmark); } } } g_free (cBookmarksList); _remove_old_icons_and_free_list (pOldBookmarkList); /* Again, since 'Home Folder' is always the first bookmark, * the head of the list won't change even if there are only bookmarks * (so we don't need to re-assigne it to the container). */ cairo_dock_sort_icons_by_order (pIconsList); } } CD_APPLET_LEAVE(); }
static void _cd_crypt_import_stash (GtkMenuItem *menu_item, gpointer data) { CD_APPLET_ENTER; crypt_dock_import_stash_wizard (); CD_APPLET_LEAVE(); }
static gboolean _on_click_item (GtkWidget *pWidget, GdkEventButton* pButton, CDQuickBrowserItem *pItem) { g_return_val_if_fail (pItem != NULL, FALSE); GldiModuleInstance *myApplet = pItem->pApplet; CD_APPLET_ENTER; if (pButton->button == 3) // right click { gchar *cUri = g_filename_to_uri (pItem->cPath, NULL, NULL); g_return_val_if_fail (cUri != NULL, FALSE); GtkWidget *pMenu = gldi_menu_new (NULL); GList *pApps = cairo_dock_fm_list_apps_for_file (cUri); if (pApps != NULL) { GtkWidget *pSubMenu = CD_APPLET_ADD_SUB_MENU_WITH_IMAGE (D_("Open with"), pMenu, GLDI_ICON_NAME_OPEN); cd_quick_browser_free_apps_list (myApplet); GList *a; gchar **pAppInfo; gchar *cIconPath; for (a = pApps; a != NULL; a = a->next) { pAppInfo = a->data; if (pAppInfo[2] != NULL) cIconPath = cairo_dock_search_icon_s_path (pAppInfo[2], cairo_dock_search_icon_size (GTK_ICON_SIZE_MENU)); else cIconPath = NULL; gpointer *data = g_new (gpointer, 2); data[0] = pItem; data[1] = pAppInfo[1]; myData.pAppList = g_list_prepend (myData.pAppList, data); // to save the exec command CD_APPLET_ADD_IN_MENU_WITH_STOCK_AND_DATA (pAppInfo[0], cIconPath, _cd_launch_with, pSubMenu, data); g_free (cIconPath); g_free (pAppInfo[0]); g_free (pAppInfo[2]); g_free (pAppInfo); } g_list_free (pApps); } CD_APPLET_ADD_IN_MENU_WITH_STOCK_AND_DATA (D_("Open parent folder"), GLDI_ICON_NAME_DIRECTORY, _cd_open_parent, pMenu, pItem); CD_APPLET_ADD_IN_MENU_WITH_STOCK_AND_DATA (D_("Copy the location"), GLDI_ICON_NAME_COPY, _cd_copy_location, pMenu, pItem); gtk_widget_show_all (pMenu); gtk_menu_popup (GTK_MENU (pMenu), NULL, NULL, NULL, // popup on mouse. NULL, 1, gtk_get_current_event_time ()); g_free (cUri); CD_APPLET_LEAVE (TRUE); // do not remove quick_browser menu now } CD_APPLET_LEAVE (FALSE); }
gboolean cd_clock_update_with_time (GldiModuleInstance *myApplet) { CD_APPLET_ENTER; //\________________ On recupere l'heure courante. time_t epoch = (time_t) time (NULL); _get_current_time (epoch, myApplet); //\________________ On change la date si necessaire. int iWidth, iHeight; CD_APPLET_GET_MY_ICON_EXTENT (&iWidth, &iHeight); gboolean bNewDate = (myData.currentTime.tm_mday != myData.iLastCheckedDay || myData.currentTime.tm_mon != myData.iLastCheckedMonth || myData.currentTime.tm_year != myData.iLastCheckedYear); if (bNewDate) { strftime (s_cDateBuffer, CD_CLOCK_DATE_BUFFER_LENGTH, "%a %d %b", &myData.currentTime); myData.iLastCheckedDay = myData.currentTime.tm_mday; myData.iLastCheckedMonth = myData.currentTime.tm_mon; myData.iLastCheckedYear = myData.currentTime.tm_year; } if (CD_APPLET_MY_CONTAINER_IS_OPENGL && myConfig.bOldStyle && myConfig.iShowDate == CAIRO_DOCK_INFO_ON_ICON) { if (bNewDate || myData.iDateTexture == 0) { if (myData.iDateTexture != 0) _cairo_dock_delete_texture (myData.iDateTexture); double fScale = (double) iWidth / (double) myData.DimensionData.width; GldiTextDescription labelDescription; memset (&labelDescription, 0, sizeof (GldiTextDescription)); gldi_text_description_set_font (&labelDescription, (gchar*)"Sans 8"); // casted and then set to null labelDescription.fColorStart.rgba.red = myConfig.fDateColor[0]; labelDescription.fColorStart.rgba.green = myConfig.fDateColor[1]; labelDescription.fColorStart.rgba.blue = myConfig.fDateColor[2]; labelDescription.fColorStart.rgba.alpha = 1.; labelDescription.bNoDecorations = TRUE; cairo_surface_t *pDateSurface = cairo_dock_create_surface_from_text_full (s_cDateBuffer, &labelDescription, fScale, iWidth, &myData.iDateWidth, &myData.iDateHeight); //g_print ("date : %dx%d\n", myData.iDateWidth, myData.iDateHeight); myData.iDateTexture = cairo_dock_create_texture_from_surface (pDateSurface); cairo_surface_destroy (pDateSurface); labelDescription.cFont = NULL; gldi_text_description_reset (&labelDescription); } } if (bNewDate && myConfig.iShowDate == CAIRO_DOCK_INFO_ON_LABEL) { CD_APPLET_SET_NAME_FOR_MY_ICON (s_cDateBuffer); } //\________________ On dessine avec cette heure. myData.iSmoothAnimationStep = 0; if (myConfig.bOldStyle) { if (CD_APPLET_MY_CONTAINER_IS_OPENGL) cd_clock_render_analogic_to_texture (myApplet, iWidth, iHeight, &myData.currentTime, 0.); else cd_clock_draw_analogic (myApplet, iWidth, iHeight, &myData.currentTime); } else { cd_clock_draw_text (myApplet, iWidth, iHeight, &myData.currentTime); ///if (CD_APPLET_MY_CONTAINER_IS_OPENGL) // on ne sait pas bien dessiner du texte, donc on le fait en cairo, et on transfere tout sur notre texture. /// cairo_dock_update_icon_texture (myIcon); } ///CD_APPLET_REDRAW_MY_ICON; //\________________ On teste les alarmes et les taches. if (!myConfig.bShowSeconds || myData.currentTime.tm_min != myData.iLastCheckedMinute) // un g_timeout de 1min ne s'effectue pas forcement a exectement 1 minute d'intervalle, et donc pourrait "sauter" la minute de l'alarme, d'ou le test sur bShowSeconds dans le cas ou l'applet ne verifie que chaque minute. { myData.iLastCheckedMinute = myData.currentTime.tm_min; // les alarmes. CDClockAlarm *pAlarm; guint i; for (i = 0; i < myConfig.pAlarms->len; i ++) { pAlarm = g_ptr_array_index (myConfig.pAlarms, i); if (myData.currentTime.tm_hour == pAlarm->iHour && myData.currentTime.tm_min == pAlarm->iMinute) { gboolean bShowAlarm = FALSE, bRemoveAlarm = FALSE; if (pAlarm->iDayOfWeek > 0) { if (pAlarm->iDayOfWeek == 1) bShowAlarm = TRUE; else if (pAlarm->iDayOfWeek - 1 == myData.currentTime.tm_wday) bShowAlarm = TRUE; else if (myData.currentTime.tm_wday == 0 || myData.currentTime.tm_wday == 6) // week-end { if (pAlarm->iDayOfWeek == 9) bShowAlarm = TRUE; } else if (pAlarm->iDayOfWeek == 8) bShowAlarm = TRUE; } else if (pAlarm->iDayOfMonth > 0) bShowAlarm = (pAlarm->iDayOfMonth - 1 == myData.currentTime.tm_mday); else // c'est une alarme qui ne se repete pas. { bShowAlarm = TRUE; bRemoveAlarm = TRUE; } if (bShowAlarm) { cd_message ("Dring ! %s", pAlarm->cMessage); gldi_dialog_show_temporary (pAlarm->cMessage, myIcon, myContainer, 60e3); if (pAlarm->cCommand != NULL) { if (myData.iAlarmPID > 0) { kill (myData.iAlarmPID, 1); myData.iAlarmPID = 0; } GError *erreur = NULL; gchar **argv = g_strsplit (pAlarm->cCommand, " ", -1); g_spawn_async (NULL, argv, NULL, 0, NULL, NULL, &myData.iAlarmPID, &erreur); if (erreur != NULL) { cd_warning ("clock : when trying to execute '%s' : %s", pAlarm->cCommand, erreur->message); g_error_free (erreur); myData.iAlarmPID = 0; } g_strfreev (argv); cd_message (" --> child_pid : %d", myData.iAlarmPID); } } if (bRemoveAlarm) { cd_message ("Cette alarme ne sera pas repetee"); g_ptr_array_remove_index (myConfig.pAlarms, i); cd_clock_free_alarm (pAlarm); /// A FAIRE : effacer l'heure dans le fichier de conf pour cette alarme. } } } // display missed tasks. if (!myData.bTaskCheckedOnce) { myData.bTaskCheckedOnce = TRUE; myData.pMissedTasks = cd_clock_get_missed_tasks (myApplet); } if (myData.pMissedTasks != NULL) // so if the dialog was closed before we could acknowledge all the tasks, it will re-open. { CDClockTask *pTask = myData.pMissedTasks->data; gchar *cMessage = _make_missed_task_message (pTask, myApplet); CairoDialogAttr attr; memset (&attr, 0, sizeof (CairoDialogAttr)); attr.cText = cMessage; attr.bUseMarkup = TRUE; attr.cImageFilePath = (gchar *)MY_APPLET_SHARE_DATA_DIR"/icon-task.png"; const gchar *cButtonsImage[3] = {"ok", NULL, NULL}; if (myData.pMissedTasks->next != NULL) { cButtonsImage[0] = "cancel"; cButtonsImage[1] = "next.png"; } attr.cButtonsImage = cButtonsImage; attr.pActionFunc = (CairoDockActionOnAnswerFunc)_on_next_missed_task; attr.pUserData = myApplet; attr.pFreeDataFunc = NULL; attr.iTimeLength = 0; attr.pIcon = myIcon; attr.pContainer = myContainer; gldi_dialog_new (&attr); g_free (cMessage); } // display next task. if (myData.pNextTask != NULL) { //g_print ("next task : %s\n", myData.pNextTask->cTitle); struct tm st; st.tm_min = myData.pNextTask->iMinute; st.tm_hour = myData.pNextTask->iHour; st.tm_mday = myData.pNextTask->iDay; st.tm_mon = myData.pNextTask->iMonth; st.tm_year = myData.pNextTask->iYear - 1900; st.tm_sec = 0; st.tm_isdst = myData.currentTime.tm_isdst; time_t t = mktime (&st); //g_print ("time : %ld, task : %ld\n", epoch, t); if (t < epoch) // la tache est depassee. { // acknowledge this task myData.pNextTask->bAcknowledged = TRUE; myData.pBackend->update_task (myData.pNextTask, myApplet); // look for next task. myData.pNextTask = cd_clock_get_next_scheduled_task (myApplet); } else if (t < epoch + 15*60 && t >= epoch) { if (t < epoch + 60) { if (! myData.pNextTask->bFirstWarning) { //g_print ("first warning\n"); myData.pNextTask->bFirstWarning = TRUE; gchar *cText = g_strdup_printf ("%s\n<b>%s</b>\n %s\n\n%s", D_("It's time for the following task:"), myData.pNextTask->cTitle?myData.pNextTask->cTitle:D_("No title"), myData.pNextTask->cText?myData.pNextTask->cText:"", D_("Repeat this message every:")); _task_warning (myData.pNextTask, cText); g_free (cText); } } else if (! myData.pNextTask->b15mnWarning) { //g_print ("15 mn warning\n"); myData.pNextTask->b15mnWarning = TRUE; gchar *cText = g_strdup_printf ("%s\n<b>%s</b>\n %s", D_("This task will begin in 15 minutes:"), myData.pNextTask->cTitle?myData.pNextTask->cTitle:D_("No title"), myData.pNextTask->cText?myData.pNextTask->cText:""); CairoDialogAttr attr; memset (&attr, 0, sizeof (CairoDialogAttr)); attr.cText = (gchar *)cText; attr.cImageFilePath = (gchar *)MY_APPLET_SHARE_DATA_DIR"/icon-task.png"; attr.iTimeLength = 60e3; attr.bUseMarkup = TRUE; attr.pIcon = myIcon; attr.pContainer = myContainer; gldi_dialog_new (&attr); CD_APPLET_DEMANDS_ATTENTION (NULL, 60); } } // display next anniversary if it is scheduled in less than 1 day, because anniversary require time to prepare. if (myData.pNextAnniversary != NULL) { if (!myData.pNextAnniversary->b1DayWarning && ! myData.pNextAnniversary->bFirstWarning && ! myData.pNextAnniversary->b15mnWarning) { GDate* pCurrentDate = g_date_new_dmy (myData.currentTime.tm_mday, myData.currentTime.tm_mon + 1, myData.currentTime.tm_year+1900); GDate* pAnnivDate = g_date_new_dmy (myData.pNextAnniversary->iDay, myData.pNextAnniversary->iMonth + 1, myData.currentTime.tm_year+1900); gint iDaysToNextAnniversary = g_date_days_between (pCurrentDate, pAnnivDate); if (iDaysToNextAnniversary >= 0 && iDaysToNextAnniversary <= 1) { myData.pNextAnniversary->b1DayWarning = TRUE; gchar *cText = g_strdup_printf ("%s\n<b>%s</b>\n %s\n\n%s", iDaysToNextAnniversary == 0 ? D_("Today is the following anniversary:") : D_("Tomorrow is the following anniversary:"), myData.pNextTask->cTitle?myData.pNextTask->cTitle:D_("No title"), myData.pNextTask->cText?myData.pNextTask->cText:"", D_("Repeat this message every:")); _task_warning (myData.pNextTask, cText); g_free (cText); myData.pNextAnniversary = cd_clock_get_next_anniversary (myApplet); } g_date_free (pCurrentDate); g_date_free (pAnnivDate); } } } } CD_APPLET_LEAVE(TRUE); }