Logo Search packages:      
Sourcecode: ebview version File versions  Download package

selection.c

/*  Copyright (C) 2001-2004  Kenichi Suto
 *
 *  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 2 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, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/


#include "defs.h"
#include "global.h"
#include "eb.h"
#include "dialog.h"
#include "grep.h"
#include "selection.h"
#include "headword.h"
#include "mainwindow.h"
#include "misc.h"
#include "popup.h"
#include "history.h"
#include "jcode.h"

static gint tag_timeout=0;
static gchar previous[256];
static gboolean auto_lookup_suspended = FALSE;

extern GList *current_in_result;
extern GtkWidget *hidden_window;

void bring_to_top(GtkWidget *win){
#ifdef __WIN32__
      HWND hWnd;
      int nTargetID, nForegroundID;
      BOOL res;

      hWnd = GDK_WINDOW_HWND (win->window);

      /* From  http://techtips.belution.com/ja/vc/0012/ */
      nForegroundID = GetWindowThreadProcessId(GetForegroundWindow(), NULL);
      nTargetID = GetWindowThreadProcessId(hWnd, NULL );

      AttachThreadInput(nTargetID, nForegroundID, TRUE );

      // SPI_GETFOREGROUNDLOCKTIMEOUT will be undefined. Why ?
      /*
      SystemParametersInfo( SPI_GETFOREGROUNDLOCKTIMEOUT,0,&sp_time,0);
      SystemParametersInfo( SPI_SETFOREGROUNDLOCKTIMEOUT,0,(LPVOID)0,0);
      SetForegroundWindow(hWnd);
      SystemParametersInfo( SPI_SETFOREGROUNDLOCKTIMEOUT,0,sp_time,0);
      */

      res = SetForegroundWindow(hWnd);

      AttachThreadInput(nTargetID, nForegroundID, FALSE);

      if(!res){
            SetFocus(hWnd);
      }
#else
      gtk_window_present(GTK_WINDOW(win));
#endif
}

static gboolean validate_euc_str(guchar *str){
      guchar *p;

      p = str;
      while(*p){
            if (iseuc(p)) {
                  p +=2;
            } else if(isprint(*p)) {
                  p ++;
            } else if(isspace(*p)) {
                  *p = 0x20;
                  p++;
            } else {
                  return(FALSE);
            }
      }
      return(TRUE);
}

static void search_selected(gchar *str)
{
      gchar *euc_str;
      gint method;
      glong len;

      LOG(LOG_DEBUG, "IN : search_selected(%s)", str);

      if(selection_mode <= SELECTION_DO_NOTHING) {
            LOG(LOG_DEBUG, "OUT : search_selected() = NOP1");
            return;
      }

      if(strcmp(previous, str) == 0){
            // Do nothing if the word is the save as before.
            LOG(LOG_DEBUG, "same as before");
            ;
      } else {

            euc_str = iconv_convert("utf-8", "euc-jp", str);
            if(validate_euc_str(euc_str) == FALSE) {
                  g_free(euc_str);
                  LOG(LOG_DEBUG, "OUT : search_selected() = INVALID");
                  return;
            }
            remove_space(euc_str);

            len = g_utf8_strlen(str, -1);

            if((auto_minchar <= len) && (len <= auto_maxchar)) {
                  gtk_entry_set_text(GTK_ENTRY(word_entry), str);

                  method = ebook_search_method();
                  if((method == SEARCH_METHOD_INTERNET) ||
                     (method == SEARCH_METHOD_MULTI) ||
                     (method == SEARCH_METHOD_FULL_TEXT)){
                        LOG(LOG_DEBUG, "OUT : search_selected() = NOP2");
                        return;
                  }

                  if(selection_mode <= SELECTION_COPY_ONLY) {
                        LOG(LOG_DEBUG, "OUT : search_selected() = COPY");
                        return;
                  }
                  
                  clear_message();
                  clear_search_result();

                  if(method == SEARCH_METHOD_GREP){
                        grep_search(euc_str);
                        show_result_tree();
                        select_first_item();
                        if(selection_mode == SELECTION_SEARCH_TOP)
                              bring_to_top(main_window);
                        save_word_history(str);
                  } else {
                        ebook_search_auto(euc_str, method);
                        if(search_result){
                              if(selection_mode == SELECTION_POPUP) {
                                    show_result_in_popup();
                              } else {
                                    show_result_tree();
                                    select_first_item();
                                    if(selection_mode == SELECTION_SEARCH_TOP)
                                          bring_to_top(main_window);
                              }
                              save_word_history(str);
                        } else {
                              current_in_result = NULL;
                              set_current_result(NULL);
                              if(selection_mode == SELECTION_POPUP) {
                                    beep();
                              } else {
                                    if(selection_mode == SELECTION_SEARCH_TOP)
                                          bring_to_top(main_window);
                                    push_message(_("No hit."));
                              }
                        }
                  }
                  
                  sprintf(previous, "%s", str);
            } else {
                  LOG(LOG_DEBUG, "OUT : search_selected() = LENGTH");
            }
            g_free(euc_str);
      }

      LOG(LOG_DEBUG, "OUT : search_selected()");
}

