1 /* -*- mode: C++; tab-width: 4; c-basic-offset: 4; -*- */
2
3 /* AbiWord
4 * Copyright (C) 1998 AbiSource, Inc.
5 * Copyright (C) Robert Staudinger <robsta@stereolyzer.net>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301 USA.
21 */
22
23
24 #include <stdlib.h>
25 #include <string.h>
26 #include <gtk/gtk.h>
27
28 #include "ut_string.h"
29 #include "ut_assert.h"
30 #include "ut_debugmsg.h"
31 #include "xap_UnixDialogHelper.h"
32 #include "xap_GtkSignalBlocker.h"
33
34 #include "xap_Dialog_Id.h"
35 #include "xap_UnixApp.h"
36 #include "xap_Frame.h"
37
38 #include "ap_Strings.h"
39 #include "ap_Dialog_Id.h"
40 #include "ap_Dialog_Goto.h"
41 #include "ap_UnixDialog_Goto.h"
42
43 #include "GTKCommon.h"
44
45
AP_UnixDialog_Goto__onSwitchPage(GtkNotebook * notebook,gpointer Page,guint page,gpointer data)46 static void AP_UnixDialog_Goto__onSwitchPage (GtkNotebook *notebook,
47 gpointer Page,
48 guint page,
49 gpointer data)
50 {
51 UT_UNUSED(notebook);
52 UT_UNUSED(Page);
53 UT_DEBUGMSG(("_onSwitchPage() '%d'\n", page));
54
55 if (page == 0)
56 {
57 AP_UnixDialog_Goto *dlg = static_cast<AP_UnixDialog_Goto *>(data);
58 dlg->updatePosition();
59 }
60 }
61
62 /*!
63 * Event dispatcher for spinbutton "page".
64 */
65 gboolean
AP_UnixDialog_Goto__onFocusPage(GtkWidget *,GdkEventFocus * event,gpointer data)66 AP_UnixDialog_Goto__onFocusPage (GtkWidget * /*widget*/,
67 GdkEventFocus *event,
68 gpointer data)
69 {
70 UT_DEBUGMSG (("ROB: _onFocusPage () '%d', '%d'\n", event->type, event->in));
71 if (event->type == GDK_FOCUS_CHANGE && event->in) {
72 AP_UnixDialog_Goto *dlg = static_cast <AP_UnixDialog_Goto *>(data);
73 dlg->updateCache (AP_JUMPTARGET_PAGE);
74 }
75 /* propagate further */
76 return FALSE;
77 }
78
79 /*!
80 * Event dispatcher for spinbutton "line".
81 */
82 gboolean
AP_UnixDialog_Goto__onFocusLine(GtkWidget *,GdkEventFocus * event,gpointer data)83 AP_UnixDialog_Goto__onFocusLine (GtkWidget * /*widget*/,
84 GdkEventFocus *event,
85 gpointer data)
86 {
87 UT_DEBUGMSG (("ROB: _onFocusLine () '%d', '%d'\n", event->type, event->in));
88 if (event->type == GDK_FOCUS_CHANGE && event->in) {
89 AP_UnixDialog_Goto *dlg = static_cast <AP_UnixDialog_Goto *>(data);
90 dlg->updateCache (AP_JUMPTARGET_LINE);
91 }
92 /* propagate further */
93 return FALSE;
94 }
95
96 /*!
97 * Event dispatcher for treeview "bookmarks".
98 */
99 gboolean
AP_UnixDialog_Goto__onFocusBookmarks(GtkWidget *,GdkEventFocus * event,gpointer data)100 AP_UnixDialog_Goto__onFocusBookmarks (GtkWidget * /*widget*/,
101 GdkEventFocus *event,
102 gpointer data)
103 {
104 UT_DEBUGMSG (("ROB: _onFocusBookmarks () '%d', '%d'\n", event->type, event->in));
105 if (event->type == GDK_FOCUS_CHANGE && event->in) {
106 AP_UnixDialog_Goto *dlg = static_cast <AP_UnixDialog_Goto *>(data);
107 dlg->updateCache (AP_JUMPTARGET_BOOKMARK);
108 }
109 /* propagate further */
110 return FALSE;
111 }
112 gboolean
AP_UnixDialog_Goto__onFocusXMLIDs(GtkWidget *,GdkEventFocus * event,gpointer data)113 AP_UnixDialog_Goto__onFocusXMLIDs (GtkWidget * /*widget*/,
114 GdkEventFocus *event,
115 gpointer data)
116 {
117 UT_DEBUGMSG (("MIQ: _onFocusXMLIDs () '%d', '%d'\n", event->type, event->in));
118 if (event->type == GDK_FOCUS_CHANGE && event->in)
119 {
120 AP_UnixDialog_Goto *dlg = static_cast <AP_UnixDialog_Goto *>(data);
121 dlg->updateCache (AP_JUMPTARGET_XMLID);
122 }
123 /* propagate further */
124 return FALSE;
125 }
126 gboolean
AP_UnixDialog_Goto__onFocusAnno(GtkWidget *,GdkEventFocus * event,gpointer data)127 AP_UnixDialog_Goto__onFocusAnno (GtkWidget * /*widget*/,
128 GdkEventFocus *event,
129 gpointer data)
130 {
131 UT_DEBUGMSG (("MIQ: _onFocusAnno () '%d', '%d'\n", event->type, event->in));
132 if (event->type == GDK_FOCUS_CHANGE && event->in)
133 {
134 AP_UnixDialog_Goto *dlg = static_cast <AP_UnixDialog_Goto *>(data);
135 dlg->updateCache (AP_JUMPTARGET_ANNOTATION);
136 }
137 /* propagate further */
138 return FALSE;
139 }
140
141 /*!
142 * Event dispatcher for spinbutton "page".
143 */
144 void
AP_UnixDialog_Goto__onPageChanged(GtkSpinButton *,gpointer data)145 AP_UnixDialog_Goto__onPageChanged (GtkSpinButton * /*spinbutton*/,
146 gpointer data)
147 {
148 AP_UnixDialog_Goto *dlg = static_cast <AP_UnixDialog_Goto *>(data);
149 dlg->onPageChanged ();
150 }
151
152 /*!
153 * Event dispatcher for spinbutton "line".
154 */
155 void
AP_UnixDialog_Goto__onLineChanged(GtkSpinButton *,gpointer data)156 AP_UnixDialog_Goto__onLineChanged (GtkSpinButton * /*spinbutton*/,
157 gpointer data)
158 {
159 AP_UnixDialog_Goto *dlg = static_cast <AP_UnixDialog_Goto *>(data);
160 dlg->onLineChanged ();
161 }
162
163 /*!
164 * Event dispatcher for treeview "bookmarks".
165 */
166 void
AP_UnixDialog_Goto__onBookmarkDblClicked(GtkTreeView *,GtkTreePath *,GtkTreeViewColumn *,gpointer data)167 AP_UnixDialog_Goto__onBookmarkDblClicked (GtkTreeView * /*tree*/,
168 GtkTreePath * /*path*/,
169 GtkTreeViewColumn * /*col*/,
170 gpointer data)
171 {
172 AP_UnixDialog_Goto *dlg = static_cast <AP_UnixDialog_Goto *>(data);
173 dlg->onBookmarkDblClicked ();
174 }
175 void
AP_UnixDialog_Goto__onXMLIDDblClicked(GtkTreeView *,GtkTreePath *,GtkTreeViewColumn *,gpointer data)176 AP_UnixDialog_Goto__onXMLIDDblClicked (GtkTreeView * /*tree*/,
177 GtkTreePath * /*path*/,
178 GtkTreeViewColumn * /*col*/,
179 gpointer data)
180 {
181 AP_UnixDialog_Goto *dlg = static_cast <AP_UnixDialog_Goto *>(data);
182 dlg->onXMLIDDblClicked ();
183 }
184 void
AP_UnixDialog_Goto__onAnnoDblClicked(GtkTreeView *,GtkTreePath *,GtkTreeViewColumn *,gpointer data)185 AP_UnixDialog_Goto__onAnnoDblClicked (GtkTreeView * /*tree*/,
186 GtkTreePath * /*path*/,
187 GtkTreeViewColumn * /*col*/,
188 gpointer data)
189 {
190 AP_UnixDialog_Goto *dlg = static_cast <AP_UnixDialog_Goto *>(data);
191 dlg->onAnnoDblClicked ();
192 }
193
194 /*!
195 * Event dispatcher for button "jump".
196 */
197 void
AP_UnixDialog_Goto__onJumpClicked(GtkButton *,gpointer data)198 AP_UnixDialog_Goto__onJumpClicked (GtkButton * /*button*/,
199 gpointer data)
200 {
201 AP_UnixDialog_Goto *dlg = static_cast <AP_UnixDialog_Goto *>(data);
202 dlg->onJumpClicked ();
203 }
204
205 /*!
206 * Event dispatcher for button "prev".
207 */
208 void
AP_UnixDialog_Goto__onPrevClicked(GtkButton *,gpointer data)209 AP_UnixDialog_Goto__onPrevClicked (GtkButton * /*button*/,
210 gpointer data)
211 {
212 AP_UnixDialog_Goto *dlg = static_cast <AP_UnixDialog_Goto *>(data);
213 dlg->onPrevClicked ();
214 }
215
216 /*!
217 * Event dispatcher for button "next".
218 */
219 void
AP_UnixDialog_Goto__onNextClicked(GtkButton *,gpointer data)220 AP_UnixDialog_Goto__onNextClicked (GtkButton * /*button*/,
221 gpointer data)
222 {
223 AP_UnixDialog_Goto *dlg = static_cast <AP_UnixDialog_Goto *>(data);
224 dlg->onNextClicked ();
225 }
226
227 /*!
228 * Event dispatcher for button "close".
229 */
230 void
AP_UnixDialog_Goto__onDialogResponse(GtkDialog *,gint response,gpointer data)231 AP_UnixDialog_Goto__onDialogResponse (GtkDialog * /*dialog*/,
232 gint response,
233 gpointer data)
234 {
235 AP_UnixDialog_Goto *dlg = static_cast <AP_UnixDialog_Goto *>(data);
236 if (response == GTK_RESPONSE_CLOSE) {
237 dlg->destroy ();
238 }
239 }
240
241 /*!
242 * Event dispatcher for window.
243 */
244 gboolean
AP_UnixDialog_Goto__onDeleteWindow(GtkWidget *,GdkEvent *,gpointer data)245 AP_UnixDialog_Goto__onDeleteWindow (GtkWidget * /*widget*/,
246 GdkEvent * /*event*/,
247 gpointer data)
248 {
249 AP_UnixDialog_Goto *dlg = static_cast <AP_UnixDialog_Goto *>(data);
250 if (dlg->getWindow ()) {
251 dlg->destroy ();
252 }
253 return TRUE;
254 }
255
256
257
258 /*!
259 * Static ctor.
260 */
261 XAP_Dialog *
static_constructor(XAP_DialogFactory * pFactory,XAP_Dialog_Id id)262 AP_UnixDialog_Goto::static_constructor(XAP_DialogFactory *pFactory,
263 XAP_Dialog_Id id)
264 {
265 AP_UnixDialog_Goto *dlg = new AP_UnixDialog_Goto (pFactory, id);
266 return dlg;
267 }
268
269 /*!
270 * Ctor.
271 */
AP_UnixDialog_Goto(XAP_DialogFactory * pDlgFactory,XAP_Dialog_Id id)272 AP_UnixDialog_Goto::AP_UnixDialog_Goto(XAP_DialogFactory *pDlgFactory,
273 XAP_Dialog_Id id)
274 : AP_Dialog_Goto (pDlgFactory, id),
275 m_wDialog (NULL),
276 m_nbNotebook (NULL),
277 m_lbPage (NULL),
278 m_lbLine (NULL),
279 m_lbBookmarks (NULL),
280 m_lbXMLids (NULL),
281 m_lbAnnotations (NULL),
282 m_sbPage (NULL),
283 m_sbLine (NULL),
284 m_lvBookmarks (NULL),
285 m_btJump (NULL),
286 m_btPrev (NULL),
287 m_btNext (NULL),
288 m_lvXMLIDs (0),
289 m_lvAnno (0),
290 m_btClose (NULL),
291 m_iPageConnect (0),
292 m_iLineConnect (0),
293 m_JumpTarget (AP_JUMPTARGET_BOOKMARK)
294 {
295 }
296
297 /*!
298 * Dtor.
299 */
~AP_UnixDialog_Goto()300 AP_UnixDialog_Goto::~AP_UnixDialog_Goto ()
301 {
302 UT_DEBUGMSG (("ROB: ~AP_UnixDialog_Goto ()\n"));
303 }
304
305
306
307 /*!
308 * Event handler for spinbutton "page".
309 */
310 void
onPageChanged()311 AP_UnixDialog_Goto::onPageChanged ()
312 {
313 UT_DEBUGMSG (("ROB: onPageChanged () maxpage='%d'\n", m_DocCount.page));
314 m_JumpTarget = AP_JUMPTARGET_PAGE;
315 UT_uint32 page = (UT_uint32)gtk_spin_button_get_value (GTK_SPIN_BUTTON (m_sbPage));
316 if (page > m_DocCount.page) {
317 gtk_spin_button_set_value (GTK_SPIN_BUTTON (m_sbPage), 1);
318 }
319 onJumpClicked();
320 }
321
322 /*!
323 * Event handler for spinbutton "line".
324 */
325 void
onLineChanged()326 AP_UnixDialog_Goto::onLineChanged ()
327 {
328 UT_DEBUGMSG (("ROB: onLineChanged () maxline='%d'\n", m_DocCount.line));
329 m_JumpTarget = AP_JUMPTARGET_LINE;
330 UT_uint32 line = (UT_uint32)gtk_spin_button_get_value (GTK_SPIN_BUTTON (m_sbLine));
331 if (line > m_DocCount.line) {
332 gtk_spin_button_set_value (GTK_SPIN_BUTTON (m_sbLine), 1);
333 }
334 if (line == 0) {
335 gtk_spin_button_set_value (GTK_SPIN_BUTTON (m_sbLine), m_DocCount.line);
336 }
337 onJumpClicked();
338 }
339
340 /*!
341 * Event handler for treeview "bookmarks".
342 */
343 void
onBookmarkDblClicked()344 AP_UnixDialog_Goto::onBookmarkDblClicked ()
345 {
346 m_JumpTarget = AP_JUMPTARGET_BOOKMARK;
347 onJumpClicked();
348 }
349 void
onXMLIDDblClicked()350 AP_UnixDialog_Goto::onXMLIDDblClicked ()
351 {
352 m_JumpTarget = AP_JUMPTARGET_XMLID;
353 onJumpClicked();
354 }
355 void
onAnnoDblClicked()356 AP_UnixDialog_Goto::onAnnoDblClicked ()
357 {
358 m_JumpTarget = AP_JUMPTARGET_ANNOTATION;
359 onJumpClicked();
360 }
361
362 /*!
363 * Event handler for button "jump".
364 */
365 void
onJumpClicked()366 AP_UnixDialog_Goto::onJumpClicked ()
367 {
368 std::string text;
369 XAP_GtkSignalBlocker b(G_OBJECT(m_sbLine), m_iLineConnect);
370
371 switch (m_JumpTarget) {
372 case AP_JUMPTARGET_PAGE:
373 gtk_spin_button_set_value(GTK_SPIN_BUTTON(m_sbLine), 0);
374 text = tostr(GTK_ENTRY (m_sbPage));
375 break;
376 case AP_JUMPTARGET_LINE:
377 text = tostr(GTK_ENTRY (m_sbLine));
378 if (text == "0") return;
379 break;
380 case AP_JUMPTARGET_BOOKMARK:
381 text = _getSelectedBookmarkLabel ();
382 break;
383 case AP_JUMPTARGET_XMLID:
384 text = _getSelectedXMLIDLabel();
385 break;
386 case AP_JUMPTARGET_ANNOTATION:
387 text = _getSelectedAnnotationLabel();
388 break;
389 default:
390 UT_DEBUGMSG (("AP_UnixDialog_Goto::onJumpClicked () no jump target\n"));
391 return;
392 // UT_ASSERT_NOT_REACHED ();
393 }
394
395 if (text.empty())
396 return;
397
398 performGoto(m_JumpTarget, text.c_str());
399 }
400
401 /*!
402 * Event handler for button "prev".
403 */
404 void
onPrevClicked()405 AP_UnixDialog_Goto::onPrevClicked ()
406 {
407 UT_DEBUGMSG (("ROB: onPrevClicked () '%d'\n", m_JumpTarget));
408
409 UT_uint32 num = 0;
410 switch (m_JumpTarget) {
411 case AP_JUMPTARGET_PAGE:
412 num = (UT_uint32)gtk_spin_button_get_value (GTK_SPIN_BUTTON (m_sbPage));
413 if (num == 1)
414 num = m_DocCount.page;
415 else
416 num--;
417 gtk_spin_button_set_value (GTK_SPIN_BUTTON (m_sbPage), num);
418 break;
419 case AP_JUMPTARGET_LINE:
420 num = (UT_uint32)gtk_spin_button_get_value (GTK_SPIN_BUTTON (m_sbLine));
421 if (num == 1)
422 num = m_DocCount.line;
423 else
424 num--;
425 gtk_spin_button_set_value (GTK_SPIN_BUTTON (m_sbLine), num);
426 break;
427 case AP_JUMPTARGET_BOOKMARK:
428 _selectPrevBookmark ();
429 break;
430 case AP_JUMPTARGET_XMLID:
431 selectPrev(GTK_TREE_VIEW (m_lvXMLIDs));
432 break;
433 case AP_JUMPTARGET_ANNOTATION:
434 selectPrev(GTK_TREE_VIEW (m_lvAnno));
435 break;
436 default:
437 UT_DEBUGMSG (("ROB: AP_UnixDialog_Goto::onPrevClicked () no jump target\n"));
438 return;
439 // UT_ASSERT_NOT_REACHED ();
440 }
441
442 onJumpClicked ();
443 }
444
445 /*!
446 * Event handler for button "next".
447 */
448 void
onNextClicked()449 AP_UnixDialog_Goto::onNextClicked ()
450 {
451 UT_DEBUGMSG (("ROB: onNextClicked () '%d'\n", m_JumpTarget));
452
453 UT_uint32 num = 0;
454 switch (m_JumpTarget) {
455 case AP_JUMPTARGET_PAGE:
456 num = (UT_uint32)gtk_spin_button_get_value (GTK_SPIN_BUTTON (m_sbPage));
457 num++;
458 gtk_spin_button_set_value (GTK_SPIN_BUTTON (m_sbPage), num);
459 break;
460 case AP_JUMPTARGET_LINE:
461 num = (UT_uint32)gtk_spin_button_get_value (GTK_SPIN_BUTTON (m_sbLine));
462 num++;
463 gtk_spin_button_set_value (GTK_SPIN_BUTTON (m_sbLine), num);
464 break;
465 case AP_JUMPTARGET_BOOKMARK:
466 _selectNextBookmark ();
467 break;
468 case AP_JUMPTARGET_XMLID:
469 selectNext(GTK_TREE_VIEW (m_lvXMLIDs));
470 break;
471 case AP_JUMPTARGET_ANNOTATION:
472 selectNext(GTK_TREE_VIEW (m_lvAnno));
473 break;
474 default:
475 UT_DEBUGMSG (("ROB: AP_UnixDialog_Goto::onNextClicked () no jump target\n"));
476 return;
477 // UT_ASSERT_NOT_REACHED ();
478 }
479
480 onJumpClicked ();
481 }
482
483 /*!
484 * Set jump target and update cached data like number of lines and pages.
485 * @see ap_types.h
486 */
487 void
updateCache(AP_JumpTarget target)488 AP_UnixDialog_Goto::updateCache (AP_JumpTarget target)
489 {
490 m_JumpTarget = target;
491 updateDocCount ();
492 }
493
494 /*!
495 * Update cached data like number of lines and pages.
496 */
497 void
updateDocCount()498 AP_UnixDialog_Goto::updateDocCount ()
499 {
500 m_DocCount = getView()->countWords(false);
501 UT_DEBUGMSG (("ROB: updateCache () page='%d' line='%d'\n", m_DocCount.page, m_DocCount.line));
502 }
503
updatePosition(void)504 void AP_UnixDialog_Goto::updatePosition (void)
505 {
506 // pages, page increment of 10 is pretty arbitrary (set in the GtkBuilder UI file)
507 UT_uint32 currentPage = getView()->getCurrentPageNumForStatusBar ();
508 XAP_GtkSignalBlocker b1(G_OBJECT(m_sbPage), m_iPageConnect);
509 gtk_spin_button_set_value (GTK_SPIN_BUTTON (m_sbPage), currentPage);
510
511 // lines, line increment of 10 is pretty arbitrary (set in the GtkBuilder UI file)
512 UT_uint32 currentLine = 0; /* FIXME get current line */
513 XAP_GtkSignalBlocker b2(G_OBJECT(m_sbLine), m_iLineConnect);
514 gtk_spin_button_set_value (GTK_SPIN_BUTTON (m_sbLine), currentLine);
515 }
516
517 void
setupXMLIDList(GtkWidget * w)518 AP_UnixDialog_Goto::setupXMLIDList( GtkWidget* w )
519 {
520 // Liststore and -view
521 GtkListStore *store = gtk_list_store_new ( NUM_COLUMNS, G_TYPE_STRING );
522 gtk_tree_view_set_model (GTK_TREE_VIEW (w), GTK_TREE_MODEL (store));
523 g_object_unref (G_OBJECT (store));
524
525 // Column Bookmark
526 GtkCellRenderer *renderer = NULL;
527 renderer = gtk_cell_renderer_text_new ();
528 gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (w),
529 -1, "Name", renderer,
530 "text", COLUMN_NAME,
531 NULL);
532 GtkTreeViewColumn *column = gtk_tree_view_get_column (GTK_TREE_VIEW (w), 0);
533 gtk_tree_view_column_set_sort_column_id (column, COLUMN_NAME);
534
535 g_signal_connect (GTK_TREE_VIEW (w), "focus-in-event",
536 G_CALLBACK (AP_UnixDialog_Goto__onFocusXMLIDs), static_cast <gpointer>(this));
537 g_signal_connect (GTK_TREE_VIEW (w), "row-activated",
538 G_CALLBACK (AP_UnixDialog_Goto__onXMLIDDblClicked), static_cast <gpointer>(this));
539 }
540
541
542 void
setupAnnotationList(GtkWidget * w)543 AP_UnixDialog_Goto::setupAnnotationList( GtkWidget* w )
544 {
545 GtkTreeViewColumn *column = NULL;
546 GtkCellRenderer *renderer = NULL;
547 // Liststore and -view
548 GtkListStore *store = gtk_list_store_new ( NUM_ANNO_COLUMNS,
549 G_TYPE_INT,
550 G_TYPE_STRING, G_TYPE_STRING );
551 gtk_tree_view_set_model (GTK_TREE_VIEW (w), GTK_TREE_MODEL (store));
552 g_object_unref (G_OBJECT (store));
553
554 // localization
555 const XAP_StringSet * pSS = m_pApp->getStringSet ();
556 std::string id, title, author;
557 pSS->getValueUTF8(AP_STRING_ID_DLG_Goto_Column_ID, id);
558 pSS->getValueUTF8(AP_STRING_ID_DLG_Goto_Column_Title, title);
559 pSS->getValueUTF8(AP_STRING_ID_DLG_Goto_Column_Author, author);
560
561 renderer = gtk_cell_renderer_text_new ();
562 gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (w),
563 -1, id.c_str(), renderer,
564 "text", COLUMN_ANNO_ID,
565 NULL);
566 column = gtk_tree_view_get_column (GTK_TREE_VIEW (w), COLUMN_ANNO_ID );
567 gtk_tree_view_column_set_sort_column_id (column, COLUMN_ANNO_ID );
568
569 renderer = gtk_cell_renderer_text_new ();
570 gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (w),
571 -1, title.c_str(), renderer,
572 "text", COLUMN_ANNO_TITLE,
573 NULL);
574 column = gtk_tree_view_get_column (GTK_TREE_VIEW (w), COLUMN_ANNO_TITLE );
575 gtk_tree_view_column_set_sort_column_id (column, COLUMN_ANNO_TITLE );
576
577
578 renderer = gtk_cell_renderer_text_new ();
579 gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (w),
580 -1, author.c_str(), renderer,
581 "text", COLUMN_ANNO_AUTHOR,
582 NULL);
583 column = gtk_tree_view_get_column (GTK_TREE_VIEW (w), COLUMN_ANNO_AUTHOR );
584 gtk_tree_view_column_set_sort_column_id (column, COLUMN_ANNO_AUTHOR );
585
586
587
588 g_signal_connect (GTK_TREE_VIEW (w), "focus-in-event",
589 G_CALLBACK (AP_UnixDialog_Goto__onFocusAnno), static_cast <gpointer>(this));
590 g_signal_connect (GTK_TREE_VIEW (w), "row-activated",
591 G_CALLBACK (AP_UnixDialog_Goto__onAnnoDblClicked), static_cast <gpointer>(this));
592 }
593
594
595 /*!
596 * Build dialog.
597 */
598 void
_constructWindow(XAP_Frame *)599 AP_UnixDialog_Goto::_constructWindow (XAP_Frame * /*pFrame*/)
600 {
601 UT_DEBUGMSG (("ROB: _constructWindow ()\n"));
602
603 // load the dialog from the UI file
604 #if GTK_CHECK_VERSION(3,0,0)
605 GtkBuilder* builder = newDialogBuilder("ap_UnixDialog_Goto.ui");
606 #else
607 GtkBuilder* builder = newDialogBuilder("ap_UnixDialog_Goto-2.ui");
608 #endif
609
610 m_wDialog = GTK_WIDGET(gtk_builder_get_object(builder, "ap_UnixDialog_Goto"));
611 m_nbNotebook = GTK_WIDGET(gtk_builder_get_object(builder, "nbNotebook"));
612 m_lbPage = GTK_WIDGET(gtk_builder_get_object(builder, "lbPage"));
613 m_lbLine = GTK_WIDGET(gtk_builder_get_object(builder, "lbLine"));
614 m_lbBookmarks = GTK_WIDGET(gtk_builder_get_object(builder, "lbBookmarks"));
615 m_lbXMLids = GTK_WIDGET(gtk_builder_get_object(builder, "lbXMLids"));
616 m_lbAnnotations = GTK_WIDGET(gtk_builder_get_object(builder, "lbAnnotations"));
617 m_sbPage = GTK_WIDGET(gtk_builder_get_object(builder, "sbPage"));
618 m_sbLine = GTK_WIDGET(gtk_builder_get_object(builder, "sbLine"));
619 m_lvBookmarks = GTK_WIDGET(gtk_builder_get_object(builder, "lvBookmarks"));
620 m_btJump = GTK_WIDGET(gtk_builder_get_object(builder, "btJump"));
621 m_btPrev = GTK_WIDGET(gtk_builder_get_object(builder, "btPrev"));
622 m_btNext = GTK_WIDGET(gtk_builder_get_object(builder, "btNext"));
623 m_lvXMLIDs = GTK_WIDGET(gtk_builder_get_object(builder, "lvXMLIDs"));
624 m_lvAnno = GTK_WIDGET(gtk_builder_get_object(builder, "lvAnno"));
625 m_btClose = GTK_WIDGET(gtk_builder_get_object(builder, "btClose"));
626
627
628 // localise
629 const XAP_StringSet * pSS = m_pApp->getStringSet();
630 localizeLabel(GTK_WIDGET(gtk_builder_get_object(builder, "lbPosition")), pSS, AP_STRING_ID_DLG_Goto_Label_Position);
631 /* FIXME jump targets localised in xp land, make sure they work for non ascii characters */
632 const gchar **targets = getJumpTargets ();
633 const gchar *text = NULL;
634 if ((text = targets[AP_JUMPTARGET_PAGE]) != NULL)
635 gtk_label_set_text (GTK_LABEL (m_lbPage), text);
636 if ((text = targets[AP_JUMPTARGET_LINE]) != NULL)
637 gtk_label_set_text (GTK_LABEL (m_lbLine), text);
638 if ((text = targets[AP_JUMPTARGET_BOOKMARK]) != NULL)
639 gtk_label_set_text (GTK_LABEL (m_lbBookmarks), text);
640 if ((text = targets[AP_JUMPTARGET_XMLID]) != NULL)
641 gtk_label_set_text (GTK_LABEL (m_lbXMLids), text);
642 if ((text = targets[AP_JUMPTARGET_ANNOTATION]) != NULL)
643 gtk_label_set_text (GTK_LABEL (m_lbAnnotations), text);
644
645
646 setupXMLIDList( m_lvXMLIDs );
647 setupAnnotationList( m_lvAnno );
648
649 // Liststore and -view
650 GtkListStore *store = gtk_list_store_new (NUM_COLUMNS, G_TYPE_STRING);
651 gtk_tree_view_set_model (GTK_TREE_VIEW (m_lvBookmarks), GTK_TREE_MODEL (store));
652 g_object_unref (G_OBJECT (store));
653
654 // Column Bookmark
655 GtkCellRenderer *renderer = NULL;
656 renderer = gtk_cell_renderer_text_new ();
657 gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (m_lvBookmarks),
658 -1, "Name", renderer,
659 "text", COLUMN_NAME,
660 NULL);
661 GtkTreeViewColumn *column = gtk_tree_view_get_column (GTK_TREE_VIEW (m_lvBookmarks), 0);
662 gtk_tree_view_column_set_sort_column_id (column, COLUMN_NAME);
663
664 // Signals
665 g_signal_connect (GTK_NOTEBOOK (m_nbNotebook), "switch-page",
666 G_CALLBACK (AP_UnixDialog_Goto__onSwitchPage), static_cast <gpointer>(this));
667 g_signal_connect (GTK_SPIN_BUTTON (m_sbPage), "focus-in-event",
668 G_CALLBACK (AP_UnixDialog_Goto__onFocusPage), static_cast <gpointer>(this));
669 m_iPageConnect = g_signal_connect (GTK_SPIN_BUTTON (m_sbPage), "value-changed",
670 G_CALLBACK (AP_UnixDialog_Goto__onPageChanged), static_cast <gpointer>(this));
671
672 g_signal_connect (GTK_SPIN_BUTTON (m_sbLine), "focus-in-event",
673 G_CALLBACK (AP_UnixDialog_Goto__onFocusLine), static_cast <gpointer>(this));
674 m_iLineConnect = g_signal_connect (GTK_SPIN_BUTTON (m_sbLine), "value-changed",
675 G_CALLBACK (AP_UnixDialog_Goto__onLineChanged), static_cast <gpointer>(this));
676
677 g_signal_connect (GTK_TREE_VIEW (m_lvBookmarks), "focus-in-event",
678 G_CALLBACK (AP_UnixDialog_Goto__onFocusBookmarks), static_cast <gpointer>(this));
679 g_signal_connect (GTK_TREE_VIEW (m_lvBookmarks), "row-activated",
680 G_CALLBACK (AP_UnixDialog_Goto__onBookmarkDblClicked), static_cast <gpointer>(this));
681
682 g_signal_connect (GTK_BUTTON (m_btJump), "clicked",
683 G_CALLBACK (AP_UnixDialog_Goto__onJumpClicked), static_cast <gpointer>(this));
684 g_signal_connect (GTK_BUTTON (m_btPrev), "clicked",
685 G_CALLBACK (AP_UnixDialog_Goto__onPrevClicked), static_cast <gpointer>(this));
686 g_signal_connect (GTK_BUTTON (m_btNext), "clicked",
687 G_CALLBACK (AP_UnixDialog_Goto__onNextClicked), static_cast <gpointer>(this));
688
689 g_signal_connect (GTK_DIALOG (m_wDialog), "response",
690 G_CALLBACK (AP_UnixDialog_Goto__onDialogResponse), static_cast <gpointer>(this));
691 g_signal_connect (m_wDialog, "delete-event",
692 G_CALLBACK (AP_UnixDialog_Goto__onDeleteWindow), static_cast <gpointer>(this));
693
694 g_object_unref(G_OBJECT(builder));
695 }
696
697 /*!
698 * Update dialog's data.
699 */
700 void
_updateWindow()701 AP_UnixDialog_Goto::_updateWindow ()
702 {
703 UT_DEBUGMSG (("ROB: _updateWindow () #bookmarks='%d', mapped='%d'\n", getExistingBookmarksCount(), gtk_widget_get_mapped(m_wDialog)));
704
705 ConstructWindowName ();
706 gtk_window_set_title (GTK_WINDOW (m_wDialog), m_WindowName);
707
708 // position: pages and lines
709 updatePosition();
710
711 // bookmarks, detaching model for faster updates
712 GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (m_lvBookmarks));
713 g_object_ref (G_OBJECT (model));
714 gtk_tree_view_set_model (GTK_TREE_VIEW (m_lvBookmarks), NULL);
715 gtk_list_store_clear (GTK_LIST_STORE (model));
716
717 GtkTreeIter iter;
718 UT_uint32 numBookmarks = getExistingBookmarksCount();
719 for (UT_uint32 i = 0; i < numBookmarks; i++) {
720
721 gtk_list_store_append (GTK_LIST_STORE (model), &iter);
722 const std::string & name = getNthExistingBookmark(i);
723 UT_DEBUGMSG ((" ROB: '%s'\n", name.c_str()));
724 gtk_list_store_set (GTK_LIST_STORE (model), &iter,
725 COLUMN_NAME, name.c_str(), /*
726 COLUMN_PAGE, "0",
727 COLUMN_NUMBER, 0, */
728 -1);
729 }
730 gtk_tree_view_set_model (GTK_TREE_VIEW (m_lvBookmarks), model);
731 g_object_unref (G_OBJECT (model));
732
733 updateXMLIDList( m_lvXMLIDs );
734 updateAnnotationList( m_lvAnno );
735 updateDocCount ();
736 }
737
738
739 void
updateXMLIDList(GtkWidget * w)740 AP_UnixDialog_Goto::updateXMLIDList( GtkWidget* w )
741 {
742 // detaching model for faster updates
743 GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (w));
744 g_object_ref (G_OBJECT (model));
745 gtk_tree_view_set_model (GTK_TREE_VIEW (w), NULL);
746 gtk_list_store_clear (GTK_LIST_STORE (model));
747
748 if( PD_DocumentRDFHandle rdf = getRDF() )
749 {
750 GtkTreeIter iter;
751 std::set< std::string > xmlids;
752 rdf->getAllIDs( xmlids );
753 UT_DEBUGMSG (("MIQ: xmlids.sz:%lu\n", (long unsigned)xmlids.size() ));
754
755 for( std::set< std::string >::iterator xiter = xmlids.begin();
756 xiter != xmlids.end(); ++xiter )
757 {
758 gtk_list_store_append (GTK_LIST_STORE (model), &iter);
759 std::string name = *xiter;
760 UT_DEBUGMSG ((" MIQ: '%s'\n", name.c_str()));
761 gtk_list_store_set (GTK_LIST_STORE (model), &iter,
762 COLUMN_NAME, name.c_str(), -1);
763 }
764 }
765
766 gtk_tree_view_set_model (GTK_TREE_VIEW (w), model);
767 g_object_unref (G_OBJECT (model));
768
769 }
770
771
772 void
updateAnnotationList(GtkWidget * w)773 AP_UnixDialog_Goto::updateAnnotationList( GtkWidget* w )
774 {
775 // detaching model for faster updates
776 GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (w));
777 g_object_ref (G_OBJECT (model));
778 gtk_tree_view_set_model (GTK_TREE_VIEW (w), NULL);
779 gtk_list_store_clear (GTK_LIST_STORE (model));
780
781 GtkTreeIter iter;
782 FV_View* pView = getView();
783 UT_uint32 max = pView->countAnnotations();
784 for( UT_uint32 i=0; i<max; ++i )
785 {
786 gtk_list_store_append (GTK_LIST_STORE (model), &iter);
787 std::string name = tostr(i);
788 std::string title = pView->getAnnotationTitle(i);
789 std::string author = pView->getAnnotationAuthor(i);
790
791 UT_DEBUGMSG ((" MIQ: '%s'\n", name.c_str()));
792 gtk_list_store_set (GTK_LIST_STORE (model), &iter,
793 COLUMN_ANNO_ID, i,
794 COLUMN_ANNO_TITLE, title.c_str(),
795 COLUMN_ANNO_AUTHOR, author.c_str(),
796 -1);
797 }
798
799 gtk_tree_view_set_model (GTK_TREE_VIEW (w), model);
800 g_object_unref (G_OBJECT (model));
801
802 }
803
804
805
806 void
runModeless(XAP_Frame * pFrame)807 AP_UnixDialog_Goto::runModeless (XAP_Frame * pFrame)
808 {
809 UT_DEBUGMSG (("ROB: runModeless ()\n"));
810 _constructWindow (pFrame);
811 UT_ASSERT (m_wDialog);
812 _updateWindow ();
813 abiSetupModelessDialog (GTK_DIALOG (m_wDialog), pFrame, this, GTK_RESPONSE_CLOSE);
814 gtk_widget_show_all (m_wDialog);
815 gtk_window_present (GTK_WINDOW (m_wDialog));
816 }
817
818 void
notifyActiveFrame(XAP_Frame *)819 AP_UnixDialog_Goto::notifyActiveFrame (XAP_Frame * /*pFrame*/)
820 {
821 UT_DEBUGMSG (("ROB: notifyActiveFrame ()\n"));
822 UT_ASSERT (m_wDialog);
823
824 _updateWindow ();
825 /* default to page */
826 m_JumpTarget = AP_JUMPTARGET_PAGE;
827 }
828
829 void
activate(void)830 AP_UnixDialog_Goto::activate (void)
831 {
832 UT_ASSERT (m_wDialog);
833 UT_DEBUGMSG (("ROB: AP_UnixDialog_Goto::activate ()\n"));
834 _updateWindow ();
835 gtk_window_present (GTK_WINDOW (m_wDialog));
836 }
837
838 void
destroy()839 AP_UnixDialog_Goto::destroy ()
840 {
841 UT_DEBUGMSG (("ROB: AP_UnixDialog_Goto::destroy ()\n"));
842 modeless_cleanup ();
843 if (m_wDialog) {
844 gtk_widget_destroy (m_wDialog);
845 m_wDialog = NULL;
846 }
847 }
848
849 /**
850 * Try to select the bookmark before the current one.
851 * If none is selected the last in the list is picked.
852 * Wraps around.
853 */
854 void
_selectPrevBookmark()855 AP_UnixDialog_Goto::_selectPrevBookmark ()
856 {
857 UT_DEBUGMSG (("ROB: AP_UnixDialog_Goto::_selectPrevBookmark ()\n"));
858 selectPrev(GTK_TREE_VIEW (m_lvBookmarks));
859 }
860
861 /**
862 * Try to select the bookmark after the current one.
863 * If none is selected the first in the list is picked.
864 * Wraps around.
865 */
866 void
_selectNextBookmark()867 AP_UnixDialog_Goto::_selectNextBookmark ()
868 {
869 UT_DEBUGMSG (("ROB: AP_UnixDialog_Goto::_selectNextBookmark ()\n"));
870 selectNext(GTK_TREE_VIEW (m_lvBookmarks));
871 }
872
873
874 /*!
875 * Get the label of the currently selected bookmark in the list.
876 */
877 std::string
_getSelectedBookmarkLabel()878 AP_UnixDialog_Goto::_getSelectedBookmarkLabel ()
879 {
880 UT_DEBUGMSG (("ROB: AP_UnixDialog_Goto::_getSelectedBookmarkLabel ()\n"));
881 std::string ret = getSelectedText( GTK_TREE_VIEW (m_lvBookmarks), COLUMN_NAME );
882 return ret;
883 }
884
885 std::string
_getSelectedXMLIDLabel()886 AP_UnixDialog_Goto::_getSelectedXMLIDLabel()
887 {
888 UT_DEBUGMSG (("MIQ: AP_UnixDialog_Goto::_getSelectedXMLIDLabel ()\n"));
889 std::string ret = getSelectedText( GTK_TREE_VIEW (m_lvXMLIDs), COLUMN_NAME );
890 return ret;
891 }
892
893 std::string
_getSelectedAnnotationLabel()894 AP_UnixDialog_Goto::_getSelectedAnnotationLabel()
895 {
896 UT_DEBUGMSG (("MIQ: AP_UnixDialog_Goto::_getSelectedAnnotationLabel ()\n"));
897 std::string ret = tostr(getSelectedUInt( GTK_TREE_VIEW (m_lvAnno), COLUMN_ANNO_ID ));
898 return ret;
899 }
900
901