/* AbiWord * Copyright (C) 1998 AbiSource, Inc. * * 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. */ // for gtkclist. todo: use treeview #undef GTK_DISABLE_DEPRECATED #include #include #include #include "ut_string.h" #include "ut_assert.h" #include "ut_debugmsg.h" #include "xap_UnixDialogHelper.h" #include "xap_Dialog_Id.h" #include "xap_UnixApp.h" #include "xap_Frame.h" #include "ap_Strings.h" #include "ap_Dialog_Id.h" #include "ap_Dialog_Goto.h" #include "ap_UnixDialog_Goto.h" #include "fv_View.h" /*****************************************************************/ XAP_Dialog * AP_UnixDialog_Goto::static_constructor(XAP_DialogFactory * pFactory, XAP_Dialog_Id id) { AP_UnixDialog_Goto * p = new AP_UnixDialog_Goto(pFactory, id); return p; } AP_UnixDialog_Goto::AP_UnixDialog_Goto(XAP_DialogFactory * pDlgFactory, XAP_Dialog_Id id) : AP_Dialog_Goto(pDlgFactory,id) { m_wMainWindow = NULL; m_pBookmarks = NULL; } AP_UnixDialog_Goto::~AP_UnixDialog_Goto(void) { if(m_pBookmarks) { delete [] m_pBookmarks; m_pBookmarks = 0; } } void AP_UnixDialog_Goto::s_blist_clicked(GtkWidget *clist, gint row, gint column, GdkEventButton *event, AP_UnixDialog_Goto *me) { gtk_entry_set_text(GTK_ENTRY(me->m_wEntry), (gchar*)me->m_pBookmarks[row]); } char *AP_UnixDialog_Goto::s_convert(const char * st) { UT_ASSERT(st); char *res = g_strdup (st); char *tmp = res; while (*tmp) { if (*tmp == '&') *tmp = '_'; tmp++; } return res; } void AP_UnixDialog_Goto::s_goto (const char *number, AP_UnixDialog_Goto * me) { UT_UCSChar *ucsnumber = (UT_UCSChar *) malloc (sizeof (UT_UCSChar) * (strlen(number) + 1)); UT_UCS4_strcpy_char (ucsnumber, number); int target = me->getSelectedRow (); me->getView()->gotoTarget ((AP_JumpTarget) target, ucsnumber); free (ucsnumber); } void AP_UnixDialog_Goto::s_response (GtkWidget * widget, gint id, AP_UnixDialog_Goto * me ) { switch ( id ) { case BUTTON_PREVIOUS: s_prevClicked ( widget, me ) ; break ; case BUTTON_NEXT: s_nextClicked ( widget, me ) ; break ; case BUTTON_GOTO: s_gotoClicked ( widget, me ) ; break ; default: abiDestroyWidget ( widget ) ; break ; // will emit other signals for us } } void AP_UnixDialog_Goto::s_gotoClicked (GtkWidget * widget, AP_UnixDialog_Goto * me) { const char *number = gtk_entry_get_text (GTK_ENTRY (me->m_wEntry)); if (number && *number) s_goto ((const char *) number, me); } void AP_UnixDialog_Goto::s_nextClicked (GtkWidget * widget, AP_UnixDialog_Goto * me) { s_goto ("+1", me); } void AP_UnixDialog_Goto::s_prevClicked (GtkWidget * widget, AP_UnixDialog_Goto * me) { s_goto ("-1", me); } void AP_UnixDialog_Goto::s_closeClicked (GtkWidget * widget, AP_UnixDialog_Goto * me) { me->destroy(); } void AP_UnixDialog_Goto::s_deleteClicked (GtkWidget * widget, gpointer /* data */,AP_UnixDialog_Goto * me) { me->destroy(); } void AP_UnixDialog_Goto::s_targetChanged (GtkWidget *clist, gint row, gint column, GdkEventButton *event, AP_UnixDialog_Goto *me) { me->setSelectedRow (row); } void AP_UnixDialog_Goto::s_dataChanged (GtkWidget *widget, AP_UnixDialog_Goto * me) { const gchar *text = gtk_entry_get_text (GTK_ENTRY (widget)); if (text[0] == '\0') { gtk_widget_grab_default (me->m_wClose); gtk_widget_set_sensitive (me->m_wGoto, FALSE); } else { gtk_widget_set_sensitive (me->m_wGoto, TRUE); gtk_widget_grab_default (me->m_wGoto); } } void AP_UnixDialog_Goto::setSelectedRow (int row) { m_iRow = row; XAP_String_Id id = AP_STRING_ID_DLG_Goto_Label_Number; const XAP_StringSet * pSS = m_pApp->getStringSet(); if(row == (int) AP_JUMPTARGET_BOOKMARK) { gtk_widget_hide(m_dlabel); gtk_widget_show(m_swindow); gtk_widget_set_sensitive (m_wPrev, FALSE); gtk_widget_set_sensitive (m_wNext, FALSE); id = AP_STRING_ID_DLG_Goto_Label_Name; } else { gtk_widget_hide(m_swindow); gtk_widget_show(m_dlabel); gtk_widget_set_sensitive (m_wPrev, TRUE); gtk_widget_set_sensitive (m_wNext, TRUE); } // change string ids UT_UTF8String s; pSS->getValueUTF8 (id,s); char * tmp = s_convert ((char*)s.utf8_str()); gtk_label_parse_uline (GTK_LABEL (m_numberLabel), tmp); g_free (tmp); } int AP_UnixDialog_Goto::getSelectedRow (void) { return (m_iRow); } void AP_UnixDialog_Goto::runModeless (XAP_Frame * pFrame) { _constructWindow (); setSelectedRow ( 0 ) ; UT_ASSERT (m_wMainWindow); abiSetupModelessDialog( GTK_DIALOG(m_wMainWindow),pFrame, this, BUTTON_CLOSE ); } void AP_UnixDialog_Goto::destroy (void) { UT_ASSERT (m_wMainWindow); modeless_cleanup(); abiDestroyWidget(m_wMainWindow); m_wMainWindow = NULL; } void AP_UnixDialog_Goto::activate (void) { UT_ASSERT (m_wMainWindow); ConstructWindowName(); gtk_window_set_title (GTK_WINDOW (m_wMainWindow), m_WindowName); gdk_window_raise (m_wMainWindow->window); } void AP_UnixDialog_Goto::notifyActiveFrame(XAP_Frame *pFrame) { UT_ASSERT(m_wMainWindow); ConstructWindowName(); gtk_window_set_title (GTK_WINDOW (m_wMainWindow), m_WindowName); } GtkWidget * AP_UnixDialog_Goto::_constructWindow (void) { GtkWidget *vbox; GtkWidget *actionarea; GtkWidget *contents; ConstructWindowName(); m_wMainWindow = abiDialogNew( "goto dialog", TRUE, m_WindowName ); gtk_container_set_border_width (GTK_CONTAINER (m_wMainWindow), 4); vbox = GTK_DIALOG (m_wMainWindow)->vbox; actionarea = GTK_DIALOG (m_wMainWindow)->action_area; contents = _constructWindowContents (); // TODO: This call must be in _constructWindowContents gtk_window_add_accel_group (GTK_WINDOW (m_wMainWindow), m_accelGroup); gtk_box_pack_start (GTK_BOX (vbox), contents, TRUE, TRUE, 0); // Buttons m_wClose = abiAddStockButton(GTK_DIALOG(m_wMainWindow), GTK_STOCK_CLOSE, BUTTON_CLOSE); m_wPrev = abiAddStockButton(GTK_DIALOG(m_wMainWindow), GTK_STOCK_GO_BACK, BUTTON_PREVIOUS); m_wNext = abiAddStockButton(GTK_DIALOG(m_wMainWindow), GTK_STOCK_GO_FORWARD, BUTTON_NEXT); m_wGoto = abiAddStockButton(GTK_DIALOG(m_wMainWindow), GTK_STOCK_JUMP_TO, BUTTON_GOTO); //const XAP_StringSet * pSS = m_pApp->getStringSet(); //m_wGoto = gtk_button_new_with_label (pSS->getValueUTF8 (AP_STRING_ID_DLG_Goto_Btn_Goto).utf8_str()); gtk_widget_show_all (m_wMainWindow); //initially hide the bookmark list; also we want the bookmark list to be // of same size as the descriptive text, so that when we swap them // the whole window does not get resized gtk_window_set_default_size(GTK_WINDOW(m_swindow),(gint)m_dlabel->allocation.width,(gint)m_dlabel->allocation.height); gtk_widget_hide(m_swindow); _connectSignals (); return (m_wMainWindow); } GtkWidget *AP_UnixDialog_Goto::_constructWindowContents (void) { GtkWidget *hbox; GtkWidget *vbox; GtkWidget *what_lb; GtkWidget *clist; GtkWidget *vbox2; GtkWidget *number_lb; GtkWidget *contents; GtkWidget *blist; guint number_lb_key; guint what_lb_key; const XAP_StringSet * pSS = m_pApp->getStringSet(); char *tmp; m_accelGroup = gtk_accel_group_new (); contents = gtk_vbox_new (FALSE, 0); hbox = gtk_hbox_new (FALSE, 8); gtk_box_pack_start (GTK_BOX (contents), hbox, TRUE, TRUE, 0); gtk_container_set_border_width (GTK_CONTAINER (hbox), 4); vbox = gtk_vbox_new (FALSE, 0); gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0); what_lb = gtk_label_new (""); UT_UTF8String s; pSS->getValueUTF8(AP_STRING_ID_DLG_Goto_Label_What,s); tmp = s_convert((char*)s.utf8_str()); what_lb_key = gtk_label_parse_uline (GTK_LABEL (what_lb), tmp); g_free (tmp); gtk_box_pack_start (GTK_BOX (vbox), what_lb, FALSE, FALSE, 0); gtk_misc_set_alignment (GTK_MISC (what_lb), 0, 0.5); clist = gtk_clist_new (1); gtk_box_pack_start (GTK_BOX (vbox), clist, TRUE, TRUE, 0); gtk_clist_set_column_width (GTK_CLIST (clist), 0, 80); gtk_clist_set_selection_mode (GTK_CLIST (clist), GTK_SELECTION_BROWSE); gtk_clist_column_titles_hide (GTK_CLIST (clist)); m_iRow = 0; char **tmp2 = getJumpTargets (); for (int i = 0; tmp2[i] != NULL; i++) gtk_clist_append (GTK_CLIST (clist), &tmp2[i]); vbox2 = gtk_vbox_new (FALSE, 0); gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 0); number_lb = gtk_label_new (""); m_numberLabel = number_lb; pSS->getValueUTF8 (AP_STRING_ID_DLG_Goto_Label_Number,s); tmp = s_convert ((char*)s.utf8_str()); number_lb_key = gtk_label_parse_uline (GTK_LABEL (number_lb), tmp); g_free (tmp); gtk_box_pack_start (GTK_BOX (vbox2), number_lb, FALSE, FALSE, 0); gtk_misc_set_alignment (GTK_MISC (number_lb), 0, 0.5); m_wEntry = gtk_entry_new (); gtk_box_pack_start (GTK_BOX (vbox2), m_wEntry, FALSE, FALSE, 0); pSS->getValueUTF8 (AP_STRING_ID_DLG_Goto_Label_Help,s); m_dlabel = gtk_label_new (s.utf8_str()); gtk_box_pack_start (GTK_BOX (vbox2), m_dlabel, FALSE, FALSE, 0); gtk_label_set_justify (GTK_LABEL (m_dlabel), GTK_JUSTIFY_FILL); gtk_label_set_line_wrap (GTK_LABEL (m_dlabel), TRUE); gtk_misc_set_alignment (GTK_MISC (m_dlabel), 0, 0.5); // the bookmark list m_swindow = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (m_swindow),GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_box_pack_start (GTK_BOX (vbox2), m_swindow, FALSE, FALSE, 0); gtk_widget_hide(m_swindow); blist = gtk_clist_new (1); gtk_clist_set_selection_mode(GTK_CLIST(blist), GTK_SELECTION_BROWSE); gtk_clist_column_titles_hide(GTK_CLIST(blist)); //gtk_box_pack_start (GTK_BOX (vbox2), m_blist, FALSE, FALSE, 0); if(m_pBookmarks) delete [] m_pBookmarks; m_pBookmarks = new const XML_Char *[getExistingBookmarksCount()]; for (int i = 0; i < (int)getExistingBookmarksCount(); i++) m_pBookmarks[i] = getNthExistingBookmark(i); int (*my_cmp)(const void *, const void *) = (int (*)(const void*, const void*)) UT_XML_strcmp; qsort(m_pBookmarks, getExistingBookmarksCount(),sizeof(XML_Char*),my_cmp); for (int i = 0; i < (int)getExistingBookmarksCount(); i++) gtk_clist_append (GTK_CLIST (blist), (gchar**) &m_pBookmarks[i]); gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(m_swindow),blist); //add signal handlers g_signal_connect (G_OBJECT (clist), "select_row", G_CALLBACK (s_targetChanged), this); g_signal_connect (G_OBJECT (m_wEntry), "changed", G_CALLBACK (s_dataChanged), this); g_signal_connect (G_OBJECT (m_wEntry), "activate", G_CALLBACK (s_gotoClicked), this); g_signal_connect (G_OBJECT (blist), "select_row", G_CALLBACK (s_blist_clicked), this); gtk_widget_add_accelerator (clist, "grab_focus", m_accelGroup, what_lb_key, GDK_MOD1_MASK, (GtkAccelFlags) 0); gtk_widget_add_accelerator (m_wEntry, "grab_focus", m_accelGroup, number_lb_key, GDK_MOD1_MASK, (GtkAccelFlags) 0); return contents; } void AP_UnixDialog_Goto::_populateWindowData (void) {} static void s_destroy_clicked(GtkWidget * /* widget */, AP_UnixDialog_Goto * dlg) { UT_ASSERT(dlg); UT_DEBUGMSG(("DOM: destroying dialog\n")); dlg->destroy(); } static void s_delete_clicked(GtkWidget * widget, gpointer, gpointer * dlg) { abiDestroyWidget(widget); } void AP_UnixDialog_Goto::_connectSignals(void) { g_signal_connect_after(G_OBJECT(m_wMainWindow), "response", G_CALLBACK(s_response), this); // the catch-alls // Dont use gtk_signal_connect_after for modeless dialogs g_signal_connect(G_OBJECT(m_wMainWindow), "destroy", G_CALLBACK(s_destroy_clicked), (gpointer) this); g_signal_connect(G_OBJECT(m_wMainWindow), "delete_event", G_CALLBACK(s_delete_clicked), (gpointer) this); }