void
selection_received (GtkWidget *widget, GtkSelectionData *data)
{
      gchar *str;
      gchar **list;
      gint count;

      LOG(LOG_DEBUG, "IN : selection_received()");

      if((data == NULL) || (data->data == NULL) || (data->length < 0)){
            LOG(LOG_DEBUG, "no data");
            goto END;
      }

      // No conversion required for STRING type.
      if (data->type == GDK_TARGET_STRING){
            str = g_strndup(data->data, data->length);

      // Convert to UTF-8 for COMPOUND_TEXT type.
      } else if ((data->type == gdk_atom_intern ("COMPOUND_TEXT", FALSE)) ||
               (data->type == gdk_atom_intern ("TEXT", FALSE))){
            count = gdk_text_property_to_utf8_list (data->type,
                                          data->format, 
                                          data->data,
                                          data->length,
                                          &list);


            if((count == 0) || (list == NULL)){
                  goto END;
            }
            str = g_strdup(list[0]);
            g_strfreev(list);

      } else {
            LOG(LOG_DEBUG, "unknown data type");
            goto END;
      }

      remove_space(str);
      search_selected(str);
      g_free(str);

 END:

      if(selection_mode != SELECTION_DO_NOTHING){
            auto_lookup_start();
      }

      LOG(LOG_DEBUG, "OUT : selection_received()");
      return;
}


gint copy_clipboard_win(gpointer data){
      gchar *str=NULL;
      GtkClipboard* clipboard;

      LOG(LOG_DEBUG, "IN : copy_clipboard()");

#ifdef __WIN32__
      clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
#else
      clipboard = gtk_clipboard_get(GDK_SELECTION_PRIMARY);
#endif

      str = gtk_clipboard_wait_for_text(clipboard);
      if(str == NULL){
            goto END;
      }

      remove_space(str);
      search_selected(str);
      g_free(str);

 END:
      if(selection_mode != SELECTION_DO_NOTHING){
            auto_lookup_start();
      }

      LOG(LOG_DEBUG, "OUT : copy_clipboard()");
      return (FALSE);
}

