bug鏈接:https://bugzilla.gnome.org/show_bug.cgi?id=726228
只記得貢獻了第一次代碼後,在bugzilla中找來找去,不知怎麼就選上了這個任務。或許是表面上看着很簡單吧。至少現在看來我是大錯特錯了。
當時自己確定要修復這個bug時,就給David發了一封郵件,告知他我的意願。David在回信中談到了他自己對這個bug的認識,如下:
My suggestion would be to create a new GlEventView widget, which would be a stack which switches between the category list/event list view and the details view. It might be a bit complex to disentangle the code, especially the signal propagation during view mode changes, but the majority of the patch should be moving code from one file to another.
當然,對於我這麼一個newbie來說,這些解釋肯定是對我的幫助不太大的。通過之後和David的交流,我算是向前買了一小步。當然這一段時間,自己也算是摸不着北地摸索了很久,筆記本又增加了若干頁墨跡的重量。
之前程序中構件等級是這樣的:
window
->category list
->stack
->event list view
->detail view
目標是這樣:
window
->stack
->events view (GlEventView)
->category list
->event list view
->detail view
又是幾頁的墨跡,我來到了這一步:自己畫了一個簡圖,有了三步走計劃
三步走計劃:
The first: make event list view a GtkBox
The second: create a GtkBox named event_view to contain category list and event list view
The third: create a GtkStack named GlEventView which contains event_view and detail view
So,我目標很明確。照着這三步,一個個實現就一定ok了。當時是這麼想的,不過後來發現我錯了。
雖然目標明確,但我還是不知從哪裏下手,比如在哪裏改動UI等。就這麼在這幾天學習了一些關於signal、GValue、GAction等知識,雖然是一知半解,沒有完全明白。
再往後,弄明白了一共需要兩個GtkStack來處理頁面轉換。一個是GlEventView,另一個是GlEventViewList(當時這麼理解,其實GlEventViewList應該是GtkBox)。
當然這期間,自己一直在做的一件事情就是用g_print() 輸出一些輔助信息來幫助自己理解整個程序是怎麼運行的。比如說,打開程序和我點擊某一個event view list row後什麼函數會被調用和其間的順序。
再往後,就到了一個轉折點。
我終於明白了新建一個GlEventView是要新建一個類,需要新建.c、.h和一個.ui文件。一個月就這麼過去了,已經10月14日了。
在這裏記錄下這個郵件:
Hi David
I think I get the idea about fixing the bug. For such a long time, I was heading a wrong direction.
I should create a type named GlEventView which is a stack, and move the some parts of the existing stack GlEventViewList to GlEventView. Then I should do the things we discussed days ago, like making GlCategoryList and GlEventViewList in the same widget,
etc. Am I right? I think finally I get the right idea about it.
之後遇到的一個很棘手的問題是關於類的調用問題,比如說我想在gl-eventview.c中調用GlEventViewList這個類的指針。
在這裏詳細解釋下這個問題。
在C++中,如果在一個類A的實現中需要調用另一個類B的話,一般我們只要生成一個B類的對象或者指針就可以。但是在Gnome開發中就不可以這樣了。因爲一個類就對應着一個widget,重新生成是無法解決問題的。其實這裏涉及到一個知識,那就是在Gnome開發中,一個widget對應的類只能操作其的子類。而這個父子關係是通過.ui文件來實現的。
我提交的patch中gl-eventview.ui文件內容如下:
<interface domain="gnome-logs">
<template class="GlEventView" parent="GtkStack">
<property name="visible">True</property>
<child>
<object class="GlEventViewList" id="events">
<property name="visible">True</property>
</object>
</child>
</template>
</interface>
這個.ui 文件是描述GlEventView的佈局,<child>標籤就說明了GlEventViewList是GlEventView的子類。然後如果我想在gl-eventview.c中想要用到GlEventViewList的話,我還需要做些工作。那就是在GlEventViewPrivate中添加一個條目GtkWidget *events;。在gl_event_view_class_init中使用下面兩個語句來將GlEventViewList和events綁定:
gtk_widget_class_set_template_from_resource (widget_class,
"/org/gnome/Logs/gl-eventview.ui");
gtk_widget_class_bind_template_child_private (widget_class, GlEventView,
events);
在這裏有一點需要注意.ui文件中GlEventViewList的id要和GlEventViewPrivate中widget的名字一樣。如此一來,我們就將GlEventViewList和GtkWidget *events綁定。想要用到GlEventViewList的指針時,需要以下的代碼:
GlEventViewPrivate *priv;
GlEventViewList *events;
priv = gl_event_view_get_instance_private (view);
events = GL_EVENT_VIEW_LIST (priv->events);
這麼以來events就是GlEventViewList的指針了。
到此,進度還不到三分之一。
今天就先寫到這裏吧。