aboutsummaryrefslogtreecommitdiffstats
path: root/addressbook/gui/widgets/e-addressbook-model.h
blob: 79a606b314a94d4abbba0713fb5b9b26171c37d5 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
#ifndef _E_ADDRESSBOOK_MODEL_H_
#define _E_ADDRESSBOOK_MODEL_H_

#include <gal/e-table/e-table-model.h>
#include "addressbook/backend/ebook/e-book.h"
#include "addressbook/backend/ebook/e-book-view.h"
#include "addressbook/backend/ebook/e-card-simple.h"

#define E_ADDRESSBOOK_MODEL_TYPE        (e_addressbook_model_get_type ())
#define E_ADDRESSBOOK_MODEL(o)          (GTK_CHECK_CAST ((o), E_ADDRESSBOOK_MODEL_TYPE, EAddressbookModel))
#define E_ADDRESSBOOK_MODEL_CLASS(k)    (GTK_CHECK_CLASS_CAST((k), E_ADDRESSBOOK_MODEL_TYPE, EAddressbookModelClass))
#define E_IS_ADDRESSBOOK_MODEL(o)       (GTK_CHECK_TYPE ((o), E_ADDRESSBOOK_MODEL_TYPE))
#define E_IS_ADDRESSBOOK_MODEL_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_ADDRESSBOOK_MODEL_TYPE))

/* Virtual Column list:
   0   Email
   1   Full Name
   2   Street
   3   Phone
*/

typedef struct _EAddressbookModel EAddressbookModel;
typedef struct _EAddressbookModelClass EAddressbookModelClass;

struct _EAddressbookModel {
    ETableModel parent;

    /* item specific fields */
    EBook *book;
    char *query;
    EBookView *book_view;

    int get_view_idle;

    ECardSimple **data;
    int data_count;

    int create_card_id, remove_card_id, modify_card_id, status_message_id;

    guint editable : 1;
    guint first_get_view : 1;
};


struct _EAddressbookModelClass {
    ETableModelClass parent_class;

    /*
     * Signals
     */
    void (*status_message) (EAddressbookModel *model, const gchar *message);
};


GtkType e_addressbook_model_get_type (void);
ETableModel *e_addressbook_model_new (void);

/* Returns object with ref count of 1. */
ECard *e_addressbook_model_get_card(EAddressbookModel *model,
                    int                row);
void   e_addressbook_model_stop    (EAddressbookModel *model);

#endif /* _E_ADDRESSBOOK_MODEL_H_ */
href='#n245'>245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/* e-text-event-processor.c
 * Copyright (C) 2000  Helix Code, Inc.
 * Author: Chris Lahey <clahey@helixcode.com>
 *
 * This library 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 library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include <gnome.h>
#include "e-text-event-processor-emacs-like.h"
static void e_text_event_processor_emacs_like_init      (ETextEventProcessorEmacsLike        *card);
static void e_text_event_processor_emacs_like_class_init    (ETextEventProcessorEmacsLikeClass   *klass);
static gint e_text_event_processor_emacs_like_event (ETextEventProcessor *tep, ETextEventProcessorEvent *event);

static ETextEventProcessorClass *parent_class = NULL;

/* The arguments we take */
enum {
    ARG_0
};

static const ETextEventProcessorCommand control_keys[26] =
{
    { E_TEP_START_OF_LINE,      E_TEP_MOVE, 0, "" }, /* a */
    { E_TEP_BACKWARD_CHARACTER, E_TEP_MOVE, 0, "" }, /* b */
    { E_TEP_SELECTION,          E_TEP_COPY, 0, "" }, /* c */
    { E_TEP_FORWARD_CHARACTER,  E_TEP_DELETE, 0, "" }, /* d */
    { E_TEP_END_OF_LINE,        E_TEP_MOVE, 0, "" }, /* e */
    { E_TEP_FORWARD_CHARACTER,  E_TEP_MOVE, 0, "" }, /* f */
    { E_TEP_SELECTION, E_TEP_NOP, 0, "" },           /* g */
    { E_TEP_BACKWARD_CHARACTER, E_TEP_DELETE, 0, "" }, /* h */
    { E_TEP_SELECTION, E_TEP_NOP, 0, "" },           /* i */
    { E_TEP_SELECTION, E_TEP_NOP, 0, "" },           /* j */
    { E_TEP_END_OF_LINE,        E_TEP_DELETE, 0, "" }, /* k */
    { E_TEP_SELECTION, E_TEP_NOP, 0, "" },           /* l */
    { E_TEP_SELECTION, E_TEP_NOP, 0, "" },           /* m */
    { E_TEP_FORWARD_LINE,       E_TEP_MOVE, 0, "" }, /* n */
    { E_TEP_SELECTION, E_TEP_NOP, 0, "" },           /* o */
    { E_TEP_BACKWARD_LINE,      E_TEP_MOVE, 0, "" }, /* p */
    { E_TEP_SELECTION, E_TEP_NOP, 0, "" },           /* q */
    { E_TEP_SELECTION, E_TEP_NOP, 0, "" },           /* r */
    { E_TEP_SELECTION, E_TEP_NOP, 0, "" },           /* s */
    { E_TEP_SELECTION, E_TEP_NOP, 0, "" },           /* t */
    { E_TEP_START_OF_LINE,      E_TEP_DELETE, 0, "" }, /* u */
    { E_TEP_SELECTION,          E_TEP_PASTE, 0, "" }, /* v */
    { E_TEP_BACKWARD_WORD,      E_TEP_DELETE, 0, "" }, /* w */
    { E_TEP_SELECTION,          E_TEP_DELETE, 0, "" }, /* x */
    { E_TEP_SELECTION, E_TEP_NOP, 0, "" },           /* y */
    { E_TEP_SELECTION, E_TEP_NOP, 0, "" }           /* z */
};

static const ETextEventProcessorCommand alt_keys[26] =
{
    { E_TEP_SELECTION, E_TEP_NOP, 0, "" },           /* a */
    { E_TEP_BACKWARD_WORD,      E_TEP_MOVE, 0, "" }, /* b */
    { E_TEP_SELECTION, E_TEP_NOP, 0, "" },           /* c */
    { E_TEP_FORWARD_WORD,       E_TEP_DELETE, 0, "" }, /* d */
    { E_TEP_SELECTION, E_TEP_NOP, 0, "" },           /* e */
    { E_TEP_FORWARD_WORD,       E_TEP_MOVE, 0, "" }, /* f */
    { E_TEP_SELECTION, E_TEP_NOP, 0, "" },           /* g */
    { E_TEP_SELECTION, E_TEP_NOP, 0, "" },           /* h */
    { E_TEP_SELECTION, E_TEP_NOP, 0, "" },           /* i */
    { E_TEP_SELECTION, E_TEP_NOP, 0, "" },           /* j */
    { E_TEP_SELECTION, E_TEP_NOP, 0, "" },           /* k */
    { E_TEP_SELECTION, E_TEP_NOP, 0, "" },           /* l */
    { E_TEP_SELECTION, E_TEP_NOP, 0, "" },           /* m */
    { E_TEP_SELECTION, E_TEP_NOP, 0, "" },           /* n */
    { E_TEP_SELECTION, E_TEP_NOP, 0, "" },           /* o */
    { E_TEP_SELECTION, E_TEP_NOP, 0, "" },           /* p */
    { E_TEP_SELECTION, E_TEP_NOP, 0, "" },           /* q */
    { E_TEP_SELECTION, E_TEP_NOP, 0, "" },           /* r */
    { E_TEP_SELECTION, E_TEP_NOP, 0, "" },           /* s */
    { E_TEP_SELECTION, E_TEP_NOP, 0, "" },           /* t */
    { E_TEP_SELECTION, E_TEP_NOP, 0, "" },           /* u */
    { E_TEP_SELECTION, E_TEP_NOP, 0, "" },           /* v */
    { E_TEP_SELECTION, E_TEP_NOP, 0, "" },           /* w */
    { E_TEP_SELECTION, E_TEP_NOP, 0, "" },           /* x */
    { E_TEP_SELECTION, E_TEP_NOP, 0, "" },           /* y */
    { E_TEP_SELECTION, E_TEP_NOP, 0, "" }           /* z */

};

GtkType
e_text_event_processor_emacs_like_get_type (void)
{
  static GtkType text_event_processor_emacs_like_type = 0;

  if (!text_event_processor_emacs_like_type)
    {
      static const GtkTypeInfo text_event_processor_emacs_like_info =
      {
        "ETextEventProcessorEmacsLike",
        sizeof (ETextEventProcessorEmacsLike),
        sizeof (ETextEventProcessorEmacsLikeClass),
        (GtkClassInitFunc) e_text_event_processor_emacs_like_class_init,
        (GtkObjectInitFunc) e_text_event_processor_emacs_like_init,
        /* reserved_1 */ NULL,
        /* reserved_2 */ NULL,
        (GtkClassInitFunc) NULL,
      };

      text_event_processor_emacs_like_type = gtk_type_unique (e_text_event_processor_get_type (), &text_event_processor_emacs_like_info);
    }

  return text_event_processor_emacs_like_type;
}