gint copy_clipboard_x(gpointer data){
      static GdkAtom ctext_atom = GDK_NONE;

      LOG(LOG_DEBUG, "IN : copy_clipboard()");

      /*
      xwindow = XGetSelectionOwner (gdk_display_get_default(), GDK_SELECTION_PRIMARY);
      if (xwindow == None){
            return(TRUE);
      }
      */

      gtk_entry_set_text(GTK_ENTRY(hidden_entry), "");

      // Ask for COMPOUND_TEXT
      if (ctext_atom == GDK_NONE){
            ctext_atom = gdk_atom_intern ("COMPOUND_TEXT", FALSE);
      }

#ifdef __WIN32__
      gtk_selection_convert (hidden_entry,
                         GDK_SELECTION_CLIPBOARD,
                         ctext_atom, 
                         GDK_CURRENT_TIME);
#else
      gtk_selection_convert (hidden_entry,
                         GDK_SELECTION_PRIMARY,
                         ctext_atom, 
                         GDK_CURRENT_TIME);
#endif
      
      LOG(LOG_DEBUG, "OUT : copy_clipboard()");
      return (FALSE);
}


#ifdef __WIN32__
static gboolean registered=FALSE;
static WNDPROC OrgWndProc = NULL;
static HWND next_hwnd = NULL;
static HWND hidden_hwnd;

LRESULT CALLBACK
HiddenWndProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    LRESULT retval;
    HANDLE hText;
    char *pText;
    gchar *str;


    switch (msg) {
    case WM_DESTROY:
          ChangeClipboardChain(hwnd , next_hwnd);
          PostQuitMessage(0);
          break;
    case WM_DRAWCLIPBOARD:
          OpenClipboard(hwnd);
          hText = GetClipboardData(CF_TEXT);

          if(hText != NULL) {
                pText = GlobalLock(hText);
                GlobalUnlock(hText);
          }
          CloseClipboard();

          //remove_space(pText);
          str = iconv_convert(fs_codeset, "utf-8", pText);
          search_selected(str);
          g_free(str);

          if(next_hwnd != NULL)
                SendMessage(next_hwnd, msg, wParam, lParam);
          break;
    case WM_CHANGECBCHAIN:
          if((HWND)wParam == next_hwnd)
                next_hwnd = (HWND)lParam;
          break;
    default:
          break;
    }

    retval = OrgWndProc(hwnd, msg, wParam, lParam);
    return retval;
}

#endif

void auto_lookup_start()
{
      
      if(selection_mode == SELECTION_DO_NOTHING)
            return;
      
#ifdef __WIN32__
      if(registered == FALSE) {
            if(OrgWndProc == NULL){
                  hidden_hwnd = GDK_WINDOW_HWND (hidden_window->window);
                  OrgWndProc = (WNDPROC)GetWindowLong(hidden_hwnd, GWL_WNDPROC);
                  SetWindowLong(hidden_hwnd, GWL_WNDPROC, (LONG)HiddenWndProc);
            }
            next_hwnd = SetClipboardViewer(hidden_hwnd);
      }
      registered = TRUE;
#else

      if(tag_timeout != 0)
            gtk_timeout_remove(tag_timeout);
      tag_timeout = gtk_timeout_add(auto_interval, copy_clipboard_x, NULL);

#endif
      auto_lookup_suspended = FALSE;
}

void auto_lookup_stop()
{

#ifdef __WIN32__
      if(registered == TRUE) {
            hidden_hwnd = GDK_WINDOW_HWND (hidden_window->window);
            ChangeClipboardChain(hidden_hwnd, next_hwnd);
            next_hwnd = NULL;
            registered = FALSE;
      }
#else
      if(tag_timeout != 0)
            gtk_timeout_remove(tag_timeout);
      tag_timeout = 0;
#endif

      auto_lookup_suspended = FALSE;
}

void auto_lookup_suspend()
{
      if((selection_mode != SELECTION_DO_NOTHING) && (auto_lookup_suspended == FALSE)) {
            auto_lookup_stop();
            auto_lookup_suspended = TRUE;
      }
}

void auto_lookup_resume()
{
      if((selection_mode != SELECTION_DO_NOTHING) && (auto_lookup_suspended == TRUE)) {
            auto_lookup_start();
            auto_lookup_suspended = FALSE;
      }
}

Generated by  Doxygen 1.6.0   Back to index