📄 memopad.c
字号:
#include <stdlib.h>#include <string.h>#include "mwtypes.h"#include "glib.h"#include "emtk.h"#ifdef FILEMODE #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <sys/mman.h>#else# include "glist_stable.h"# ifndef NOGDBM# include "db.h"# endif#endif#include "laf/laf.h"#ifdef FONT_TABLE #include "font_table.h"#else #define lookupFont(a, b) (FONT1) #define init_font_table(a) #define unload_font_table()#endif#include "glib.h"#include "memopad.h"#ifdef LAUNCHER_SUPPORT #include "deskmsg.h"#endif#ifndef FILEMODE #include "memopad_record.h"#endif#include "memopad_edit.h"#include "i18n.h"#define EDIT_MEMO_TITLE _("Memo %d of %d")#define MAX_TITLE_WIDTH 200#define MAX_TITLE_CHAR 50typedef struct { int key; char *title; char *encoding; GDate date;} MemoListItem;#define MEMOLISTITEM(p) ((MemoListItem *) p)static int list_window;static int edit_window;static int sort_combo;static int clist_id;static int table_id;static char *edit_title;static int database_context;static GList *list;MemopadCallBack handlers;#ifndef FILEMODEstatic gint memoListKeyCompareFunc(gconstpointer a, gconstpointer b) { return !(MEMOLISTITEM(a)->key == *((int *) b)); // return 0 if match}static gint memoTitleSortCompareFunc(gconstpointer a, gconstpointer b) { return g_strcasecmp(MEMOLISTITEM(a)->title, MEMOLISTITEM(b)->title);}static gint memoDateSortCompareFunc(gconstpointer a, gconstpointer b) { return g_date_compare(&(MEMOLISTITEM(a)->date), &(MEMOLISTITEM(b)->date));}static void comboSortChanged(int id, void *data, int row) { switch (row) { case 0: list = g_list_sort_stable(list, memoDateSortCompareFunc); break; case 1: list = g_list_sort_stable(list, memoTitleSortCompareFunc); break; } update_clist();}#if 0static char *getTitle(const char *content) { char *ch; int length; ch = strchr(content, '\n'); if (!ch) { length = MAX_TITLE_CHAR; } else { length = MIN((ch - content), MAX_TITLE_CHAR); } return g_strndup(g_strchug((char *) content), length);}#endifstatic void update_clist() { GList *item; MemoListItem *mitem; int row; char buf[11]; //char *rowStr; emtk_table_hide(table_id); emtk_table_remove_all(table_id); for (item = list, row = 1; item != NULL; item = g_list_next(item), row++) { if (item->data) { mitem = MEMOLISTITEM(item->data); //rowStr = g_strdup_printf("%d.", row); g_date_strftime(buf, 11, "%Y/%m/%d", &(mitem->date)); emtk_table_append_label_new(table_id, lookupFont(mitem->encoding, SMALL_FONT), FALSE, buf, 0); emtk_table_append_label_new(table_id, lookupFont(mitem->encoding, SMALL_FONT), FALSE, mitem->title, 1); //g_free(rowStr); } } emtk_table_show(table_id);}/* TODO: specify encoding */static void newMemo(int key, Memo *memo) { MemoListItem *newitem; int index; newitem = g_new0(MemoListItem, 1); newitem->key = key; //newitem->title = getTitle(memo->content); newitem->title = g_strdup(memo->title); newitem->encoding = g_strdup(memo->encoding); memcpy(&(newitem->date), &(memo->date), sizeof(GDate)); list = g_list_append(list, newitem); edit_window = 0; index = emtk_combobox_list_get_focus_row(sort_combo); comboSortChanged(0, NULL, index); //update_clist();}static void modifiedMemo(int key, Memo *memo) { GList *item; int index; item = g_list_find_custom(list, (gpointer) (&key), memoListKeyCompareFunc); if (item) { g_free(MEMOLISTITEM(item->data)->title); //MEMOLISTITEM(item->data)->title = getTitle(content); MEMOLISTITEM(item->data)->title = g_strdup(memo->title); memcpy(&(MEMOLISTITEM(item->data)->date), &(memo->date), sizeof(GDate)); } edit_window = 0; index = emtk_combobox_list_get_focus_row(sort_combo); comboSortChanged(0, NULL, index); }static void deleteMemo(int key) { GList *item; MemoListItem *mitem; item = g_list_find_custom(list, (gpointer) (&key), memoListKeyCompareFunc); if (item) { g_return_if_fail(item->data != NULL); mitem = MEMOLISTITEM(item->data); list = g_list_remove(list, item->data); if (mitem->title) g_free(mitem->title); g_free(mitem); } edit_window = 0; update_clist();}/* TODO: specify encoding */void openNewEditor(int id, void *data) { int records; Memo *memo; char *title; char *encoding; #ifndef NOGDBM if (db_get_num_records(database_context) == 0) { records = 1; } else { records = db_get_num_records(database_context) + 1; }#else records = 1;#endif memo = memopad_record_new(); memo->new = TRUE; memo->content = g_strdup(""); memo->content_len = 0; /* If encoding not availabe, revert to english */ memo->encoding = (lc_all) ? g_strdup(lc_all) : g_strdup("en_US"); title = g_strdup_printf(EDIT_MEMO_TITLE, records, records); edit_window = memopad_edit_new_window(title, memo, database_context, &handlers); g_free(title);}static void closeHandler(int id, void *data) { //emtk_app_close(); int *feedback = (int *) data; *feedback = EMTK_APP_WINDOW_DESTROY_WITH_EMTK_CLOSE; }static int addEntry(int key, char *data) { MemoListItem *item; Memo *memo; item = g_new0(MemoListItem, 1); deserialize(&memo, data); item->key = memo->memo_id; //item->title = getTitle(memo->content); item->title = g_strdup(memo->title); memcpy(&(item->date), &(memo->date), sizeof(GDate)); item->encoding = g_strdup(memo->encoding); memopad_record_destroy(memo); list = g_list_append(list, item); return TRUE;}static void list_selection_handler(int clist, void *data, int row) { Memo *memo; MemoListItem *item; char *title; int records; item = g_list_nth_data(list, row); memo = memopad_record_load(database_context, item->key);#ifndef NOGDBM records = db_get_num_records(database_context);#else records = 0;#endif title = g_strdup_printf(EDIT_MEMO_TITLE, row + 1, records); edit_window = memopad_edit_new_window(title, memo, database_context, &handlers); g_free(title);}static void drawListWnd(int window, WindowRect *clientRect) { // emtk_window_key_handler_add(window, key_pressed, NULL, KEY_TYPE_ANY); sort_combo = emtk_combobox_new(window, 50, 0, 100, 2, lookupFont("en_US", SMALL_FONT), 20, TRUE, KEY_TYPE_ANY); emtk_combobox_list_append_widget(sort_combo, emtk_label_new(window, 0, 0, lookupFont("en_US", SMALL_FONT), FALSE, _("Date"))); emtk_combobox_list_append_widget(sort_combo, emtk_label_new(window, 0, 0, lookupFont("en_US", SMALL_FONT), FALSE, _("Title"))); emtk_combobox_list_set_focus_change_callback(sort_combo, comboSortChanged, NULL); emtk_window_add_object(window, sort_combo); emtk_window_add_object(window, emtk_button_new(window, 0, clientRect->h - LIST_BTN_HEIGHT, 40, LIST_BTN_HEIGHT, FONT1, _("New"), 0, openNewEditor, NULL)); table_id = emtk_table_new(window, 0, 22, clientRect->w - SCROLLBAR_WIDTH, LIST_ROW_HEIGHT, 2, (clientRect->h-LIST_BTN_HEIGHT - 22)/LIST_ROW_HEIGHT, 0); emtk_table_set_one_click_activate(table_id, TRUE); emtk_table_set_selection_callback(table_id, list_selection_handler, NULL); emtk_table_add_column_new(table_id, 80); emtk_table_add_column_new(table_id, clientRect->w - SCROLLBAR_WIDTH - 80); emtk_table_set_highlight_color(table_id, emtk_app_get_hl_color()); emtk_window_add_object(window, table_id); emtk_table_add_vscrollbar_new(table_id, SCROLLBAR_WIDTH, VSCROLLBAR_ALIGN_RIGHT); list = NULL;#ifndef NOGDBM db_iterate(database_context, addEntry);#endif list = g_list_sort_stable(list, memoDateSortCompareFunc); update_clist();}static void init() { handlers.deleted = deleteMemo; handlers.modified = modifiedMemo; handlers.new = newMemo; list_window = emtk_app_window_new(_("Memo"), FONT2, drawListWnd, closeHandler, NULL); lc_all = getenv("LC_ALL");}#endif /* FILEMODE */#ifdef FILEMODEstatic char *getFileName(char *path) { char *ptr = strrchr(path, '/'); if (ptr) return ptr + 1; else return path; }#endif#ifdef LAUNCHER_SUPPORTvoid memopad_msg_arrived(MSG *msg, gpointer user_data) { if (msg->type == MSG_TYPE_COMMAND && msg->subtype == MSG_COMMAND_CLOSE) { printf("Close request received\n"); if (edit_window) { emtk_app_close_window(edit_window); } emtk_app_close_window(list_window); }} #endifint main(int argc, char **argv) { #ifdef LAUNCHER_SUPPORT DESKTOP_CHANNEL channel;#endif#ifndef FILEMODE#else int fd; Memo memo; struct stat st;#endif //sleep(5); i18n_init(); #ifndef FILEMODE database_context = memopad_record_db_open(); if (database_context <= 0) { fprintf(stderr, "Error opening memopad database, exiting\n"); exit(1); }#else if (argc < 2) { printf("usuage %s filename\n", argv[0]); return 1; } fd = open(argv[1], O_RDONLY); if (fd < 0) { printf("error opening file %s\n", argv[1]); return 2; } fstat(fd, &st); memo.memo_id = -1; memo.content = mmap(0, st.st_size, PROT_READ, MAP_SHARED, fd, 0); memo.content_len = st.st_size; memo.encoding = "en_US";#endif init_font_table(NULL); emtk_app_init(&argc, &argv); emtk_app_root(APP_WINDOW_X, APP_WINDOW_Y, APP_WINDOW_W, APP_WINDOW_H); #ifndef FILEMODE #ifdef LAUNCHER_SUPPORT //channel = g_new0(DESKTOP_CHANNEL, 1); printf("opening channel\n"); if (!desktop_channel_listen_connect(&channel, memopad_msg_arrived, NULL)) { printf("Failed opening channel for listening\n"); return 3; } #endif init();#else memopad_edit_new_window(getFileName(argv[1]), &memo, 0, NULL);#endif emtk_app_run(); #ifndef FILEMODE memopad_record_db_close(database_context);#else munmap(memo.content, st.st_size); close(fd);#endif #ifdef LAUNCHER_SUPPORT printf("disconnecting listen channel\n"); desktop_channel_listen_disconnect(&channel); //g_free(channel);#endif unload_font_table(); exit(0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -