/* diff.c This file is part of "Pharmacy: A GNOME CVS front-end" Copyright 1998 Reklaw (N. Adam Walker) "Pharmacy" is released under the GPL See the LICENCE for more details. */ #include #include #include "diff.h" #include "pharmacy.h" #include #define BUFSIZE 255 /* Menu Stuff */ #define MENU_GO 0 #define MENU_STOP 1 /* sep */ #define MENU_CLEAR 3 #define MENU_PRINT 4 typedef enum { NONE, RIGHT, LEFT } SIDES; static gchar* pgcDiffBuffer; static gint s_nLineUpRow = -1; static gint s_nLastRow = -1; static SIDES s_nLastSide = NONE; /* User Interface Update */ static void diffcontrol_ui_update_cb (gchar * pgcHint) { DiffControl* pCntl = pharmacy_get_diff(); if(pCntl) { if(g_bExper) { gtk_widget_show (pCntl->pvBox); } else { gtk_widget_hide (pCntl->pvBox); } } } static void diffcontrol_parse (DiffControl* pCntl,gchar* pInStr) { gchar* pStr = pInStr; gint bLeft = 0; gint bRight = 0; gchar* pListStr = NULL; gchar* text[3]; gint nRow = -1; gint nLen = -1; g_return_if_fail(pCntl); g_return_if_fail(pStr); nLen = strlen(pStr); /* Which side? */ if(pStr[0]=='<') { s_nLastSide = LEFT; bLeft = 1; pStr++; } else if(pStr[0]=='>') { s_nLastSide = RIGHT; bRight = 1; pStr++; } else if(nLen>1 && pStr[0]=='-' && pStr[1]=='-') { if(s_nLineUpRow == -1) { s_nLineUpRow = -2; } else { s_nLineUpRow = -3; } } else if(nLen>1 && pStr[0]=='+' && pStr[1]=='+') { if(s_nLineUpRow == -1) { s_nLineUpRow = -2; } else { s_nLineUpRow = -3; } } else { s_nLastSide = NONE; bRight = bLeft = 1; s_nLineUpRow = -1; } text[0] = ""; text[1] = ""; text[2] = NULL; if(bLeft && !bRight) { s_nLastSide = LEFT; } if(!bLeft && bRight) { s_nLastSide = RIGHT; } if(s_nLineUpRow>=0) { gtk_clist_get_text(GTK_CLIST(pCntl->pList),s_nLineUpRow, s_nLastSide==RIGHT?1:0, &text[s_nLastSide==RIGHT?1:0]); } /* Insert into list */ if(bLeft) { text[0] = g_strdup(pStr); g_debug_message("left"); } if(bRight) { text[1] = g_strdup(pStr); g_debug_message("right"); } if(s_nLineUpRow == -2) { s_nLineUpRow = s_nLastRow; s_nLastRow = gtk_clist_append(GTK_CLIST(pCntl->pList),text); } else if(s_nLineUpRow == -3) { // s_nLastRow = gtk_clist_append(GTK_CLIST(pCntl->pList),text); s_nLineUpRow = -1; } else if(s_nLineUpRow == -1) { s_nLastRow = gtk_clist_append(GTK_CLIST(pCntl->pList),text); } else { if(s_nLineUpRow >= GTK_CLIST(pCntl->pList)->rows) { s_nLastRow = gtk_clist_append(GTK_CLIST(pCntl->pList),text); } else { g_debug_message("setting text"); gtk_clist_set_text(GTK_CLIST(pCntl->pList),s_nLineUpRow, s_nLastSide==RIGHT?1:0, text[s_nLastSide==RIGHT?1:0]); s_nLineUpRow++; } } } static GtkWidget *s_pFileSel = NULL; static void open_canceled_cb () { gtk_widget_destroy (GTK_WIDGET (s_pFileSel)); s_pFileSel = NULL; } static void open_fileselected_cb () { /* FIXME: Do I free this or what? */ gchar *pFilename = NULL; FILE* pFile = NULL; gint nRead = 0; DiffControl* pCntl = NULL; gchar *pgcLine = NULL; gchar str[DC_BUFF_LEN]; g_return_if_fail (s_pFileSel); pFilename = gtk_file_selection_get_filename (GTK_FILE_SELECTION (s_pFileSel)); g_debug_message (pFilename); pCntl = pharmacy_get_diff(); g_return_if_fail(pCntl); gtk_clist_clear(GTK_CLIST(pCntl->pList)); /* Read in Diff file */ pFile = fopen(pFilename,"r"); if(pFile) { do { g_debug_message("Read"); nRead = fread(str,1,DC_BUFF_LEN-1,pFile); str[nRead] = 0; if(nRead) { concat_to_buffer (&pgcDiffBuffer, str); while (pgcDiffBuffer && (pgcLine = (gchar*)get_next_line (&pgcDiffBuffer))) { diffcontrol_parse (pCntl,pgcLine); g_free (pgcLine); pgcLine = NULL; } } } while(nRead==DC_BUFF_LEN); } open_canceled_cb (); } static void diffcontrol_open_cb () { if (s_pFileSel == NULL) { s_pFileSel = gtk_file_selection_new (_ ("Open a diff file")); } gtk_widget_show (s_pFileSel); gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (s_pFileSel)->ok_button), "clicked", open_fileselected_cb, NULL); gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (s_pFileSel)-> cancel_button), "clicked", open_canceled_cb, NULL); } GtkWidget * pixbutton_new (char *pszText, char *pszPixmap) { GtkWidget *pTemp = NULL; GtkWidget *pTempBox = NULL; GtkWidget *pButton = NULL; gtk_widget_show (pTempBox = gtk_hbox_new (0, 0)); pTemp = gnome_stock_pixmap_widget (GTK_WIDGET (pharmacy_get_app ()), pszPixmap); gtk_box_pack_start (GTK_BOX (pTempBox), pTemp, FALSE, FALSE, 0); gtk_widget_show (pTemp); pTemp = gtk_label_new (pszText); gtk_widget_show (pTemp); gtk_box_pack_start (GTK_BOX (pTempBox), pTemp, FALSE, FALSE, 0); pButton = gtk_button_new (); gtk_container_add (GTK_CONTAINER (pButton), pTempBox); return pButton; } DiffControl * diffcontrol_new () { /* Local Vars */ DiffControl *pCntl = g_malloc (sizeof (DiffControl)); GtkWidget *pScroll = NULL; GtkWidget *phOutBox = NULL; GtkWidget *phDrops = NULL; GtkWidget *pButtonBox = NULL; gchar* text[3]; text[0] = _ ("Left"); text[1] = _ ("Right"); text[2]; if (pCntl) { /* Init State */ pCntl->pList = NULL; pCntl->pFileOneDD = NULL; pCntl->pFileTwoDD = NULL; pCntl->pRefresh = NULL; pCntl->pvBox = NULL; pCntl->pOpen = NULL; /* Create Widgets */ pCntl->pvBox = gtk_vbox_new (0, 0); pCntl->pList = gtk_clist_new_with_titles (2,text); pCntl->pFileOneDD = gtk_combo_new (); pCntl->pFileTwoDD = gtk_combo_new (); pCntl->pRefresh = gtk_button_new (); pCntl->pOpen = gtk_button_new (); phDrops = gtk_hbox_new (0, 0); pButtonBox = gtk_hbox_new (0, 0); /* Buttons */ pCntl->pOpen = pixbutton_new (_ ("Open..."), GNOME_STOCK_PIXMAP_OPEN); gtk_signal_connect (GTK_OBJECT (pCntl->pOpen), "clicked", diffcontrol_open_cb, NULL); /* Put buttons in box */ gtk_box_pack_start (GTK_BOX (pButtonBox), pCntl->pOpen, FALSE, FALSE, 5); /* Combo Boxs (Drop Downs hence DD) */ gtk_box_pack_start (GTK_BOX (phDrops), pCntl->pFileOneDD, TRUE, TRUE, 1); gtk_box_pack_start (GTK_BOX (phDrops), pCntl->pFileTwoDD, TRUE, TRUE, 1); gtk_box_pack_start (GTK_BOX (pCntl->pvBox), phDrops, FALSE, TRUE, 0); gtk_box_pack_start (GTK_BOX (pCntl->pvBox), phOutBox = util_contain_in_scrolled (pCntl->pList), TRUE, TRUE, 1); gtk_box_pack_start (GTK_BOX (pCntl->pvBox), pButtonBox, FALSE, TRUE, 0); gtk_widget_show (pCntl->pList); gtk_widget_show (pCntl->pOpen); gtk_widget_show (pButtonBox); gtk_widget_show (phOutBox); gtk_widget_show (pCntl->pFileOneDD); gtk_widget_show (pCntl->pFileTwoDD); gtk_widget_show (phDrops); gtk_signal_connect (GTK_OBJECT (pharmacy_get_app ()), PHARMACY_UI_UPDATE_SIGNAL, diffcontrol_ui_update_cb, NULL); } return pCntl; } GtkWidget * diffcontrol_get_widget (DiffControl * pCntl) { g_assert (pCntl); return pCntl->pvBox; }