static void
e_text_event_processor_emacs_like_class_init (ETextEventProcessorEmacsLikeClass *klass)
{
  GtkObjectClass *object_class;
  ETextEventProcessorClass *processor_class;

  object_class = (GtkObjectClass*) klass;
  processor_class = (ETextEventProcessorClass*) klass;

  parent_class = gtk_type_class (e_text_event_processor_get_type ());

  processor_class->event = e_text_event_processor_emacs_like_event;
}

static void
e_text_event_processor_emacs_like_init (ETextEventProcessorEmacsLike *tep)
{
}

static gint
e_text_event_processor_emacs_like_event (ETextEventProcessor *tep, ETextEventProcessorEvent *event)
{
    ETextEventProcessorCommand command;
    ETextEventProcessorEmacsLike *tep_el = E_TEXT_EVENT_PROCESSOR_EMACS_LIKE(tep);
    command.action = E_TEP_NOP;
    switch (event->type) {
    case GDK_BUTTON_PRESS:
        if (event->button.button == 1) {
            command.action = E_TEP_GRAB;
            command.time = event->button.time;
            gtk_signal_emit_by_name (GTK_OBJECT (tep), "command", &command);
            if (event->button.state & GDK_SHIFT_MASK)
                command.action = E_TEP_SELECT;
            else
                command.action = E_TEP_MOVE;
            command.position = E_TEP_VALUE;
            command.value = event->button.position;
            command.time = event->button.time;
            tep_el->mouse_down = TRUE;
        }
        break;
    case GDK_BUTTON_RELEASE:
        if (event->button.button == 1) {
            command.action = E_TEP_UNGRAB;
            command.time = event->button.time;
            gtk_signal_emit_by_name (GTK_OBJECT (tep), "command", &command);
            command.time = event->button.time;
            tep_el->mouse_down = FALSE;
        } else if (event->button.button == 2) {
            command.action = E_TEP_MOVE;
            command.position = E_TEP_VALUE;
            command.value = event->button.position;
            command.time = event->button.time;
            gtk_signal_emit_by_name (GTK_OBJECT (tep), "command", &command);            

            command.action = E_TEP_GET_SELECTION;
            command.position = E_TEP_SELECTION;
            command.value = 0;
            command.time = event->button.time;
        }
        break;
    case GDK_MOTION_NOTIFY:
        if (tep_el->mouse_down) {
            command.action = E_TEP_SELECT;
            command.position = E_TEP_VALUE;
            command.time = event->motion.time;
            command.value = event->motion.position;
        }
        break;
    case GDK_KEY_PRESS: 
        {
            ETextEventProcessorEventKey key = event->key;
            command.time = event->key.time;
            if (key.state & GDK_SHIFT_MASK)
                command.action = E_TEP_SELECT;
            else
                command.action = E_TEP_MOVE;
            switch(key.keyval) {
            case GDK_Home:
                if (key.state & GDK_CONTROL_MASK)
                    command.position = E_TEP_START_OF_BUFFER;
                else
                    command.position = E_TEP_START_OF_LINE;
                break;
            case GDK_End:
                if (key.state & GDK_CONTROL_MASK)
                    command.position = E_TEP_END_OF_BUFFER;
                else
                    command.position = E_TEP_END_OF_LINE;
                break;
            case GDK_Page_Up: command.position = E_TEP_BACKWARD_PAGE; break;
            case GDK_Page_Down: command.position = E_TEP_FORWARD_PAGE; break;
                /* CUA has Ctrl-Up/Ctrl-Down as paragraph up down */
            case GDK_Up:        command.position = E_TEP_BACKWARD_LINE; break;
            case GDK_Down:      command.position = E_TEP_FORWARD_LINE; break;
            case GDK_Left:
                if (key.state & GDK_CONTROL_MASK)
                    command.position = E_TEP_BACKWARD_WORD;
                else
                    command.position = E_TEP_BACKWARD_CHARACTER;
                break;
            case GDK_Right:     
                if (key.state & GDK_CONTROL_MASK)
                    command.position = E_TEP_FORWARD_WORD;
                else
                    command.position = E_TEP_FORWARD_CHARACTER;
                break;
      
            case GDK_BackSpace:
                command.action = E_TEP_DELETE;
                if (key.state & GDK_CONTROL_MASK)
                    command.position = E_TEP_BACKWARD_WORD;
                else
                    command.position = E_TEP_BACKWARD_CHARACTER;
                break;
            case GDK_Clear:
                command.action = E_TEP_DELETE;
                command.position = E_TEP_END_OF_LINE;
                break;
            case GDK_Insert:
                if (key.state & GDK_SHIFT_MASK) {
                    command.action = E_TEP_PASTE;
                    command.position = E_TEP_SELECTION;
                } else if (key.state & GDK_CONTROL_MASK) {
                    command.action = E_TEP_COPY;
                    command.position = E_TEP_SELECTION;
                } else {
                /* gtk_toggle_insert(text) -- IMPLEMENT */
                }
                break;
            case GDK_Delete:
                if (key.state & GDK_CONTROL_MASK){
                    command.action = E_TEP_DELETE;
                    command.position = E_TEP_FORWARD_WORD;
                } else if (key.state & GDK_SHIFT_MASK) {
                    command.action = E_TEP_COPY;
                    command.position = E_TEP_SELECTION;
                    gtk_signal_emit_by_name (GTK_OBJECT (tep), "command", &command);
                
                    command.action = E_TEP_DELETE;
                    command.position = E_TEP_SELECTION;
                } else {
                    command.action = E_TEP_DELETE;
                    command.position = E_TEP_FORWARD_CHARACTER;
                }
                break;
            case GDK_Tab:
                /* Don't insert literally */
                command.action = E_TEP_NOP;
                command.position = E_TEP_SELECTION;
                break;
            case GDK_Return:
                if (key.state & GDK_CONTROL_MASK) {
                    command.action = E_TEP_ACTIVATE;
                    command.position = E_TEP_SELECTION;
                } else {
                    command.action = E_TEP_INSERT;
                    command.position = E_TEP_SELECTION;
                    command.value = 1;
                    command.string = "\n";
                }
                break;
            case GDK_Escape:
                /* Don't insert literally */
                command.action = E_TEP_NOP;
                command.position = E_TEP_SELECTION;
                break;
      
            default:
                if (key.state & GDK_CONTROL_MASK) {
                    if ((key.keyval >= 'A') && (key.keyval <= 'Z'))
                        key.keyval -= 'A' - 'a';
                    
                    if ((key.keyval >= 'a') && (key.keyval <= 'z')) {
                        command.position = control_keys[(int) (key.keyval - 'a')].position;
                        if (control_keys[(int) (key.keyval - 'a')].action != E_TEP_MOVE)
                            command.action = control_keys[(int) (key.keyval - 'a')].action;
                        command.value = control_keys[(int) (key.keyval - 'a')].value;
                        command.string = control_keys[(int) (key.keyval - 'a')].string;
                    }

                    if (key.keyval == 'x') {
                        command.action = E_TEP_COPY;
                        command.position = E_TEP_SELECTION;
                        gtk_signal_emit_by_name (GTK_OBJECT (tep), "command", &command);
                        
                        command.action = E_TEP_DELETE;
                        command.position = E_TEP_SELECTION;
                    }
                    
                    break;
                } else if (key.state & GDK_MOD1_MASK) {
                    if ((key.keyval >= 'A') && (key.keyval <= 'Z'))
                        key.keyval -= 'A' - 'a';
                    
                    if ((key.keyval >= 'a') && (key.keyval <= 'z')) {
                        command.position = alt_keys[(int) (key.keyval - 'a')].position;
                        if (alt_keys[(int) (key.keyval - 'a')].action != E_TEP_MOVE)
                            command.action = alt_keys[(int) (key.keyval - 'a')].action;
                        command.value = alt_keys[(int) (key.keyval - 'a')].value;
                        command.string = alt_keys[(int) (key.keyval - 'a')].string;
                    }
                } else if (key.length > 0) {
                    command.action = E_TEP_INSERT;
                    command.position = E_TEP_SELECTION;
                    command.value = strlen(key.string);
                    command.string = key.string;
                    
                } else {
                    command.action = E_TEP_NOP;
                }
            }
            break;
        case GDK_KEY_RELEASE:
            command.time = event->key.time;
            command.action = E_TEP_NOP;
            break;
        default:
            command.action = E_TEP_NOP;
            break;
        }
    }
    if (command.action != E_TEP_NOP) {
        gtk_signal_emit_by_name (GTK_OBJECT (tep), "command", &command);
        return 1;
    }
    else
        return 0;
}