Logo Search packages:      
Sourcecode: cairo-dock-plugins version File versions  Download package

applet-notifications.c

/**
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail    : see the 'copyright' file.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#define _BSD_SOURCE
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <glib/gstdio.h>

#include "applet-struct.h"
#include "applet-dnd2share.h"
#include "applet-notifications.h"

static void _clear_history (GtkMenuItem *menu_item, gpointer data)
{
      CD_APPLET_ENTER;
      int iAnswer = cairo_dock_ask_question_and_wait (D_("Clear the list of the recently uploaded files ?"), myIcon, myContainer);
      if (iAnswer == GTK_RESPONSE_YES)
      {
            cd_dnd2share_clear_working_directory ();
            cd_dnd2share_clear_history ();
      }
      CD_APPLET_LEAVE ();
}

static void _show_local_file (GtkMenuItem *menu_item, CDUploadedItem *pItem)
{
      CD_APPLET_ENTER;
      if (pItem->iFileType == CD_TYPE_TEXT)
      {
            cd_dnd2share_copy_url_to_clipboard (pItem->cLocalPath);
            if (myConfig.bEnableDialogs)
            {
                  cairo_dock_remove_dialog_if_any (myIcon);
                  cairo_dock_show_temporary_dialog_with_icon (D_("The text has been pasted in the clipboard.\nYou can retrieve it with CTRL+v."),
                        myIcon,
                        myContainer,
                        myConfig.dTimeDialogs,
                        MY_APPLET_SHARE_DATA_DIR"/"MY_APPLET_ICON_FILE);
            }
      }
      else
      {
            if (g_file_test (pItem->cLocalPath, G_FILE_TEST_EXISTS))
                  cairo_dock_fm_launch_uri (pItem->cLocalPath);
            else
            {
                  gchar *cPreviewPath = g_strdup_printf ("%s/%s", myData.cWorkingDirPath, pItem->cItemName);
                  if (g_file_test (cPreviewPath, G_FILE_TEST_EXISTS))
                  {
                        cairo_dock_fm_launch_uri (cPreviewPath);
                  }
                  else
                  {
                        cd_warning ("couldn't find the orignial file nor a preview of it");
                        cairo_dock_remove_dialog_if_any (myIcon);
                        cairo_dock_show_temporary_dialog_with_icon (D_("Sorry, couldn't find the orignial file nor a preview of it."),
                              myIcon,
                              myContainer,
                              myConfig.dTimeDialogs,
                              MY_APPLET_SHARE_DATA_DIR"/"MY_APPLET_ICON_FILE);
                  }
                  g_free (cPreviewPath);
            }
      }
      CD_APPLET_LEAVE ();
}
static void _remove_from_history (GtkMenuItem *menu_item, CDUploadedItem *pItem)
{
      CD_APPLET_ENTER;
      cd_dnd2share_remove_one_item (pItem);
      CD_APPLET_LEAVE ();
}

static void _copy_url_into_clipboard (GtkMenuItem *menu_item, const gchar *cURL)
{
      CD_APPLET_ENTER;
      cd_dnd2share_copy_url_to_clipboard (cURL);
      if (myConfig.bEnableDialogs)
      {
            cairo_dock_remove_dialog_if_any (myIcon);
            cairo_dock_show_temporary_dialog_with_icon (D_("The URL has been stored into the clipboard.\nJust use 'CTRL+v' to paste it anywhere."),
                  myIcon,
                  myContainer,
                  myConfig.dTimeDialogs,
                  MY_APPLET_SHARE_DATA_DIR"/"MY_APPLET_ICON_FILE);
      }
      CD_APPLET_LEAVE ();
}

static void _store_last_url (gboolean bIntoClipboard)
{
      if (myData.cLastURL == NULL)
      {
            cairo_dock_remove_dialog_if_any (myIcon);
            cairo_dock_show_temporary_dialog_with_icon (myConfig.iNbItems != 0 ?
                  D_("No uploaded file available\n.Just drag'n drop a file on the icon to upload it") :
                  D_("No uploaded file available\n.Consider activating the history if you want the applet remembers previous uploads."),
            myIcon,
            myContainer,
            myConfig.dTimeDialogs,
            MY_APPLET_SHARE_DATA_DIR"/"MY_APPLET_ICON_FILE);
      }
      else
      {
            if (bIntoClipboard)
                  cd_dnd2share_copy_url_to_clipboard (myData.cLastURL);
            else
                  cd_dnd2share_copy_url_to_primary (myData.cLastURL);
            
            if (myConfig.bEnableDialogs)
            {
                  cairo_dock_remove_dialog_if_any (myIcon);
                  cairo_dock_show_temporary_dialog_with_icon (bIntoClipboard ? 
                              D_("The current URL has been stored into the clipboard.\nJust use 'CTRL+v' to paste it anywhere.") :
                              D_("The current URL has been stored into the selection.\nJust middle-click to paste it anywhere."),
                        myIcon,
                        myContainer,
                        myConfig.dTimeDialogs,
                        MY_APPLET_SHARE_DATA_DIR"/"MY_APPLET_ICON_FILE);
            }
      }
}

static void _on_drop_data (const gchar *cMyData)
{
      CDFileType iFileType = CD_UNKNOWN_TYPE;
      gchar *cFilePath = NULL;
      if( strncmp(cMyData, "file://", 7) == 0)
      {
            // Les formats supportés par Uppix.net sont : GIF, JPEG, PNG, Flash (SWF or SWC), BMP, PSD, TIFF, JP2, JPX,
            // JB2, JPC, WBMP, and XBM.
            // ... mais l'applet ne prendra en charge que les plus utilisés :
            
            cFilePath = g_filename_from_uri (cMyData, NULL, NULL);  // on passe en encodage UTF-8.
            g_return_if_fail (cFilePath != NULL);
            
            if ( strchr(cFilePath, ',') != NULL) // S'il y une virgule, curl n'aime pas
            {
                  myData.cTmpFilePath = g_strdup ("/tmp/dnd2share-file_with_comma.XXXXXX");
                  int fds = mkstemp (myData.cTmpFilePath);
                  if (fds == -1)
                  {
                        g_free (myData.cTmpFilePath);
                        myData.cTmpFilePath = NULL;
                        return;
                  }
                  close(fds);
                  
                  gchar *cCommandCopyFileWithComma = g_strdup_printf ("cp '%s' '%s'", cFilePath, myData.cTmpFilePath); // copie du fichier dans tmp.
                  int r = system (cCommandCopyFileWithComma);
                  g_free (cCommandCopyFileWithComma);
                  g_free (cFilePath);
                  cFilePath = g_strdup (myData.cTmpFilePath);  // on utilise le fichier tmp, il sera efface a la fin de l'upload.
            }
            
            guint64 iSize;
            time_t iLastModificationTime;
            gchar *cMimeType = NULL;
            int iUID, iGID, iPermissionsMask;
            if (cairo_dock_fm_get_file_properties (cMyData, &iSize, &iLastModificationTime, &cMimeType, &iUID, &iGID, &iPermissionsMask))
            {
                  if (cMimeType != NULL)
                  {
                        g_print ("cMimeType : %s (%s)\n", cMimeType, cMyData);
                        if (strncmp (cMimeType, "image", 5) == 0)
                              iFileType = CD_TYPE_IMAGE;
                        else if (strncmp (cMimeType, "video", 5) == 0)
                              iFileType = CD_TYPE_VIDEO;
                  }
                  g_free (cMimeType);
            }
            
            if (iFileType == CD_UNKNOWN_TYPE)
            {
                  if (g_str_has_suffix(cMyData,"jpg") 
                        || g_str_has_suffix(cMyData,"JPG")
                        || g_str_has_suffix(cMyData,"png")
                        || g_str_has_suffix(cMyData,"PNG")
                        || g_str_has_suffix(cMyData,"jpeg")
                        || g_str_has_suffix(cMyData,"JPEG")
                        || g_str_has_suffix(cMyData,"gif")
                        || g_str_has_suffix(cMyData,"GIF")
                        || g_str_has_suffix(cMyData,"bmp")
                        || g_str_has_suffix(cMyData,"BMP")
                        || g_str_has_suffix(cMyData,"TIFF")
                        || g_str_has_suffix(cMyData,"tiff"))
                        iFileType = CD_TYPE_IMAGE;
                  else if (g_str_has_suffix(cMyData,"avi") 
                        || g_str_has_suffix(cMyData,"AVI")
                        || g_str_has_suffix(cMyData,"ogg")
                        || g_str_has_suffix(cMyData,"OGG")
                        || g_str_has_suffix(cMyData,"ogv")
                        || g_str_has_suffix(cMyData,"OGV")
                        || g_str_has_suffix(cMyData,"mp4")
                        || g_str_has_suffix(cMyData,"MP4")
                        || g_str_has_suffix(cMyData,"mov")
                        || g_str_has_suffix(cMyData,"MOV"))
                        iFileType = CD_TYPE_VIDEO;
            }
      }
      else  // c'est du texte.
      {
            // g_print ("TEXT\n");
            iFileType = CD_TYPE_TEXT;
      }
      
      if (iFileType == CD_UNKNOWN_TYPE)
      {
            iFileType = CD_TYPE_FILE;
            g_print ("we'll consider this as an archive.");
      }
      cd_dnd2share_launch_upload (cFilePath ? cFilePath : cMyData, iFileType);
      g_free (cFilePath);
}

static void _get_image (GtkClipboard *clipboard, GdkPixbuf *pixbuf, gpointer data)
{
      g_return_if_fail (pixbuf != NULL);
      if (myData.cTmpFilePath != NULL)
      {
            cd_warning ("Please wait the current upload is finished before starting a new one.");
            return ;
      }
      myData.cTmpFilePath = g_strdup ("/tmp/dnd2share-tmp-file.XXXXXX");
      int fds = mkstemp (myData.cTmpFilePath);
      if (fds == -1)
      {
            g_free (myData.cTmpFilePath);
            myData.cTmpFilePath = NULL;
            return ;
      }
      close(fds);
      
      CD_APPLET_ENTER;
      gboolean bSaved = gdk_pixbuf_save (pixbuf,
            myData.cTmpFilePath,
            "png",
            NULL,
            NULL);
      CD_APPLET_LEAVE_IF_FAIL (bSaved);
      //g_return_if_fail (bSaved);
      
      cd_dnd2share_launch_upload (myData.cTmpFilePath, CD_TYPE_IMAGE);
      CD_APPLET_LEAVE ();
}
static void _get_text (GtkClipboard *clipboard, const gchar *cText, gpointer data)
{
      g_return_if_fail (cText != NULL);
      CD_APPLET_ENTER;
      gchar *cFilePath = NULL;
      const gchar *cDropData = NULL;
      if ( *cText == '/' && g_file_test (cText, G_FILE_TEST_EXISTS) )
            cFilePath = g_strdup_printf ("file://%s", cText);
      else
            cDropData = cText;
      
      _on_drop_data (cFilePath ? cFilePath : cDropData);
      CD_APPLET_LEAVE ();
}
static void _send_clipboard (GtkMenuItem *menu_item, gpointer *data)
{
      CD_APPLET_ENTER;
      GtkClipboard *pClipBoard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
      gboolean bDataAvailable = gtk_clipboard_wait_is_image_available (pClipBoard);
      g_return_if_fail (myIcon != NULL);  // protection, car cette fonction bloque mais laisse tourner la main loop.
      if (bDataAvailable)
      {
            gtk_clipboard_request_image (pClipBoard, (GtkClipboardImageReceivedFunc) _get_image, data);
            CD_APPLET_LEAVE ();
            //return;
      }
      bDataAvailable = gtk_clipboard_wait_is_text_available (pClipBoard);
      g_return_if_fail (myIcon != NULL);
      if (bDataAvailable)
      {
            gtk_clipboard_request_text (pClipBoard, (GtkClipboardTextReceivedFunc) _get_text, data);
            CD_APPLET_LEAVE ();
            //return;
      }
      CD_APPLET_LEAVE ();
}


//\___________ Define here the action to be taken when the user left-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.
CD_APPLET_ON_CLICK_BEGIN
      _store_last_url (TRUE);
CD_APPLET_ON_CLICK_END


CD_APPLET_ON_DROP_DATA_BEGIN
      g_print  ("DND2SHARE : drop de '%s'\n", CD_APPLET_RECEIVED_DATA);
      _on_drop_data (CD_APPLET_RECEIVED_DATA);
CD_APPLET_ON_DROP_DATA_END


CD_APPLET_ON_SCROLL_BEGIN
      if (myData.pUpoadedItems == NULL)
            return CAIRO_DOCK_LET_PASS_NOTIFICATION;
      
      CDUploadedItem *pItem;
      if (CD_APPLET_SCROLL_DOWN)
      {
            myData.iCurrentItemNum ++;  // item suivant.
            pItem = g_list_nth_data (myData.pUpoadedItems, myData.iCurrentItemNum);
            if (pItem == NULL)
            {
                  pItem = myData.pUpoadedItems->data;
                  myData.iCurrentItemNum = 0;
            }
      }
      else if (CD_APPLET_SCROLL_UP)
      {
            myData.iCurrentItemNum --;  // item precedent.
            pItem = g_list_nth_data (myData.pUpoadedItems, myData.iCurrentItemNum);
            if (pItem == NULL)
            {
                  pItem = g_list_last (myData.pUpoadedItems)->data;
                  g_print ("dernier item\n");
                  myData.iCurrentItemNum = g_list_length (myData.pUpoadedItems) - 1;
            }
      }
      else
            return CAIRO_DOCK_LET_PASS_NOTIFICATION;
      g_free (myData.cLastURL);
      myData.cLastURL = NULL;
      
      g_return_val_if_fail (pItem != NULL, CAIRO_DOCK_LET_PASS_NOTIFICATION);  // parano
      
      myData.cLastURL = g_strdup (cd_dnd2share_get_prefered_url_from_item (pItem));
      if (myConfig.bDisplayLastImage)
      {
            gchar *cPreview = g_strdup_printf ("%s/%s", myData.cWorkingDirPath, pItem->cItemName);
            if (g_file_test (cPreview, G_FILE_TEST_EXISTS))
            {
                  CD_APPLET_SET_IMAGE_ON_MY_ICON (cPreview);
                  g_free (cPreview);
            }
            else
            {
                  cPreview = pItem->cLocalPath;
                  if (g_file_test (cPreview, G_FILE_TEST_EXISTS))
                  {
                        CD_APPLET_SET_IMAGE_ON_MY_ICON (cPreview);
                  }
                  else
                  {
                        CD_APPLET_SET_IMAGE_ON_MY_ICON (MY_APPLET_SHARE_DATA_DIR"/"MY_APPLET_ICON_FILE);
                  }
            }
            CD_APPLET_REDRAW_MY_ICON;
      }
      
      if (myConfig.bEnableDialogs)
      {
            cairo_dock_remove_dialog_if_any (myIcon);
            cairo_dock_show_temporary_dialog_with_icon_printf ("%s '%s' (n°%d):\n%s",
                  myIcon,
                  myContainer,
                  myConfig.dTimeDialogs,
                  "same icon",
                  (pItem->iFileType == CD_TYPE_TEXT ? D_("Text") : D_("File")),
                  pItem->cFileName,
                  myData.iCurrentItemNum,
                  D_("Click on the icon to copy the URL into the clipboard."));
      }
CD_APPLET_ON_SCROLL_END


CD_APPLET_ON_MIDDLE_CLICK_BEGIN
      _store_last_url (FALSE);
CD_APPLET_ON_MIDDLE_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.
CD_APPLET_ON_BUILD_MENU_BEGIN
      GtkWidget *pModuleSubMenu = CD_APPLET_CREATE_MY_SUB_MENU ();
      
      CD_APPLET_ADD_IN_MENU (D_("Send the clipboard's content"), _send_clipboard, CD_APPLET_MY_MENU);
      
      if (myData.pUpoadedItems != NULL)
            CD_APPLET_ADD_IN_MENU_WITH_STOCK (D_("Clear History"), GTK_STOCK_CLEAR, _clear_history, CD_APPLET_MY_MENU);
      
      CDSiteBackend *pBackend;
      CDUploadedItem *pItem;
      GtkWidget *pItemSubMenu;
      gchar *str;
      gchar *cName = NULL, *cURI = NULL, *cIconName = NULL;
      gboolean bIsDirectory;
      int iVolumeID;
      double fOrder;
      int i;
      GList *it;
      for (it = myData.pUpoadedItems; it != NULL; it = it->next)
      {
            pItem = it->data;
            
            // on cherche une miniature a mettre dans le menu.
            gchar *cPreview = NULL;
            if (pItem->iFileType == CD_TYPE_IMAGE)
            {
                  cPreview = g_strdup_printf ("%s/%s", myData.cWorkingDirPath, pItem->cItemName);
                  if (! g_file_test (cPreview, G_FILE_TEST_EXISTS))
                  {
                        g_free (cPreview);
                        cPreview = cairo_dock_search_icon_s_path ("image-x-generic");;
                  }
            }
            else if (pItem->iFileType == CD_TYPE_TEXT)
            {
                  cPreview = cairo_dock_search_icon_s_path ("text-x-generic");
            }
            else if (pItem->iFileType == CD_TYPE_VIDEO)
            {
                  cPreview = cairo_dock_search_icon_s_path ("video-x-generic");
            }
            if (cPreview == NULL)
            {
                  cairo_dock_fm_get_file_info (pItem->cLocalPath, &cName, &cURI, &cPreview, &bIsDirectory, &iVolumeID, &fOrder, 0);
                  g_free (cName);
                  cName = NULL;
                  g_free (cURI);
                  cURI = NULL;
            }
            
            // on cree un sous-menu pour ce fichier.
            str = strchr (pItem->cFileName, '\n');
            if (str)
                  *str = '\0';
            pItemSubMenu = CD_APPLET_ADD_SUB_MENU_WITH_IMAGE (pItem->cFileName, pModuleSubMenu, cPreview);
            if (str)
                  *str = '\n';
            g_free (cPreview);
            
            // on le peuple avec les liens.
            pBackend = &myData.backends[pItem->iFileType][pItem->iSiteID];
            for (i = 0; i < pBackend->iNbUrls; i ++)
            {
                  //g_print ("%d) %s : ", i, pBackend->cUrlLabels[i]);
                  //g_print (" + %s\n", pItem->cDistantUrls[i]);
                  CD_APPLET_ADD_IN_MENU_WITH_DATA (pBackend->cUrlLabels[i], _copy_url_into_clipboard, pItemSubMenu, pItem->cDistantUrls[i]);
            }
            if (pItem->iFileType != CD_TYPE_TEXT)
                  CD_APPLET_ADD_IN_MENU_WITH_DATA (D_("Open file"), _show_local_file, pItemSubMenu, pItem);
            else
                  CD_APPLET_ADD_IN_MENU_WITH_DATA (D_("Get text"), _show_local_file, pItemSubMenu, pItem);
            
            CD_APPLET_ADD_IN_MENU_WITH_STOCK_AND_DATA (D_("Remove from history"), GTK_STOCK_REMOVE, _remove_from_history, pItemSubMenu, pItem);
      }
      
      CD_APPLET_ADD_ABOUT_IN_MENU (CD_APPLET_MY_MENU);
CD_APPLET_ON_BUILD_MENU_END

Generated by  Doxygen 1.6.0   Back to index