Merge lp:~indicator-applet-developers/indicator-messages/consolidate into lp:~indicator-applet-developers/indicator-messages/trunk.13.10
- consolidate
- Merge into trunk.13.10
Status: | Merged |
---|---|
Approved by: | Sebastien Bacher |
Approved revision: | 425 |
Merged at revision: | 356 |
Proposed branch: | lp:~indicator-applet-developers/indicator-messages/consolidate |
Merge into: | lp:~indicator-applet-developers/indicator-messages/trunk.13.10 |
Diff against target: |
10261 lines (+5533/-3772) 54 files modified
COPYING.GPLv3 (+674/-0) Makefile.am (+1/-0) autogen.sh (+11/-5) common/Makefile.am (+32/-0) common/com.canonical.indicator.messages.application.xml (+39/-0) configure.ac (+22/-27) data/Makefile.am (+4/-1) data/com.canonical.indicator.messages (+10/-0) debian/control (+7/-7) debian/indicator-messages.install (+1/-1) debian/libmessaging-menu-dev.install (+1/-0) debian/libmessaging-menu0.symbols (+15/-0) debian/source/format (+1/-0) doc/reference/Makefile.am (+1/-2) doc/reference/messaging-menu-docs.xml.in (+2/-1) libmessaging-menu/Makefile.am (+33/-22) libmessaging-menu/gtupleaction.c (+0/-354) libmessaging-menu/gtupleaction.h (+0/-40) libmessaging-menu/messaging-menu-app.c (+503/-270) libmessaging-menu/messaging-menu-app.h (+17/-2) libmessaging-menu/messaging-menu-message.c (+547/-0) libmessaging-menu/messaging-menu-message.h (+70/-0) libmessaging-menu/messaging-menu.h (+25/-0) po/POTFILES.in (+13/-1) po/indicator-messages.pot (+0/-46) src/Makefile.am (+13/-60) src/app-section.c (+279/-175) src/dbus-data.h (+16/-1) src/gactionmuxer.c (+8/-0) src/gactionmuxer.h (+3/-0) src/gmenuutils.c (+1/-1) src/ido-detail-label.c (+0/-401) src/ido-detail-label.h (+0/-59) src/ido-menu-item.c (+0/-439) src/ido-menu-item.h (+0/-54) src/im-app-menu-item.c (+0/-354) src/im-app-menu-item.h (+0/-54) src/im-application-list.c (+1237/-0) src/im-application-list.h (+62/-0) src/im-desktop-menu.c (+303/-0) src/im-desktop-menu.h (+35/-0) src/im-menu.c (+198/-0) src/im-menu.h (+64/-0) src/im-phone-menu.c (+318/-0) src/im-phone-menu.h (+68/-0) src/im-source-menu-item.c (+0/-407) src/im-source-menu-item.h (+0/-54) src/indicator-desktop-shortcuts.c (+680/-0) src/indicator-desktop-shortcuts.h (+80/-0) src/indicator-messages.c (+0/-382) src/messages-service.c (+98/-550) test/Makefile.am (+3/-2) test/indicator-messages-service-activate.c (+4/-0) test/test-gactionmuxer.cpp (+34/-0) |
To merge this branch: | bzr merge lp:~indicator-applet-developers/indicator-messages/consolidate |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Sebastien Bacher | Approve | ||
PS Jenkins bot (community) | continuous-integration | Approve | |
Review via email: mp+181006@code.launchpad.net |
Commit message
Re-merge the consolidate branch, but with additional bugfix
Description of the change
Re-merge the consolidate branch, but with additional bugfix
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:411
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 412. By Pete Woods
-
Merge trunk
Pete Woods (pete-woods) wrote : | # |
> Thanks Pete, there is a merge conflict in src/im-
> Would it also be possible to have the previous branch re-used? e.g show the
> fix as a different commit, would make things easier to review
Hi Sebastien, I thought I did reuse the existing branch? (lp:~indicator-applet-developers/indicator-messages/consolidate)
I've fixed the merge-conflict now, too.
Pete Woods (pete-woods) wrote : | # |
> > Thanks Pete, there is a merge conflict in src/im-
> though.
> > Would it also be possible to have the previous branch re-used? e.g show the
> > fix as a different commit, would make things easier to review
>
> Hi Sebastien, I thought I did reuse the existing branch? (lp:~indicator-
> applet-
>
i.e. commit 411, below. Perhaps I am misunderstanding here...
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:412
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Sebastien Bacher (seb128) wrote : | # |
> Hi Sebastien, I thought I did reuse the existing branch? (lp:~indicator-applet-developers/indicator-messages/consolidate)
Sorry, I got confused by launchpad, it listed only one commit (411) on the mp with a non trivial diff, I guess it's a side effect of the reverts...
The fix in r411 seems fine to me, I'm going to build that branch/run it for a bit and comment back
Pete Woods (pete-woods) wrote : | # |
> > Hi Sebastien, I thought I did reuse the existing branch? (lp:~indicator-
> applet-
>
> Sorry, I got confused by launchpad, it listed only one commit (411) on the mp
> with a non trivial diff, I guess it's a side effect of the reverts...
>
> The fix in r411 seems fine to me, I'm going to build that branch/run it for a
> bit and comment back
Yes, reverting the revert was fiddly! :)
Sebastien Bacher (seb128) wrote : | # |
Running the new version, it mostly works, some comments:
> g_menu_append (clear_section, "Clear", "indicator.
"Clear" should be set as translatable (e.g _("Clear"))
> item = g_menu_item_new ("Clear All", "remove-all");
same
* "Clear" should be disabled if the indicator is not blue
* the ordering of items is wrong, https:/
"a section for Ubuntu’s default chat client, if it is registered;
a section for Ubuntu’s default mail client, if it is registered;
a section for any other registered application, sorted alphabetically by the application Name. "
The old codebase lists:
- status
- empathy
- tb
- ...
The new one:
- GMail
- tb
- fb
- xchat-gnome
-...
- 413. By Pete Woods
-
"Clear" and "Clear All" now translatable
Pete Woods (pete-woods) wrote : | # |
Well, I've addressed the trivial translatable issue. I think I'll have to leave the rest for Ted.
I can't find a way to enable / disable a GMenu. I'm thinking it must be easy, but there's nothing describing it in the documentation.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:413
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Sebastien Bacher (seb128) wrote : | # |
> Well, I've addressed the trivial translatable issue.
Thanks
> I think I'll have to leave the rest for Ted.
That makes sense
Some other issues:
- the envelop doesn't turn blue when I receive new emails there (or not always, just got 3, the launcher picked them, the indicator menu has them, but the envelop
- you use g_desktop_
- if the glib requirement is bumped you can drop the "#if G_ENCODE_
- the tb entry in the menu is missing the "Compose new message" item it seems
Sebastien Bacher (seb128) wrote : | # |
oh, also xchat-gnome events seem to not be working anymore (e.g query messages don't get listed in the menu)
the service output those errors
"(process:13670): Indicator-
(the string is not exact, I translated the french one)
- 414. By Pete Woods
-
Compile again
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:414
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:417
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 418. By Ted Gould
-
Stealing the desktop shortcuts from libindicator
- 419. By Ted Gould
-
Remove unused struct member
- 420. By Ted Gould
-
Building up a shortcuts object to track the shortcuts from the desktop file
- 421. By Ted Gould
-
Switch to looking in the shortcuts object to set the actions
- 422. By Ted Gould
-
Putting shortcuts into the menu
- 423. By Ted Gould
-
Adding in a sigterm handler
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:423
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Ted Gould (ted) wrote : | # |
Okay, so the updates on the branch of things that were done 8/20 by Pete
and myself.
* The action names can now have ':'s in the name.
* "Clear" and "Clear All" were made translatable.
* The accessibility strings were also made translatable and adjust based
on the state of the icon.
* Setting of the alert icon was modified to handle source updates as
well as added and removed sources.
* Desktop file actions are now gotten from the libindicator parser, but
no libindicator (thus GTK) dep was added.
* The Clear menu item is no sensitive based on whether there are items
to clear
* The base action has been updated from (sssb) to the more modern a{sv}
I think that's all the issues that were listed in the comments.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:424
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:425
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Sebastien Bacher (seb128) wrote : | # |
Thanks, that looks better, still some issue:
- the order is still wrong, default im client and mailer should be first
- the libindicate parser copy seems a lot of undeed code, can we do without it?
- the spacing between the icons and status seems wrong, but I guess that's a bug somewhere else in the stack since e.g indicator-bluetooth seems to have the same issue
Sebastien Bacher (seb128) : | # |
Sebastien Bacher (seb128) wrote : | # |
let's get that in and resolve those point with following merge requests
Preview Diff
1 | === added file 'COPYING.GPLv3' |
2 | --- COPYING.GPLv3 1970-01-01 00:00:00 +0000 |
3 | +++ COPYING.GPLv3 2013-08-21 02:09:27 +0000 |
4 | @@ -0,0 +1,674 @@ |
5 | + GNU GENERAL PUBLIC LICENSE |
6 | + Version 3, 29 June 2007 |
7 | + |
8 | + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> |
9 | + Everyone is permitted to copy and distribute verbatim copies |
10 | + of this license document, but changing it is not allowed. |
11 | + |
12 | + Preamble |
13 | + |
14 | + The GNU General Public License is a free, copyleft license for |
15 | +software and other kinds of works. |
16 | + |
17 | + The licenses for most software and other practical works are designed |
18 | +to take away your freedom to share and change the works. By contrast, |
19 | +the GNU General Public License is intended to guarantee your freedom to |
20 | +share and change all versions of a program--to make sure it remains free |
21 | +software for all its users. We, the Free Software Foundation, use the |
22 | +GNU General Public License for most of our software; it applies also to |
23 | +any other work released this way by its authors. You can apply it to |
24 | +your programs, too. |
25 | + |
26 | + When we speak of free software, we are referring to freedom, not |
27 | +price. Our General Public Licenses are designed to make sure that you |
28 | +have the freedom to distribute copies of free software (and charge for |
29 | +them if you wish), that you receive source code or can get it if you |
30 | +want it, that you can change the software or use pieces of it in new |
31 | +free programs, and that you know you can do these things. |
32 | + |
33 | + To protect your rights, we need to prevent others from denying you |
34 | +these rights or asking you to surrender the rights. Therefore, you have |
35 | +certain responsibilities if you distribute copies of the software, or if |
36 | +you modify it: responsibilities to respect the freedom of others. |
37 | + |
38 | + For example, if you distribute copies of such a program, whether |
39 | +gratis or for a fee, you must pass on to the recipients the same |
40 | +freedoms that you received. You must make sure that they, too, receive |
41 | +or can get the source code. And you must show them these terms so they |
42 | +know their rights. |
43 | + |
44 | + Developers that use the GNU GPL protect your rights with two steps: |
45 | +(1) assert copyright on the software, and (2) offer you this License |
46 | +giving you legal permission to copy, distribute and/or modify it. |
47 | + |
48 | + For the developers' and authors' protection, the GPL clearly explains |
49 | +that there is no warranty for this free software. For both users' and |
50 | +authors' sake, the GPL requires that modified versions be marked as |
51 | +changed, so that their problems will not be attributed erroneously to |
52 | +authors of previous versions. |
53 | + |
54 | + Some devices are designed to deny users access to install or run |
55 | +modified versions of the software inside them, although the manufacturer |
56 | +can do so. This is fundamentally incompatible with the aim of |
57 | +protecting users' freedom to change the software. The systematic |
58 | +pattern of such abuse occurs in the area of products for individuals to |
59 | +use, which is precisely where it is most unacceptable. Therefore, we |
60 | +have designed this version of the GPL to prohibit the practice for those |
61 | +products. If such problems arise substantially in other domains, we |
62 | +stand ready to extend this provision to those domains in future versions |
63 | +of the GPL, as needed to protect the freedom of users. |
64 | + |
65 | + Finally, every program is threatened constantly by software patents. |
66 | +States should not allow patents to restrict development and use of |
67 | +software on general-purpose computers, but in those that do, we wish to |
68 | +avoid the special danger that patents applied to a free program could |
69 | +make it effectively proprietary. To prevent this, the GPL assures that |
70 | +patents cannot be used to render the program non-free. |
71 | + |
72 | + The precise terms and conditions for copying, distribution and |
73 | +modification follow. |
74 | + |
75 | + TERMS AND CONDITIONS |
76 | + |
77 | + 0. Definitions. |
78 | + |
79 | + "This License" refers to version 3 of the GNU General Public License. |
80 | + |
81 | + "Copyright" also means copyright-like laws that apply to other kinds of |
82 | +works, such as semiconductor masks. |
83 | + |
84 | + "The Program" refers to any copyrightable work licensed under this |
85 | +License. Each licensee is addressed as "you". "Licensees" and |
86 | +"recipients" may be individuals or organizations. |
87 | + |
88 | + To "modify" a work means to copy from or adapt all or part of the work |
89 | +in a fashion requiring copyright permission, other than the making of an |
90 | +exact copy. The resulting work is called a "modified version" of the |
91 | +earlier work or a work "based on" the earlier work. |
92 | + |
93 | + A "covered work" means either the unmodified Program or a work based |
94 | +on the Program. |
95 | + |
96 | + To "propagate" a work means to do anything with it that, without |
97 | +permission, would make you directly or secondarily liable for |
98 | +infringement under applicable copyright law, except executing it on a |
99 | +computer or modifying a private copy. Propagation includes copying, |
100 | +distribution (with or without modification), making available to the |
101 | +public, and in some countries other activities as well. |
102 | + |
103 | + To "convey" a work means any kind of propagation that enables other |
104 | +parties to make or receive copies. Mere interaction with a user through |
105 | +a computer network, with no transfer of a copy, is not conveying. |
106 | + |
107 | + An interactive user interface displays "Appropriate Legal Notices" |
108 | +to the extent that it includes a convenient and prominently visible |
109 | +feature that (1) displays an appropriate copyright notice, and (2) |
110 | +tells the user that there is no warranty for the work (except to the |
111 | +extent that warranties are provided), that licensees may convey the |
112 | +work under this License, and how to view a copy of this License. If |
113 | +the interface presents a list of user commands or options, such as a |
114 | +menu, a prominent item in the list meets this criterion. |
115 | + |
116 | + 1. Source Code. |
117 | + |
118 | + The "source code" for a work means the preferred form of the work |
119 | +for making modifications to it. "Object code" means any non-source |
120 | +form of a work. |
121 | + |
122 | + A "Standard Interface" means an interface that either is an official |
123 | +standard defined by a recognized standards body, or, in the case of |
124 | +interfaces specified for a particular programming language, one that |
125 | +is widely used among developers working in that language. |
126 | + |
127 | + The "System Libraries" of an executable work include anything, other |
128 | +than the work as a whole, that (a) is included in the normal form of |
129 | +packaging a Major Component, but which is not part of that Major |
130 | +Component, and (b) serves only to enable use of the work with that |
131 | +Major Component, or to implement a Standard Interface for which an |
132 | +implementation is available to the public in source code form. A |
133 | +"Major Component", in this context, means a major essential component |
134 | +(kernel, window system, and so on) of the specific operating system |
135 | +(if any) on which the executable work runs, or a compiler used to |
136 | +produce the work, or an object code interpreter used to run it. |
137 | + |
138 | + The "Corresponding Source" for a work in object code form means all |
139 | +the source code needed to generate, install, and (for an executable |
140 | +work) run the object code and to modify the work, including scripts to |
141 | +control those activities. However, it does not include the work's |
142 | +System Libraries, or general-purpose tools or generally available free |
143 | +programs which are used unmodified in performing those activities but |
144 | +which are not part of the work. For example, Corresponding Source |
145 | +includes interface definition files associated with source files for |
146 | +the work, and the source code for shared libraries and dynamically |
147 | +linked subprograms that the work is specifically designed to require, |
148 | +such as by intimate data communication or control flow between those |
149 | +subprograms and other parts of the work. |
150 | + |
151 | + The Corresponding Source need not include anything that users |
152 | +can regenerate automatically from other parts of the Corresponding |
153 | +Source. |
154 | + |
155 | + The Corresponding Source for a work in source code form is that |
156 | +same work. |
157 | + |
158 | + 2. Basic Permissions. |
159 | + |
160 | + All rights granted under this License are granted for the term of |
161 | +copyright on the Program, and are irrevocable provided the stated |
162 | +conditions are met. This License explicitly affirms your unlimited |
163 | +permission to run the unmodified Program. The output from running a |
164 | +covered work is covered by this License only if the output, given its |
165 | +content, constitutes a covered work. This License acknowledges your |
166 | +rights of fair use or other equivalent, as provided by copyright law. |
167 | + |
168 | + You may make, run and propagate covered works that you do not |
169 | +convey, without conditions so long as your license otherwise remains |
170 | +in force. You may convey covered works to others for the sole purpose |
171 | +of having them make modifications exclusively for you, or provide you |
172 | +with facilities for running those works, provided that you comply with |
173 | +the terms of this License in conveying all material for which you do |
174 | +not control copyright. Those thus making or running the covered works |
175 | +for you must do so exclusively on your behalf, under your direction |
176 | +and control, on terms that prohibit them from making any copies of |
177 | +your copyrighted material outside their relationship with you. |
178 | + |
179 | + Conveying under any other circumstances is permitted solely under |
180 | +the conditions stated below. Sublicensing is not allowed; section 10 |
181 | +makes it unnecessary. |
182 | + |
183 | + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. |
184 | + |
185 | + No covered work shall be deemed part of an effective technological |
186 | +measure under any applicable law fulfilling obligations under article |
187 | +11 of the WIPO copyright treaty adopted on 20 December 1996, or |
188 | +similar laws prohibiting or restricting circumvention of such |
189 | +measures. |
190 | + |
191 | + When you convey a covered work, you waive any legal power to forbid |
192 | +circumvention of technological measures to the extent such circumvention |
193 | +is effected by exercising rights under this License with respect to |
194 | +the covered work, and you disclaim any intention to limit operation or |
195 | +modification of the work as a means of enforcing, against the work's |
196 | +users, your or third parties' legal rights to forbid circumvention of |
197 | +technological measures. |
198 | + |
199 | + 4. Conveying Verbatim Copies. |
200 | + |
201 | + You may convey verbatim copies of the Program's source code as you |
202 | +receive it, in any medium, provided that you conspicuously and |
203 | +appropriately publish on each copy an appropriate copyright notice; |
204 | +keep intact all notices stating that this License and any |
205 | +non-permissive terms added in accord with section 7 apply to the code; |
206 | +keep intact all notices of the absence of any warranty; and give all |
207 | +recipients a copy of this License along with the Program. |
208 | + |
209 | + You may charge any price or no price for each copy that you convey, |
210 | +and you may offer support or warranty protection for a fee. |
211 | + |
212 | + 5. Conveying Modified Source Versions. |
213 | + |
214 | + You may convey a work based on the Program, or the modifications to |
215 | +produce it from the Program, in the form of source code under the |
216 | +terms of section 4, provided that you also meet all of these conditions: |
217 | + |
218 | + a) The work must carry prominent notices stating that you modified |
219 | + it, and giving a relevant date. |
220 | + |
221 | + b) The work must carry prominent notices stating that it is |
222 | + released under this License and any conditions added under section |
223 | + 7. This requirement modifies the requirement in section 4 to |
224 | + "keep intact all notices". |
225 | + |
226 | + c) You must license the entire work, as a whole, under this |
227 | + License to anyone who comes into possession of a copy. This |
228 | + License will therefore apply, along with any applicable section 7 |
229 | + additional terms, to the whole of the work, and all its parts, |
230 | + regardless of how they are packaged. This License gives no |
231 | + permission to license the work in any other way, but it does not |
232 | + invalidate such permission if you have separately received it. |
233 | + |
234 | + d) If the work has interactive user interfaces, each must display |
235 | + Appropriate Legal Notices; however, if the Program has interactive |
236 | + interfaces that do not display Appropriate Legal Notices, your |
237 | + work need not make them do so. |
238 | + |
239 | + A compilation of a covered work with other separate and independent |
240 | +works, which are not by their nature extensions of the covered work, |
241 | +and which are not combined with it such as to form a larger program, |
242 | +in or on a volume of a storage or distribution medium, is called an |
243 | +"aggregate" if the compilation and its resulting copyright are not |
244 | +used to limit the access or legal rights of the compilation's users |
245 | +beyond what the individual works permit. Inclusion of a covered work |
246 | +in an aggregate does not cause this License to apply to the other |
247 | +parts of the aggregate. |
248 | + |
249 | + 6. Conveying Non-Source Forms. |
250 | + |
251 | + You may convey a covered work in object code form under the terms |
252 | +of sections 4 and 5, provided that you also convey the |
253 | +machine-readable Corresponding Source under the terms of this License, |
254 | +in one of these ways: |
255 | + |
256 | + a) Convey the object code in, or embodied in, a physical product |
257 | + (including a physical distribution medium), accompanied by the |
258 | + Corresponding Source fixed on a durable physical medium |
259 | + customarily used for software interchange. |
260 | + |
261 | + b) Convey the object code in, or embodied in, a physical product |
262 | + (including a physical distribution medium), accompanied by a |
263 | + written offer, valid for at least three years and valid for as |
264 | + long as you offer spare parts or customer support for that product |
265 | + model, to give anyone who possesses the object code either (1) a |
266 | + copy of the Corresponding Source for all the software in the |
267 | + product that is covered by this License, on a durable physical |
268 | + medium customarily used for software interchange, for a price no |
269 | + more than your reasonable cost of physically performing this |
270 | + conveying of source, or (2) access to copy the |
271 | + Corresponding Source from a network server at no charge. |
272 | + |
273 | + c) Convey individual copies of the object code with a copy of the |
274 | + written offer to provide the Corresponding Source. This |
275 | + alternative is allowed only occasionally and noncommercially, and |
276 | + only if you received the object code with such an offer, in accord |
277 | + with subsection 6b. |
278 | + |
279 | + d) Convey the object code by offering access from a designated |
280 | + place (gratis or for a charge), and offer equivalent access to the |
281 | + Corresponding Source in the same way through the same place at no |
282 | + further charge. You need not require recipients to copy the |
283 | + Corresponding Source along with the object code. If the place to |
284 | + copy the object code is a network server, the Corresponding Source |
285 | + may be on a different server (operated by you or a third party) |
286 | + that supports equivalent copying facilities, provided you maintain |
287 | + clear directions next to the object code saying where to find the |
288 | + Corresponding Source. Regardless of what server hosts the |
289 | + Corresponding Source, you remain obligated to ensure that it is |
290 | + available for as long as needed to satisfy these requirements. |
291 | + |
292 | + e) Convey the object code using peer-to-peer transmission, provided |
293 | + you inform other peers where the object code and Corresponding |
294 | + Source of the work are being offered to the general public at no |
295 | + charge under subsection 6d. |
296 | + |
297 | + A separable portion of the object code, whose source code is excluded |
298 | +from the Corresponding Source as a System Library, need not be |
299 | +included in conveying the object code work. |
300 | + |
301 | + A "User Product" is either (1) a "consumer product", which means any |
302 | +tangible personal property which is normally used for personal, family, |
303 | +or household purposes, or (2) anything designed or sold for incorporation |
304 | +into a dwelling. In determining whether a product is a consumer product, |
305 | +doubtful cases shall be resolved in favor of coverage. For a particular |
306 | +product received by a particular user, "normally used" refers to a |
307 | +typical or common use of that class of product, regardless of the status |
308 | +of the particular user or of the way in which the particular user |
309 | +actually uses, or expects or is expected to use, the product. A product |
310 | +is a consumer product regardless of whether the product has substantial |
311 | +commercial, industrial or non-consumer uses, unless such uses represent |
312 | +the only significant mode of use of the product. |
313 | + |
314 | + "Installation Information" for a User Product means any methods, |
315 | +procedures, authorization keys, or other information required to install |
316 | +and execute modified versions of a covered work in that User Product from |
317 | +a modified version of its Corresponding Source. The information must |
318 | +suffice to ensure that the continued functioning of the modified object |
319 | +code is in no case prevented or interfered with solely because |
320 | +modification has been made. |
321 | + |
322 | + If you convey an object code work under this section in, or with, or |
323 | +specifically for use in, a User Product, and the conveying occurs as |
324 | +part of a transaction in which the right of possession and use of the |
325 | +User Product is transferred to the recipient in perpetuity or for a |
326 | +fixed term (regardless of how the transaction is characterized), the |
327 | +Corresponding Source conveyed under this section must be accompanied |
328 | +by the Installation Information. But this requirement does not apply |
329 | +if neither you nor any third party retains the ability to install |
330 | +modified object code on the User Product (for example, the work has |
331 | +been installed in ROM). |
332 | + |
333 | + The requirement to provide Installation Information does not include a |
334 | +requirement to continue to provide support service, warranty, or updates |
335 | +for a work that has been modified or installed by the recipient, or for |
336 | +the User Product in which it has been modified or installed. Access to a |
337 | +network may be denied when the modification itself materially and |
338 | +adversely affects the operation of the network or violates the rules and |
339 | +protocols for communication across the network. |
340 | + |
341 | + Corresponding Source conveyed, and Installation Information provided, |
342 | +in accord with this section must be in a format that is publicly |
343 | +documented (and with an implementation available to the public in |
344 | +source code form), and must require no special password or key for |
345 | +unpacking, reading or copying. |
346 | + |
347 | + 7. Additional Terms. |
348 | + |
349 | + "Additional permissions" are terms that supplement the terms of this |
350 | +License by making exceptions from one or more of its conditions. |
351 | +Additional permissions that are applicable to the entire Program shall |
352 | +be treated as though they were included in this License, to the extent |
353 | +that they are valid under applicable law. If additional permissions |
354 | +apply only to part of the Program, that part may be used separately |
355 | +under those permissions, but the entire Program remains governed by |
356 | +this License without regard to the additional permissions. |
357 | + |
358 | + When you convey a copy of a covered work, you may at your option |
359 | +remove any additional permissions from that copy, or from any part of |
360 | +it. (Additional permissions may be written to require their own |
361 | +removal in certain cases when you modify the work.) You may place |
362 | +additional permissions on material, added by you to a covered work, |
363 | +for which you have or can give appropriate copyright permission. |
364 | + |
365 | + Notwithstanding any other provision of this License, for material you |
366 | +add to a covered work, you may (if authorized by the copyright holders of |
367 | +that material) supplement the terms of this License with terms: |
368 | + |
369 | + a) Disclaiming warranty or limiting liability differently from the |
370 | + terms of sections 15 and 16 of this License; or |
371 | + |
372 | + b) Requiring preservation of specified reasonable legal notices or |
373 | + author attributions in that material or in the Appropriate Legal |
374 | + Notices displayed by works containing it; or |
375 | + |
376 | + c) Prohibiting misrepresentation of the origin of that material, or |
377 | + requiring that modified versions of such material be marked in |
378 | + reasonable ways as different from the original version; or |
379 | + |
380 | + d) Limiting the use for publicity purposes of names of licensors or |
381 | + authors of the material; or |
382 | + |
383 | + e) Declining to grant rights under trademark law for use of some |
384 | + trade names, trademarks, or service marks; or |
385 | + |
386 | + f) Requiring indemnification of licensors and authors of that |
387 | + material by anyone who conveys the material (or modified versions of |
388 | + it) with contractual assumptions of liability to the recipient, for |
389 | + any liability that these contractual assumptions directly impose on |
390 | + those licensors and authors. |
391 | + |
392 | + All other non-permissive additional terms are considered "further |
393 | +restrictions" within the meaning of section 10. If the Program as you |
394 | +received it, or any part of it, contains a notice stating that it is |
395 | +governed by this License along with a term that is a further |
396 | +restriction, you may remove that term. If a license document contains |
397 | +a further restriction but permits relicensing or conveying under this |
398 | +License, you may add to a covered work material governed by the terms |
399 | +of that license document, provided that the further restriction does |
400 | +not survive such relicensing or conveying. |
401 | + |
402 | + If you add terms to a covered work in accord with this section, you |
403 | +must place, in the relevant source files, a statement of the |
404 | +additional terms that apply to those files, or a notice indicating |
405 | +where to find the applicable terms. |
406 | + |
407 | + Additional terms, permissive or non-permissive, may be stated in the |
408 | +form of a separately written license, or stated as exceptions; |
409 | +the above requirements apply either way. |
410 | + |
411 | + 8. Termination. |
412 | + |
413 | + You may not propagate or modify a covered work except as expressly |
414 | +provided under this License. Any attempt otherwise to propagate or |
415 | +modify it is void, and will automatically terminate your rights under |
416 | +this License (including any patent licenses granted under the third |
417 | +paragraph of section 11). |
418 | + |
419 | + However, if you cease all violation of this License, then your |
420 | +license from a particular copyright holder is reinstated (a) |
421 | +provisionally, unless and until the copyright holder explicitly and |
422 | +finally terminates your license, and (b) permanently, if the copyright |
423 | +holder fails to notify you of the violation by some reasonable means |
424 | +prior to 60 days after the cessation. |
425 | + |
426 | + Moreover, your license from a particular copyright holder is |
427 | +reinstated permanently if the copyright holder notifies you of the |
428 | +violation by some reasonable means, this is the first time you have |
429 | +received notice of violation of this License (for any work) from that |
430 | +copyright holder, and you cure the violation prior to 30 days after |
431 | +your receipt of the notice. |
432 | + |
433 | + Termination of your rights under this section does not terminate the |
434 | +licenses of parties who have received copies or rights from you under |
435 | +this License. If your rights have been terminated and not permanently |
436 | +reinstated, you do not qualify to receive new licenses for the same |
437 | +material under section 10. |
438 | + |
439 | + 9. Acceptance Not Required for Having Copies. |
440 | + |
441 | + You are not required to accept this License in order to receive or |
442 | +run a copy of the Program. Ancillary propagation of a covered work |
443 | +occurring solely as a consequence of using peer-to-peer transmission |
444 | +to receive a copy likewise does not require acceptance. However, |
445 | +nothing other than this License grants you permission to propagate or |
446 | +modify any covered work. These actions infringe copyright if you do |
447 | +not accept this License. Therefore, by modifying or propagating a |
448 | +covered work, you indicate your acceptance of this License to do so. |
449 | + |
450 | + 10. Automatic Licensing of Downstream Recipients. |
451 | + |
452 | + Each time you convey a covered work, the recipient automatically |
453 | +receives a license from the original licensors, to run, modify and |
454 | +propagate that work, subject to this License. You are not responsible |
455 | +for enforcing compliance by third parties with this License. |
456 | + |
457 | + An "entity transaction" is a transaction transferring control of an |
458 | +organization, or substantially all assets of one, or subdividing an |
459 | +organization, or merging organizations. If propagation of a covered |
460 | +work results from an entity transaction, each party to that |
461 | +transaction who receives a copy of the work also receives whatever |
462 | +licenses to the work the party's predecessor in interest had or could |
463 | +give under the previous paragraph, plus a right to possession of the |
464 | +Corresponding Source of the work from the predecessor in interest, if |
465 | +the predecessor has it or can get it with reasonable efforts. |
466 | + |
467 | + You may not impose any further restrictions on the exercise of the |
468 | +rights granted or affirmed under this License. For example, you may |
469 | +not impose a license fee, royalty, or other charge for exercise of |
470 | +rights granted under this License, and you may not initiate litigation |
471 | +(including a cross-claim or counterclaim in a lawsuit) alleging that |
472 | +any patent claim is infringed by making, using, selling, offering for |
473 | +sale, or importing the Program or any portion of it. |
474 | + |
475 | + 11. Patents. |
476 | + |
477 | + A "contributor" is a copyright holder who authorizes use under this |
478 | +License of the Program or a work on which the Program is based. The |
479 | +work thus licensed is called the contributor's "contributor version". |
480 | + |
481 | + A contributor's "essential patent claims" are all patent claims |
482 | +owned or controlled by the contributor, whether already acquired or |
483 | +hereafter acquired, that would be infringed by some manner, permitted |
484 | +by this License, of making, using, or selling its contributor version, |
485 | +but do not include claims that would be infringed only as a |
486 | +consequence of further modification of the contributor version. For |
487 | +purposes of this definition, "control" includes the right to grant |
488 | +patent sublicenses in a manner consistent with the requirements of |
489 | +this License. |
490 | + |
491 | + Each contributor grants you a non-exclusive, worldwide, royalty-free |
492 | +patent license under the contributor's essential patent claims, to |
493 | +make, use, sell, offer for sale, import and otherwise run, modify and |
494 | +propagate the contents of its contributor version. |
495 | + |
496 | + In the following three paragraphs, a "patent license" is any express |
497 | +agreement or commitment, however denominated, not to enforce a patent |
498 | +(such as an express permission to practice a patent or covenant not to |
499 | +sue for patent infringement). To "grant" such a patent license to a |
500 | +party means to make such an agreement or commitment not to enforce a |
501 | +patent against the party. |
502 | + |
503 | + If you convey a covered work, knowingly relying on a patent license, |
504 | +and the Corresponding Source of the work is not available for anyone |
505 | +to copy, free of charge and under the terms of this License, through a |
506 | +publicly available network server or other readily accessible means, |
507 | +then you must either (1) cause the Corresponding Source to be so |
508 | +available, or (2) arrange to deprive yourself of the benefit of the |
509 | +patent license for this particular work, or (3) arrange, in a manner |
510 | +consistent with the requirements of this License, to extend the patent |
511 | +license to downstream recipients. "Knowingly relying" means you have |
512 | +actual knowledge that, but for the patent license, your conveying the |
513 | +covered work in a country, or your recipient's use of the covered work |
514 | +in a country, would infringe one or more identifiable patents in that |
515 | +country that you have reason to believe are valid. |
516 | + |
517 | + If, pursuant to or in connection with a single transaction or |
518 | +arrangement, you convey, or propagate by procuring conveyance of, a |
519 | +covered work, and grant a patent license to some of the parties |
520 | +receiving the covered work authorizing them to use, propagate, modify |
521 | +or convey a specific copy of the covered work, then the patent license |
522 | +you grant is automatically extended to all recipients of the covered |
523 | +work and works based on it. |
524 | + |
525 | + A patent license is "discriminatory" if it does not include within |
526 | +the scope of its coverage, prohibits the exercise of, or is |
527 | +conditioned on the non-exercise of one or more of the rights that are |
528 | +specifically granted under this License. You may not convey a covered |
529 | +work if you are a party to an arrangement with a third party that is |
530 | +in the business of distributing software, under which you make payment |
531 | +to the third party based on the extent of your activity of conveying |
532 | +the work, and under which the third party grants, to any of the |
533 | +parties who would receive the covered work from you, a discriminatory |
534 | +patent license (a) in connection with copies of the covered work |
535 | +conveyed by you (or copies made from those copies), or (b) primarily |
536 | +for and in connection with specific products or compilations that |
537 | +contain the covered work, unless you entered into that arrangement, |
538 | +or that patent license was granted, prior to 28 March 2007. |
539 | + |
540 | + Nothing in this License shall be construed as excluding or limiting |
541 | +any implied license or other defenses to infringement that may |
542 | +otherwise be available to you under applicable patent law. |
543 | + |
544 | + 12. No Surrender of Others' Freedom. |
545 | + |
546 | + If conditions are imposed on you (whether by court order, agreement or |
547 | +otherwise) that contradict the conditions of this License, they do not |
548 | +excuse you from the conditions of this License. If you cannot convey a |
549 | +covered work so as to satisfy simultaneously your obligations under this |
550 | +License and any other pertinent obligations, then as a consequence you may |
551 | +not convey it at all. For example, if you agree to terms that obligate you |
552 | +to collect a royalty for further conveying from those to whom you convey |
553 | +the Program, the only way you could satisfy both those terms and this |
554 | +License would be to refrain entirely from conveying the Program. |
555 | + |
556 | + 13. Use with the GNU Affero General Public License. |
557 | + |
558 | + Notwithstanding any other provision of this License, you have |
559 | +permission to link or combine any covered work with a work licensed |
560 | +under version 3 of the GNU Affero General Public License into a single |
561 | +combined work, and to convey the resulting work. The terms of this |
562 | +License will continue to apply to the part which is the covered work, |
563 | +but the special requirements of the GNU Affero General Public License, |
564 | +section 13, concerning interaction through a network will apply to the |
565 | +combination as such. |
566 | + |
567 | + 14. Revised Versions of this License. |
568 | + |
569 | + The Free Software Foundation may publish revised and/or new versions of |
570 | +the GNU General Public License from time to time. Such new versions will |
571 | +be similar in spirit to the present version, but may differ in detail to |
572 | +address new problems or concerns. |
573 | + |
574 | + Each version is given a distinguishing version number. If the |
575 | +Program specifies that a certain numbered version of the GNU General |
576 | +Public License "or any later version" applies to it, you have the |
577 | +option of following the terms and conditions either of that numbered |
578 | +version or of any later version published by the Free Software |
579 | +Foundation. If the Program does not specify a version number of the |
580 | +GNU General Public License, you may choose any version ever published |
581 | +by the Free Software Foundation. |
582 | + |
583 | + If the Program specifies that a proxy can decide which future |
584 | +versions of the GNU General Public License can be used, that proxy's |
585 | +public statement of acceptance of a version permanently authorizes you |
586 | +to choose that version for the Program. |
587 | + |
588 | + Later license versions may give you additional or different |
589 | +permissions. However, no additional obligations are imposed on any |
590 | +author or copyright holder as a result of your choosing to follow a |
591 | +later version. |
592 | + |
593 | + 15. Disclaimer of Warranty. |
594 | + |
595 | + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY |
596 | +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT |
597 | +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY |
598 | +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, |
599 | +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
600 | +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM |
601 | +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF |
602 | +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. |
603 | + |
604 | + 16. Limitation of Liability. |
605 | + |
606 | + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING |
607 | +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS |
608 | +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY |
609 | +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE |
610 | +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF |
611 | +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD |
612 | +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), |
613 | +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF |
614 | +SUCH DAMAGES. |
615 | + |
616 | + 17. Interpretation of Sections 15 and 16. |
617 | + |
618 | + If the disclaimer of warranty and limitation of liability provided |
619 | +above cannot be given local legal effect according to their terms, |
620 | +reviewing courts shall apply local law that most closely approximates |
621 | +an absolute waiver of all civil liability in connection with the |
622 | +Program, unless a warranty or assumption of liability accompanies a |
623 | +copy of the Program in return for a fee. |
624 | + |
625 | + END OF TERMS AND CONDITIONS |
626 | + |
627 | + How to Apply These Terms to Your New Programs |
628 | + |
629 | + If you develop a new program, and you want it to be of the greatest |
630 | +possible use to the public, the best way to achieve this is to make it |
631 | +free software which everyone can redistribute and change under these terms. |
632 | + |
633 | + To do so, attach the following notices to the program. It is safest |
634 | +to attach them to the start of each source file to most effectively |
635 | +state the exclusion of warranty; and each file should have at least |
636 | +the "copyright" line and a pointer to where the full notice is found. |
637 | + |
638 | + <one line to give the program's name and a brief idea of what it does.> |
639 | + Copyright (C) <year> <name of author> |
640 | + |
641 | + This program is free software: you can redistribute it and/or modify |
642 | + it under the terms of the GNU General Public License as published by |
643 | + the Free Software Foundation, either version 3 of the License, or |
644 | + (at your option) any later version. |
645 | + |
646 | + This program is distributed in the hope that it will be useful, |
647 | + but WITHOUT ANY WARRANTY; without even the implied warranty of |
648 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
649 | + GNU General Public License for more details. |
650 | + |
651 | + You should have received a copy of the GNU General Public License |
652 | + along with this program. If not, see <http://www.gnu.org/licenses/>. |
653 | + |
654 | +Also add information on how to contact you by electronic and paper mail. |
655 | + |
656 | + If the program does terminal interaction, make it output a short |
657 | +notice like this when it starts in an interactive mode: |
658 | + |
659 | + <program> Copyright (C) <year> <name of author> |
660 | + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. |
661 | + This is free software, and you are welcome to redistribute it |
662 | + under certain conditions; type `show c' for details. |
663 | + |
664 | +The hypothetical commands `show w' and `show c' should show the appropriate |
665 | +parts of the General Public License. Of course, your program's commands |
666 | +might be different; for a GUI interface, you would use an "about box". |
667 | + |
668 | + You should also get your employer (if you work as a programmer) or school, |
669 | +if any, to sign a "copyright disclaimer" for the program, if necessary. |
670 | +For more information on this, and how to apply and follow the GNU GPL, see |
671 | +<http://www.gnu.org/licenses/>. |
672 | + |
673 | + The GNU General Public License does not permit incorporating your program |
674 | +into proprietary programs. If your program is a subroutine library, you |
675 | +may consider it more useful to permit linking proprietary applications with |
676 | +the library. If this is what you want to do, use the GNU Lesser General |
677 | +Public License instead of this License. But first, please read |
678 | +<http://www.gnu.org/philosophy/why-not-lgpl.html>. |
679 | |
680 | === modified file 'Makefile.am' |
681 | --- Makefile.am 2013-08-20 08:53:01 +0000 |
682 | +++ Makefile.am 2013-08-21 02:09:27 +0000 |
683 | @@ -1,5 +1,6 @@ |
684 | |
685 | SUBDIRS = \ |
686 | + common \ |
687 | src \ |
688 | libmessaging-menu \ |
689 | data \ |
690 | |
691 | === modified file 'autogen.sh' |
692 | --- autogen.sh 2013-08-20 08:53:01 +0000 |
693 | +++ autogen.sh 2013-08-21 02:09:27 +0000 |
694 | @@ -1,5 +1,11 @@ |
695 | -#!/bin/sh -e |
696 | - |
697 | -gtkdocize |
698 | -autoreconf -i -f |
699 | -intltoolize |
700 | +#!/bin/sh |
701 | + |
702 | +PKG_NAME="indicator-messages" |
703 | + |
704 | +which gnome-autogen.sh || { |
705 | + echo "You need gnome-common from GNOME SVN" |
706 | + exit 1 |
707 | +} |
708 | + |
709 | +USE_GNOME2_MACROS=1 \ |
710 | +. gnome-autogen.sh |
711 | |
712 | === added directory 'common' |
713 | === added file 'common/Makefile.am' |
714 | --- common/Makefile.am 1970-01-01 00:00:00 +0000 |
715 | +++ common/Makefile.am 2013-08-21 02:09:27 +0000 |
716 | @@ -0,0 +1,32 @@ |
717 | + |
718 | +noinst_LTLIBRARIES = libmessaging-common.la |
719 | + |
720 | +indicator-messages-service.c: com.canonical.indicator.messages.service.xml |
721 | + $(AM_V_GEN) gdbus-codegen \ |
722 | + --interface-prefix com.canonical.indicator.messages. \ |
723 | + --generate-c-code indicator-messages-service \ |
724 | + --c-namespace IndicatorMessages \ |
725 | + $^ |
726 | +indicator-messages-service.h: indicator-messages-service.c |
727 | + |
728 | +indicator-messages-application.c: com.canonical.indicator.messages.application.xml |
729 | + $(AM_V_GEN) gdbus-codegen \ |
730 | + --interface-prefix com.canonical.indicator.messages. \ |
731 | + --generate-c-code indicator-messages-application \ |
732 | + --c-namespace IndicatorMessages \ |
733 | + $^ |
734 | +indicator-messages-application.h: indicator-messages-application.c |
735 | + |
736 | +BUILT_SOURCES = \ |
737 | + indicator-messages-service.c \ |
738 | + indicator-messages-service.h \ |
739 | + indicator-messages-application.c \ |
740 | + indicator-messages-application.h |
741 | + |
742 | +libmessaging_common_la_SOURCES = \ |
743 | + $(BUILT_SOURCES) |
744 | + |
745 | +libmessaging_common_la_CFLAGS = $(GIO_CFLAGS) |
746 | +libmessaging_common_la_LIBADD = $(GIO_LIBS) |
747 | + |
748 | +CLEANFILES = $(BUILT_SOURCES) |
749 | |
750 | === added file 'common/com.canonical.indicator.messages.application.xml' |
751 | --- common/com.canonical.indicator.messages.application.xml 1970-01-01 00:00:00 +0000 |
752 | +++ common/com.canonical.indicator.messages.application.xml 2013-08-21 02:09:27 +0000 |
753 | @@ -0,0 +1,39 @@ |
754 | +<?xml version="1.0" encoding="UTF-8"?> |
755 | +<node name="/"> |
756 | + <interface name="com.canonical.indicator.messages.application"> |
757 | + <method name="ListSources"> |
758 | + <arg type="a(sssuxsb)" name="sources" direction="out" /> |
759 | + </method> |
760 | + <method name="ListMessages"> |
761 | + <arg type="a(sssssxaa{sv}b)" name="message" direction="out" /> |
762 | + </method> |
763 | + <method name="ActivateSource"> |
764 | + <arg type="s" name="source_id" direction="in" /> |
765 | + </method> |
766 | + <method name="ActivateMessage"> |
767 | + <arg type="s" name="message_id" direction="in" /> |
768 | + <arg type="s" name="action_id" direction="in" /> |
769 | + <arg type="av" name="parameter" direction="in" /> |
770 | + </method> |
771 | + <method name="Dismiss"> |
772 | + <arg type="as" name="sources" direction="in" /> |
773 | + <arg type="as" name="messages" direction="in" /> |
774 | + </method> |
775 | + <signal name="SourceAdded"> |
776 | + <arg type="u" name="position" direction="in" /> |
777 | + <arg type="(sssuxsb)" name="source" direction="in" /> |
778 | + </signal> |
779 | + <signal name="SourceChanged"> |
780 | + <arg type="(sssuxsb)" name="source" direction="in" /> |
781 | + </signal> |
782 | + <signal name="SourceRemoved"> |
783 | + <arg type="s" name="source_id" direction="in" /> |
784 | + </signal> |
785 | + <signal name="MessageAdded"> |
786 | + <arg type="(sssssxaa{sv}b)" name="message" direction="in" /> |
787 | + </signal> |
788 | + <signal name="MessageRemoved"> |
789 | + <arg type="s" name="message_id" direction="in" /> |
790 | + </signal> |
791 | + </interface> |
792 | +</node> |
793 | |
794 | === renamed file 'src/messages-service.xml' => 'common/com.canonical.indicator.messages.service.xml' |
795 | === modified file 'configure.ac' |
796 | --- configure.ac 2013-08-20 08:53:01 +0000 |
797 | +++ configure.ac 2013-08-21 02:09:27 +0000 |
798 | @@ -61,6 +61,12 @@ |
799 | |
800 | GOBJECT_INTROSPECTION_CHECK([$INTROSPECTION_REQUIRED_VERSION]) |
801 | |
802 | +AC_ARG_WITH([indicator-dir], |
803 | + [AS_HELP_STRING([--with-indicator-dir=DIR], [Indicator directory [default=$datadir/unity/indicators]])], |
804 | + [], |
805 | + [with_indicator_dir=$datadir/unity/indicators]) |
806 | +AC_SUBST([INDICATOR_DIR], [$with_indicator_dir]) |
807 | + |
808 | ########################### |
809 | # gcov coverage reporting |
810 | ########################### |
811 | @@ -100,33 +106,20 @@ |
812 | AM_CONDITIONAL([BUILD_TESTS],[test "x$enable_tests" = "xyes"]) |
813 | |
814 | ########################### |
815 | -# Check to see if we're local |
816 | -########################### |
817 | - |
818 | -with_localinstall="no" |
819 | -AC_ARG_ENABLE(localinstall, AS_HELP_STRING([--enable-localinstall], [install all of the files localy instead of system directories (for distcheck)]), with_localinstall=$enableval, with_localinstall=no) |
820 | - |
821 | -########################### |
822 | -# Indicator Info |
823 | -########################### |
824 | - |
825 | -if test "x$with_localinstall" = "xyes"; then |
826 | - INDICATORDIR="${libdir}/indicators/2/" |
827 | -else |
828 | - INDICATORDIR=`$PKG_CONFIG --variable=indicatordir indicator3-0.4` |
829 | -fi |
830 | -AC_SUBST(INDICATORDIR) |
831 | - |
832 | -########################### |
833 | -# DBus Service Info |
834 | -########################### |
835 | - |
836 | -if test "x$with_localinstall" = "xyes"; then |
837 | - DBUSSERVICEDIR="${datadir}/dbus-1/services/" |
838 | -else |
839 | - DBUSSERVICEDIR=`$PKG_CONFIG --variable=session_bus_services_dir dbus-1` |
840 | -fi |
841 | -AC_SUBST(DBUSSERVICEDIR) |
842 | +# Vala API Generation |
843 | +########################### |
844 | + |
845 | +AC_ARG_ENABLE([vala], |
846 | + AC_HELP_STRING([--disable-vala], [Disable vala]), |
847 | + [enable_vala=$enableval], [enable_vala=yes]) |
848 | + |
849 | +AS_IF([test "x$enable_vala" != "xno"],[ |
850 | + AM_COND_IF([HAVE_INTROSPECTION],,[ |
851 | + AC_MSG_ERROR([Vala bindings require introspection support, please --enable-introspection]) |
852 | + ]) |
853 | +AC_PATH_PROG([VALA_API_GEN], [vapigen]) |
854 | +]) |
855 | +AM_CONDITIONAL([HAVE_VALA], [test -n "$VALA_API_GEN"]) |
856 | |
857 | ############################## |
858 | # Custom Junk |
859 | @@ -162,6 +155,7 @@ |
860 | AC_OUTPUT([ |
861 | Makefile |
862 | src/Makefile |
863 | +common/Makefile |
864 | data/Makefile |
865 | data/icons/Makefile |
866 | data/icons/16x16/Makefile |
867 | @@ -202,5 +196,6 @@ |
868 | tests: $enable_tests |
869 | gcov: $use_gcov |
870 | introspecion: $enable_introspection |
871 | + Vala bindings: $enable_vala |
872 | documentation: $enable_gtk_doc |
873 | ]) |
874 | |
875 | === modified file 'data/Makefile.am' |
876 | --- data/Makefile.am 2013-08-20 08:53:01 +0000 |
877 | +++ data/Makefile.am 2013-08-21 02:09:27 +0000 |
878 | @@ -1,6 +1,6 @@ |
879 | SUBDIRS = icons |
880 | |
881 | -dbus_servicesdir = $(DBUSSERVICEDIR) |
882 | +dbus_servicesdir = $(datadir)/dbus-1/services |
883 | dbus_services_DATA = indicator-messages.service |
884 | |
885 | %.service: %.service.in |
886 | @@ -9,6 +9,9 @@ |
887 | gsettings_SCHEMAS = com.canonical.indicator.messages.gschema.xml |
888 | @GSETTINGS_RULES@ |
889 | |
890 | +indicatordir = $(INDICATOR_DIR) |
891 | +dist_indicator_DATA = com.canonical.indicator.messages |
892 | + |
893 | EXTRA_DIST = \ |
894 | $(gsettings_SCHEMAS) \ |
895 | indicator-messages.service.in |
896 | |
897 | === added file 'data/com.canonical.indicator.messages' |
898 | --- data/com.canonical.indicator.messages 1970-01-01 00:00:00 +0000 |
899 | +++ data/com.canonical.indicator.messages 2013-08-21 02:09:27 +0000 |
900 | @@ -0,0 +1,10 @@ |
901 | +[Indicator Service] |
902 | +Name=indicator-messages |
903 | +ObjectPath=/com/canonical/indicator/messages |
904 | +Position=50 |
905 | + |
906 | +[desktop] |
907 | +ObjectPath=/com/canonical/indicator/messages/desktop |
908 | + |
909 | +[phone] |
910 | +ObjectPath=/com/canonical/indicator/messages/phone |
911 | |
912 | === modified file 'debian/control' |
913 | --- debian/control 2013-08-20 08:53:01 +0000 |
914 | +++ debian/control 2013-08-21 02:09:27 +0000 |
915 | @@ -7,19 +7,19 @@ |
916 | Build-Depends: debhelper (>= 9), |
917 | dh-autoreconf, |
918 | dh-translations, |
919 | - libglib2.0-dev (>= 2.35.4), |
920 | - libgtk-3-dev (>= 3.5.12), |
921 | + gobject-introspection (>= 0.9.12-4~), |
922 | + gtk-doc-tools, |
923 | + intltool, |
924 | libdbus-glib-1-dev, |
925 | - intltool, |
926 | - libindicator3-dev, |
927 | libdbusmenu-glib-dev (>= 0.5.90), |
928 | libdbusmenu-gtk3-dev (>= 0.5.90), |
929 | - libtelepathy-glib-dev (>= 0.9.0), |
930 | - gobject-introspection (>= 0.9.12-4~), |
931 | libgirepository1.0-dev (>= 0.9.12), |
932 | - gtk-doc-tools, |
933 | libgtest-dev, |
934 | + libgtk-3-dev (>= 3.5.18), |
935 | + libindicator3-dev, |
936 | + libtelepathy-glib-dev (>= 0.9.0), |
937 | python3-dbusmock, |
938 | + valac, |
939 | Standards-Version: 3.9.3 |
940 | Homepage: https://launchpad.net/indicator-messages |
941 | # If you aren't a member of ~indicator-applet-developers but need to upload |
942 | |
943 | === modified file 'debian/indicator-messages.install' |
944 | --- debian/indicator-messages.install 2013-08-20 08:53:01 +0000 |
945 | +++ debian/indicator-messages.install 2013-08-21 02:09:27 +0000 |
946 | @@ -1,5 +1,5 @@ |
947 | -usr/lib/indicators3 |
948 | usr/lib/indicator-messages/indicator-messages-service |
949 | usr/share/dbus-1 |
950 | usr/share/glib-2.0 |
951 | usr/share/icons |
952 | +usr/share/unity/indicators |
953 | |
954 | === modified file 'debian/libmessaging-menu-dev.install' |
955 | --- debian/libmessaging-menu-dev.install 2013-08-20 08:53:01 +0000 |
956 | +++ debian/libmessaging-menu-dev.install 2013-08-21 02:09:27 +0000 |
957 | @@ -2,4 +2,5 @@ |
958 | usr/lib/pkgconfig |
959 | usr/include /usr/ |
960 | usr/share/gir-1.0/ |
961 | +usr/share/vala/ |
962 | usr/share/gtk-doc |
963 | |
964 | === modified file 'debian/libmessaging-menu0.symbols' |
965 | --- debian/libmessaging-menu0.symbols 2013-08-20 08:53:01 +0000 |
966 | +++ debian/libmessaging-menu0.symbols 2013-08-21 02:09:27 +0000 |
967 | @@ -1,9 +1,11 @@ |
968 | libmessaging-menu.so.0 libmessaging-menu0 #MINVER# |
969 | + messaging_menu_app_append_message@Base 12.10.6-0ubuntu1phablet1 |
970 | messaging_menu_app_append_source@Base 12.10.0 |
971 | messaging_menu_app_append_source_with_count@Base 12.10.0 |
972 | messaging_menu_app_append_source_with_string@Base 12.10.0 |
973 | messaging_menu_app_append_source_with_time@Base 12.10.0 |
974 | messaging_menu_app_draw_attention@Base 12.10.0 |
975 | + messaging_menu_app_get_message@Base 13.10.1+13.10.20130820 |
976 | messaging_menu_app_get_type@Base 12.10.0 |
977 | messaging_menu_app_has_source@Base 12.10.0 |
978 | messaging_menu_app_insert_source@Base 12.10.0 |
979 | @@ -13,6 +15,8 @@ |
980 | messaging_menu_app_new@Base 12.10.0 |
981 | messaging_menu_app_register@Base 12.10.0 |
982 | messaging_menu_app_remove_attention@Base 12.10.0 |
983 | + messaging_menu_app_remove_message@Base 12.10.6-0ubuntu1phablet1 |
984 | + messaging_menu_app_remove_message_by_id@Base 12.10.6-0ubuntu1phablet1 |
985 | messaging_menu_app_remove_source@Base 12.10.0 |
986 | messaging_menu_app_set_source_count@Base 12.10.0 |
987 | messaging_menu_app_set_source_icon@Base 12.10.2 |
988 | @@ -21,3 +25,14 @@ |
989 | messaging_menu_app_set_source_time@Base 12.10.0 |
990 | messaging_menu_app_set_status@Base 12.10.0 |
991 | messaging_menu_app_unregister@Base 12.10.0 |
992 | + messaging_menu_message_add_action@Base 12.10.6-0ubuntu1phablet3 |
993 | + messaging_menu_message_get_body@Base 12.10.6-0ubuntu1phablet1 |
994 | + messaging_menu_message_get_draws_attention@Base 12.10.6-0ubuntu1phablet1 |
995 | + messaging_menu_message_get_icon@Base 12.10.6-0ubuntu1phablet1 |
996 | + messaging_menu_message_get_id@Base 12.10.6-0ubuntu1phablet1 |
997 | + messaging_menu_message_get_subtitle@Base 12.10.6-0ubuntu1phablet1 |
998 | + messaging_menu_message_get_time@Base 12.10.6-0ubuntu1phablet1 |
999 | + messaging_menu_message_get_title@Base 12.10.6-0ubuntu1phablet1 |
1000 | + messaging_menu_message_get_type@Base 12.10.6-0ubuntu1phablet1 |
1001 | + messaging_menu_message_new@Base 12.10.6-0ubuntu1phablet1 |
1002 | + messaging_menu_message_set_draws_attention@Base 12.10.6-0ubuntu1phablet1 |
1003 | |
1004 | === added directory 'debian/source' |
1005 | === added file 'debian/source/format' |
1006 | --- debian/source/format 1970-01-01 00:00:00 +0000 |
1007 | +++ debian/source/format 2013-08-21 02:09:27 +0000 |
1008 | @@ -0,0 +1,1 @@ |
1009 | +1.0 |
1010 | |
1011 | === modified file 'doc/reference/Makefile.am' |
1012 | --- doc/reference/Makefile.am 2013-08-20 08:53:01 +0000 |
1013 | +++ doc/reference/Makefile.am 2013-08-21 02:09:27 +0000 |
1014 | @@ -11,8 +11,7 @@ |
1015 | CFILE_GLOB = $(top_srcdir)/libmessaging-menu/*.c |
1016 | |
1017 | IGNORE_HFILES= \ |
1018 | - indicator-messages-service.h \ |
1019 | - gtupleaction.h |
1020 | + indicator-messages-service.h |
1021 | |
1022 | INCLUDES=-I$(top_srcdir)/libmessaging-menu $(GIO_CFLAGS) |
1023 | GTKDOC_LIBS=$(top_builddir)/libmessaging-menu/libmessaging-menu.la |
1024 | |
1025 | === modified file 'doc/reference/messaging-menu-docs.xml.in' |
1026 | --- doc/reference/messaging-menu-docs.xml.in 2013-08-20 08:53:01 +0000 |
1027 | +++ doc/reference/messaging-menu-docs.xml.in 2013-08-21 02:09:27 +0000 |
1028 | @@ -18,7 +18,8 @@ |
1029 | |
1030 | <chapter> |
1031 | <title>API Reference</title> |
1032 | - <xi:include href="xml/messaging-menu.xml"/> |
1033 | + <xi:include href="xml/messaging-menu-app.xml" /> |
1034 | + <xi:include href="xml/messaging-menu-message.xml" /> |
1035 | </chapter> |
1036 | |
1037 | <chapter id="object-tree"> |
1038 | |
1039 | === modified file 'libmessaging-menu/Makefile.am' |
1040 | --- libmessaging-menu/Makefile.am 2013-08-20 08:53:01 +0000 |
1041 | +++ libmessaging-menu/Makefile.am 2013-08-21 02:09:27 +0000 |
1042 | @@ -4,36 +4,25 @@ |
1043 | libmessaging_menu_ladir = $(includedir)/messaging-menu |
1044 | |
1045 | libmessaging_menu_la_SOURCES = \ |
1046 | - messaging-menu.c \ |
1047 | - gtupleaction.c \ |
1048 | - gtupleaction.h \ |
1049 | - $(BUILT_SOURCES) |
1050 | + messaging-menu-app.c \ |
1051 | + messaging-menu-message.c |
1052 | |
1053 | libmessaging_menu_la_HEADERS = \ |
1054 | - messaging-menu.h |
1055 | + messaging-menu-app.h \ |
1056 | + messaging-menu.h \ |
1057 | + messaging-menu-message.h |
1058 | |
1059 | -libmessaging_menu_la_LIBADD = $(GIO_LIBS) |
1060 | +libmessaging_menu_la_LIBADD = \ |
1061 | + $(GIO_LIBS) \ |
1062 | + $(top_builddir)/common/libmessaging-common.la |
1063 | |
1064 | libmessaging_menu_la_CFLAGS = \ |
1065 | + -I$(top_builddir)/common \ |
1066 | $(GIO_CFLAGS) \ |
1067 | -Wall |
1068 | |
1069 | libmessaging_menu_la_LDFLAGS = -export-symbols-regex "^messaging_menu_.*" |
1070 | |
1071 | -BUILT_SOURCES = \ |
1072 | - indicator-messages-service.c \ |
1073 | - indicator-messages-service.h |
1074 | - |
1075 | -CLEANFILES = $(BUILT_SOURCES) |
1076 | - |
1077 | -indicator-messages-service.c: $(top_srcdir)/src/messages-service.xml |
1078 | - $(AM_V_GEN) gdbus-codegen \ |
1079 | - --interface-prefix com.canonical.indicator.messages. \ |
1080 | - --generate-c-code indicator-messages-service \ |
1081 | - --c-namespace IndicatorMessages \ |
1082 | - $^ |
1083 | -indicator-messages-service.h: indicator-messages-service.c |
1084 | - |
1085 | pkgconfigdir = $(libdir)/pkgconfig |
1086 | pkgconfig_DATA = messaging-menu.pc |
1087 | |
1088 | @@ -52,7 +41,11 @@ |
1089 | MessagingMenu_1_0_gir_CFLAGS = $(INCLUDES) $(GIO_CFLAGS) |
1090 | MessagingMenu_1_0_gir_SCANNERFLAGS = --c-include="messaging-menu.h" |
1091 | MessagingMenu_1_0_gir_LIBS = libmessaging-menu.la |
1092 | -MessagingMenu_1_0_gir_FILES = messaging-menu.c messaging-menu.h |
1093 | +MessagingMenu_1_0_gir_FILES = \ |
1094 | + messaging-menu-app.c \ |
1095 | + messaging-menu-app.h \ |
1096 | + messaging-menu-message.c \ |
1097 | + messaging-menu-message.h |
1098 | MessagingMenu_1_0_gir_EXPORT_PACKAGES = messaging-menu |
1099 | INTROSPECTION_GIRS += MessagingMenu-1.0.gir |
1100 | |
1101 | @@ -62,5 +55,23 @@ |
1102 | typelibdir = $(libdir)/girepository-1.0 |
1103 | typelib_DATA = $(INTROSPECTION_GIRS:.gir=.typelib) |
1104 | |
1105 | -CLEANFILES +=$(gir_DATA) $(typelib_DATA) |
1106 | +CLEANFILES = $(gir_DATA) $(typelib_DATA) |
1107 | + |
1108 | + |
1109 | +######################### |
1110 | +# VAPI Files |
1111 | +######################### |
1112 | + |
1113 | +if HAVE_VALA |
1114 | + |
1115 | +vapidir = $(datadir)/vala/vapi |
1116 | +vapi_DATA = MessagingMenu-1.0.vapi |
1117 | + |
1118 | +MessagingMenu-1.0.vapi: MessagingMenu-1.0.gir |
1119 | + $(VALA_API_GEN) --pkg gio-2.0 --library=MessagingMenu-1.0 $< |
1120 | + |
1121 | +CLEANFILES += $(vapi_DATA) |
1122 | + |
1123 | +endif |
1124 | + |
1125 | endif |
1126 | |
1127 | === removed file 'libmessaging-menu/gtupleaction.c' |
1128 | --- libmessaging-menu/gtupleaction.c 2013-08-20 08:53:01 +0000 |
1129 | +++ libmessaging-menu/gtupleaction.c 1970-01-01 00:00:00 +0000 |
1130 | @@ -1,354 +0,0 @@ |
1131 | -/* |
1132 | - * Copyright 2012 Canonical Ltd. |
1133 | - * |
1134 | - * This program is free software: you can redistribute it and/or modify it |
1135 | - * under the terms of the GNU General Public License version 3, as |
1136 | - * published by the Free Software Foundation. |
1137 | - * |
1138 | - * This program is distributed in the hope that it will be useful, but |
1139 | - * WITHOUT ANY WARRANTY; without even the implied warranties of |
1140 | - * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
1141 | - * PURPOSE. See the GNU General Public License for more details. |
1142 | - * |
1143 | - * You should have received a copy of the GNU General Public License along |
1144 | - * with this program. If not, see <http://www.gnu.org/licenses/>. |
1145 | - * |
1146 | - * Authors: |
1147 | - * Lars Uebernickel <lars.uebernickel@canonical.com> |
1148 | - */ |
1149 | - |
1150 | -#include "gtupleaction.h" |
1151 | - |
1152 | -typedef GObjectClass GTupleActionClass; |
1153 | - |
1154 | -struct _GTupleAction |
1155 | -{ |
1156 | - GObject parent; |
1157 | - |
1158 | - gchar *name; |
1159 | - GVariantType *type; |
1160 | - gboolean enabled; |
1161 | - |
1162 | - gsize n_children; |
1163 | - GVariant **children; |
1164 | -}; |
1165 | - |
1166 | -static void action_interface_init (GActionInterface *iface); |
1167 | - |
1168 | -G_DEFINE_TYPE_WITH_CODE (GTupleAction, g_tuple_action, G_TYPE_OBJECT, |
1169 | - G_IMPLEMENT_INTERFACE (G_TYPE_ACTION, action_interface_init)); |
1170 | - |
1171 | -enum |
1172 | -{ |
1173 | - PROP_0, |
1174 | - PROP_NAME, |
1175 | - PROP_PARAMETER_TYPE, |
1176 | - PROP_ENABLED, |
1177 | - PROP_STATE_TYPE, |
1178 | - PROP_STATE, |
1179 | - N_PROPERTIES |
1180 | -}; |
1181 | - |
1182 | -enum |
1183 | -{ |
1184 | - SIGNAL_ACTIVATE, |
1185 | - N_SIGNALS |
1186 | -}; |
1187 | - |
1188 | -static GParamSpec *properties[N_PROPERTIES]; |
1189 | -static guint signal_ids[N_SIGNALS]; |
1190 | - |
1191 | -static const gchar * |
1192 | -g_tuple_action_get_name (GAction *action) |
1193 | -{ |
1194 | - GTupleAction *tuple = G_TUPLE_ACTION (action); |
1195 | - |
1196 | - return tuple->name; |
1197 | -} |
1198 | - |
1199 | -static const GVariantType * |
1200 | -g_tuple_action_get_parameter_type (GAction *action) |
1201 | -{ |
1202 | - return NULL; |
1203 | -} |
1204 | - |
1205 | -static const GVariantType * |
1206 | -g_tuple_action_get_state_type (GAction *action) |
1207 | -{ |
1208 | - GTupleAction *tuple = G_TUPLE_ACTION (action); |
1209 | - |
1210 | - return tuple->type; |
1211 | -} |
1212 | - |
1213 | -static GVariant * |
1214 | -g_tuple_action_get_state_hint (GAction *action) |
1215 | -{ |
1216 | - return NULL; |
1217 | -} |
1218 | - |
1219 | -static gboolean |
1220 | -g_tuple_action_get_enabled (GAction *action) |
1221 | -{ |
1222 | - GTupleAction *tuple = G_TUPLE_ACTION (action); |
1223 | - |
1224 | - return tuple->enabled; |
1225 | -} |
1226 | - |
1227 | -static GVariant * |
1228 | -g_tuple_action_get_state (GAction *action) |
1229 | -{ |
1230 | - GTupleAction *tuple = G_TUPLE_ACTION (action); |
1231 | - GVariant *result; |
1232 | - |
1233 | - result = g_variant_new_tuple (tuple->children, tuple->n_children); |
1234 | - return g_variant_ref_sink (result); |
1235 | -} |
1236 | - |
1237 | -static void |
1238 | -g_tuple_action_set_state (GTupleAction *tuple, |
1239 | - GVariant *state) |
1240 | -{ |
1241 | - int i; |
1242 | - |
1243 | - g_return_if_fail (g_variant_type_is_tuple (g_variant_get_type (state))); |
1244 | - |
1245 | - if (tuple->type == NULL) |
1246 | - { |
1247 | - tuple->type = g_variant_type_copy (g_variant_get_type (state)); |
1248 | - tuple->n_children = g_variant_n_children (state); |
1249 | - tuple->children = g_new0 (GVariant *, tuple->n_children); |
1250 | - } |
1251 | - |
1252 | - for (i = 0; i < tuple->n_children; i++) |
1253 | - { |
1254 | - if (tuple->children[i]) |
1255 | - g_variant_unref (tuple->children[i]); |
1256 | - tuple->children[i] = g_variant_get_child_value (state, i); |
1257 | - } |
1258 | - |
1259 | - g_object_notify_by_pspec (G_OBJECT (tuple), properties[PROP_STATE]); |
1260 | -} |
1261 | - |
1262 | -static void |
1263 | -g_tuple_action_change_state (GAction *action, |
1264 | - GVariant *value) |
1265 | -{ |
1266 | - GTupleAction *tuple = G_TUPLE_ACTION (action); |
1267 | - |
1268 | - g_return_if_fail (value != NULL); |
1269 | - g_return_if_fail (g_variant_is_of_type (value, tuple->type)); |
1270 | - |
1271 | - g_variant_ref_sink (value); |
1272 | - |
1273 | - /* TODO add a change-state signal similar to GSimpleAction */ |
1274 | - g_tuple_action_set_state (tuple, value); |
1275 | - |
1276 | - g_variant_unref (value); |
1277 | -} |
1278 | - |
1279 | -static void |
1280 | -g_tuple_action_activate (GAction *action, |
1281 | - GVariant *parameter) |
1282 | -{ |
1283 | - GTupleAction *tuple = G_TUPLE_ACTION (action); |
1284 | - |
1285 | - g_return_if_fail (parameter == NULL); |
1286 | - |
1287 | - if (tuple->enabled) |
1288 | - g_signal_emit (tuple, signal_ids[SIGNAL_ACTIVATE], 0, NULL); |
1289 | -} |
1290 | - |
1291 | -static void |
1292 | -g_tuple_action_get_property (GObject *object, |
1293 | - guint prop_id, |
1294 | - GValue *value, |
1295 | - GParamSpec *pspec) |
1296 | -{ |
1297 | - GAction *action = G_ACTION (object); |
1298 | - |
1299 | - switch (prop_id) |
1300 | - { |
1301 | - case PROP_NAME: |
1302 | - g_value_set_string (value, g_tuple_action_get_name (action)); |
1303 | - break; |
1304 | - |
1305 | - case PROP_PARAMETER_TYPE: |
1306 | - g_value_set_boxed (value, g_tuple_action_get_parameter_type (action)); |
1307 | - break; |
1308 | - |
1309 | - case PROP_ENABLED: |
1310 | - g_value_set_boolean (value, g_tuple_action_get_enabled (action)); |
1311 | - break; |
1312 | - |
1313 | - case PROP_STATE_TYPE: |
1314 | - g_value_set_boxed (value, g_tuple_action_get_state_type (action)); |
1315 | - break; |
1316 | - |
1317 | - case PROP_STATE: |
1318 | - g_value_take_variant (value, g_tuple_action_get_state (action)); |
1319 | - break; |
1320 | - |
1321 | - default: |
1322 | - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
1323 | - } |
1324 | -} |
1325 | - |
1326 | -static void |
1327 | -g_tuple_action_set_property (GObject *object, |
1328 | - guint prop_id, |
1329 | - const GValue *value, |
1330 | - GParamSpec *pspec) |
1331 | -{ |
1332 | - GTupleAction *tuple = G_TUPLE_ACTION (object); |
1333 | - |
1334 | - switch (prop_id) |
1335 | - { |
1336 | - case PROP_NAME: |
1337 | - tuple->name = g_value_dup_string (value); |
1338 | - g_object_notify_by_pspec (object, properties[PROP_NAME]); |
1339 | - break; |
1340 | - |
1341 | - case PROP_ENABLED: |
1342 | - tuple->enabled = g_value_get_boolean (value); |
1343 | - g_object_notify_by_pspec (object, properties[PROP_ENABLED]); |
1344 | - break; |
1345 | - |
1346 | - case PROP_STATE: |
1347 | - g_tuple_action_set_state (tuple, g_value_get_variant (value)); |
1348 | - break; |
1349 | - |
1350 | - default: |
1351 | - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
1352 | - } |
1353 | -} |
1354 | - |
1355 | -static void |
1356 | -g_tuple_action_finalize (GObject *object) |
1357 | -{ |
1358 | - GTupleAction *tuple = G_TUPLE_ACTION (object); |
1359 | - int i; |
1360 | - |
1361 | - g_free (tuple->name); |
1362 | - g_variant_type_free (tuple->type); |
1363 | - |
1364 | - for (i = 0; i < tuple->n_children; i++) |
1365 | - g_variant_unref (tuple->children[i]); |
1366 | - |
1367 | - g_free (tuple->children); |
1368 | - |
1369 | - G_OBJECT_CLASS (g_tuple_action_parent_class)->finalize (object); |
1370 | -} |
1371 | - |
1372 | -static void |
1373 | -action_interface_init (GActionInterface *iface) |
1374 | -{ |
1375 | - iface->get_name = g_tuple_action_get_name; |
1376 | - iface->get_parameter_type = g_tuple_action_get_parameter_type; |
1377 | - iface->get_state_type = g_tuple_action_get_state_type; |
1378 | - iface->get_state_hint = g_tuple_action_get_state_hint; |
1379 | - iface->get_enabled = g_tuple_action_get_enabled; |
1380 | - iface->get_state = g_tuple_action_get_state; |
1381 | - iface->change_state = g_tuple_action_change_state; |
1382 | - iface->activate = g_tuple_action_activate; |
1383 | -} |
1384 | - |
1385 | -static void |
1386 | -g_tuple_action_class_init (GTupleActionClass *class) |
1387 | -{ |
1388 | - GObjectClass *object_class = G_OBJECT_CLASS (class); |
1389 | - |
1390 | - object_class->get_property = g_tuple_action_get_property; |
1391 | - object_class->set_property = g_tuple_action_set_property; |
1392 | - object_class->finalize = g_tuple_action_finalize; |
1393 | - |
1394 | - properties[PROP_NAME] = g_param_spec_string ("name", |
1395 | - "Name", |
1396 | - "The name of the action", |
1397 | - NULL, |
1398 | - G_PARAM_READWRITE | |
1399 | - G_PARAM_CONSTRUCT_ONLY | |
1400 | - G_PARAM_STATIC_STRINGS); |
1401 | - |
1402 | - properties[PROP_PARAMETER_TYPE] = g_param_spec_boxed ("parameter-type", |
1403 | - "Parameter Type", |
1404 | - "The variant type passed to activate", |
1405 | - G_TYPE_VARIANT_TYPE, |
1406 | - G_PARAM_READABLE | |
1407 | - G_PARAM_STATIC_STRINGS); |
1408 | - |
1409 | - properties[PROP_ENABLED] = g_param_spec_boolean ("enabled", |
1410 | - "Enabled", |
1411 | - "Whether the action can be activated", |
1412 | - TRUE, |
1413 | - G_PARAM_READWRITE | |
1414 | - G_PARAM_STATIC_STRINGS); |
1415 | - |
1416 | - properties[PROP_STATE_TYPE] = g_param_spec_boxed ("state-type", |
1417 | - "State Type", |
1418 | - "The variant type of the state, must be a tuple", |
1419 | - G_TYPE_VARIANT_TYPE, |
1420 | - G_PARAM_READABLE | |
1421 | - G_PARAM_STATIC_STRINGS); |
1422 | - |
1423 | - properties[PROP_STATE] = g_param_spec_variant ("state", |
1424 | - "State", |
1425 | - "The state of the action", |
1426 | - G_VARIANT_TYPE_TUPLE, |
1427 | - NULL, |
1428 | - G_PARAM_READWRITE | |
1429 | - G_PARAM_STATIC_STRINGS); |
1430 | - |
1431 | - g_object_class_install_properties (object_class, N_PROPERTIES, properties); |
1432 | - |
1433 | - signal_ids[SIGNAL_ACTIVATE] = g_signal_new ("activate", |
1434 | - G_TYPE_TUPLE_ACTION, |
1435 | - G_SIGNAL_RUN_LAST | G_SIGNAL_MUST_COLLECT, |
1436 | - 0, NULL, NULL, |
1437 | - g_cclosure_marshal_VOID__VARIANT, |
1438 | - G_TYPE_NONE, 1, |
1439 | - G_TYPE_VARIANT); |
1440 | -} |
1441 | - |
1442 | -static void |
1443 | -g_tuple_action_init (GTupleAction *action) |
1444 | -{ |
1445 | - action->enabled = TRUE; |
1446 | -} |
1447 | - |
1448 | -GTupleAction * |
1449 | -g_tuple_action_new (const gchar *name, |
1450 | - GVariant *initial_state) |
1451 | -{ |
1452 | - const GVariantType *type; |
1453 | - |
1454 | - g_return_val_if_fail (name != NULL, NULL); |
1455 | - g_return_val_if_fail (initial_state != NULL, NULL); |
1456 | - |
1457 | - type = g_variant_get_type (initial_state); |
1458 | - g_return_val_if_fail (g_variant_type_is_tuple (type), NULL); |
1459 | - |
1460 | - return g_object_new (G_TYPE_TUPLE_ACTION, |
1461 | - "name", name, |
1462 | - "state", initial_state, |
1463 | - NULL); |
1464 | -} |
1465 | - |
1466 | -void |
1467 | -g_tuple_action_set_child (GTupleAction *action, |
1468 | - gsize index, |
1469 | - GVariant *value) |
1470 | -{ |
1471 | - const GVariantType *type; |
1472 | - |
1473 | - g_return_if_fail (G_IS_TUPLE_ACTION (action)); |
1474 | - g_return_if_fail (index < action->n_children); |
1475 | - g_return_if_fail (value != NULL); |
1476 | - |
1477 | - type = g_variant_get_type (value); |
1478 | - g_return_if_fail (g_variant_is_of_type (value, type)); |
1479 | - |
1480 | - g_variant_unref (action->children[index]); |
1481 | - action->children[index] = g_variant_ref_sink (value); |
1482 | - |
1483 | - g_object_notify_by_pspec (G_OBJECT (action), properties[PROP_STATE]); |
1484 | -} |
1485 | |
1486 | === removed file 'libmessaging-menu/gtupleaction.h' |
1487 | --- libmessaging-menu/gtupleaction.h 2013-08-20 08:53:01 +0000 |
1488 | +++ libmessaging-menu/gtupleaction.h 1970-01-01 00:00:00 +0000 |
1489 | @@ -1,40 +0,0 @@ |
1490 | -/* |
1491 | - * Copyright 2012 Canonical Ltd. |
1492 | - * |
1493 | - * This program is free software: you can redistribute it and/or modify it |
1494 | - * under the terms of the GNU General Public License version 3, as |
1495 | - * published by the Free Software Foundation. |
1496 | - * |
1497 | - * This program is distributed in the hope that it will be useful, but |
1498 | - * WITHOUT ANY WARRANTY; without even the implied warranties of |
1499 | - * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
1500 | - * PURPOSE. See the GNU General Public License for more details. |
1501 | - * |
1502 | - * You should have received a copy of the GNU General Public License along |
1503 | - * with this program. If not, see <http://www.gnu.org/licenses/>. |
1504 | - * |
1505 | - * Authors: |
1506 | - * Lars Uebernickel <lars.uebernickel@canonical.com> |
1507 | - */ |
1508 | - |
1509 | -#ifndef __g_tuple_action_h__ |
1510 | -#define __g_tuple_action_h__ |
1511 | - |
1512 | -#include <gio/gio.h> |
1513 | - |
1514 | -#define G_TYPE_TUPLE_ACTION (g_tuple_action_get_type ()) |
1515 | -#define G_TUPLE_ACTION(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_TUPLE_ACTION, GTupleAction)) |
1516 | -#define G_IS_TUPLE_ACTION(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_TUPLE_ACTION)) |
1517 | - |
1518 | -typedef struct _GTupleAction GTupleAction; |
1519 | - |
1520 | -GType g_tuple_action_get_type (void) G_GNUC_CONST; |
1521 | - |
1522 | -GTupleAction * g_tuple_action_new (const gchar *name, |
1523 | - GVariant *initial_state); |
1524 | - |
1525 | -void g_tuple_action_set_child (GTupleAction *action, |
1526 | - gsize index, |
1527 | - GVariant *value); |
1528 | - |
1529 | -#endif |
1530 | |
1531 | === renamed file 'libmessaging-menu/messaging-menu.c' => 'libmessaging-menu/messaging-menu-app.c' |
1532 | --- libmessaging-menu/messaging-menu.c 2013-08-20 08:53:01 +0000 |
1533 | +++ libmessaging-menu/messaging-menu-app.c 2013-08-21 02:09:27 +0000 |
1534 | @@ -17,10 +17,12 @@ |
1535 | * Lars Uebernickel <lars.uebernickel@canonical.com> |
1536 | */ |
1537 | |
1538 | -#include "messaging-menu.h" |
1539 | +#include "messaging-menu-app.h" |
1540 | #include "indicator-messages-service.h" |
1541 | +#include "indicator-messages-application.h" |
1542 | |
1543 | #include <gio/gdesktopappinfo.h> |
1544 | +#include <string.h> |
1545 | |
1546 | /** |
1547 | * SECTION:messaging-menu |
1548 | @@ -102,14 +104,14 @@ |
1549 | int registered; /* -1 for unknown */ |
1550 | MessagingMenuStatus status; |
1551 | gboolean status_set; |
1552 | - GSimpleActionGroup *source_actions; |
1553 | - GMenu *menu; |
1554 | GDBusConnection *bus; |
1555 | |
1556 | + GHashTable *messages; |
1557 | + GList *sources; |
1558 | + IndicatorMessagesApplication *app_interface; |
1559 | + |
1560 | IndicatorMessagesService *messages_service; |
1561 | guint watch_id; |
1562 | - guint action_export_id; |
1563 | - guint menu_export_id; |
1564 | |
1565 | GCancellable *cancellable; |
1566 | }; |
1567 | @@ -133,10 +135,61 @@ |
1568 | |
1569 | static const gchar *status_ids[] = { "available", "away", "busy", "invisible", "offline" }; |
1570 | |
1571 | +typedef struct |
1572 | +{ |
1573 | + gchar *id; |
1574 | + GIcon *icon; |
1575 | + gchar *label; |
1576 | + |
1577 | + guint32 count; |
1578 | + gint64 time; |
1579 | + gchar *string; |
1580 | + gboolean draws_attention; |
1581 | +} Source; |
1582 | + |
1583 | static void global_status_changed (IndicatorMessagesService *service, |
1584 | const gchar *status_str, |
1585 | gpointer user_data); |
1586 | |
1587 | +/* in messaging-menu-message.c */ |
1588 | +GVariant * _messaging_menu_message_to_variant (MessagingMenuMessage *msg); |
1589 | + |
1590 | +static void |
1591 | +source_free (gpointer data) |
1592 | +{ |
1593 | + Source *source = data; |
1594 | + |
1595 | + if (source) |
1596 | + { |
1597 | + g_free (source->id); |
1598 | + g_clear_object (&source->icon); |
1599 | + g_free (source->label); |
1600 | + g_free (source->string); |
1601 | + g_slice_free (Source, source); |
1602 | + } |
1603 | +} |
1604 | + |
1605 | +static GVariant * |
1606 | +source_to_variant (Source *source) |
1607 | +{ |
1608 | + GVariant *v; |
1609 | + gchar *iconstr; |
1610 | + |
1611 | + iconstr = source->icon ? g_icon_to_string (source->icon) : NULL; |
1612 | + |
1613 | + v = g_variant_new ("(sssuxsb)", source->id, |
1614 | + source->label, |
1615 | + iconstr ? iconstr : "", |
1616 | + source->count, |
1617 | + source->time, |
1618 | + source->string ? source->string : "", |
1619 | + source->draws_attention); |
1620 | + |
1621 | + g_free (iconstr); |
1622 | + |
1623 | + return v; |
1624 | +} |
1625 | + |
1626 | static gchar * |
1627 | messaging_menu_app_get_dbus_object_path (MessagingMenuApp *app) |
1628 | { |
1629 | @@ -155,18 +208,14 @@ |
1630 | } |
1631 | |
1632 | static void |
1633 | -export_menus_and_actions (GObject *source, |
1634 | - GAsyncResult *res, |
1635 | - gpointer user_data) |
1636 | +messaging_menu_app_got_bus (GObject *source, |
1637 | + GAsyncResult *res, |
1638 | + gpointer user_data) |
1639 | { |
1640 | MessagingMenuApp *app = user_data; |
1641 | GError *error = NULL; |
1642 | gchar *object_path; |
1643 | |
1644 | - object_path = messaging_menu_app_get_dbus_object_path (app); |
1645 | - if (!object_path) |
1646 | - return; |
1647 | - |
1648 | app->bus = g_bus_get_finish (res, &error); |
1649 | if (app->bus == NULL) |
1650 | { |
1651 | @@ -175,23 +224,13 @@ |
1652 | return; |
1653 | } |
1654 | |
1655 | - app->action_export_id = g_dbus_connection_export_action_group (app->bus, |
1656 | - object_path, |
1657 | - G_ACTION_GROUP (app->source_actions), |
1658 | - &error); |
1659 | - if (!app->action_export_id) |
1660 | - { |
1661 | - g_warning ("unable to export action group: %s", error->message); |
1662 | - g_clear_error (&error); |
1663 | - } |
1664 | + object_path = messaging_menu_app_get_dbus_object_path (app); |
1665 | |
1666 | - app->menu_export_id = g_dbus_connection_export_menu_model (app->bus, |
1667 | - object_path, |
1668 | - G_MENU_MODEL (app->menu), |
1669 | - &error); |
1670 | - if (!app->menu_export_id) |
1671 | + if (object_path && |
1672 | + !g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (app->app_interface), |
1673 | + app->bus, object_path, &error)) |
1674 | { |
1675 | - g_warning ("unable to export menu: %s", error->message); |
1676 | + g_warning ("unable to export application interface: %s", error->message); |
1677 | g_clear_error (&error); |
1678 | } |
1679 | |
1680 | @@ -214,7 +253,7 @@ |
1681 | |
1682 | g_bus_get (G_BUS_TYPE_SESSION, |
1683 | app->cancellable, |
1684 | - export_menus_and_actions, |
1685 | + messaging_menu_app_got_bus, |
1686 | app); |
1687 | } |
1688 | |
1689 | @@ -248,20 +287,6 @@ |
1690 | { |
1691 | MessagingMenuApp *app = MESSAGING_MENU_APP (object); |
1692 | |
1693 | - if (app->bus) |
1694 | - { |
1695 | - if (app->action_export_id > 0) |
1696 | - g_dbus_connection_unexport_action_group (app->bus, app->action_export_id); |
1697 | - |
1698 | - if (app->menu_export_id > 0) |
1699 | - g_dbus_connection_unexport_menu_model (app->bus, app->menu_export_id); |
1700 | - |
1701 | - app->action_export_id = 0; |
1702 | - app->menu_export_id = 0; |
1703 | - g_object_unref (app->bus); |
1704 | - app->bus = NULL; |
1705 | - } |
1706 | - |
1707 | if (app->watch_id > 0) |
1708 | { |
1709 | g_bus_unwatch_name (app->watch_id); |
1710 | @@ -287,9 +312,14 @@ |
1711 | g_clear_object (&app->messages_service); |
1712 | } |
1713 | |
1714 | + g_clear_pointer (&app->messages, g_hash_table_unref); |
1715 | + |
1716 | + g_list_free_full (app->sources, source_free); |
1717 | + app->sources = NULL; |
1718 | + |
1719 | + g_clear_object (&app->app_interface); |
1720 | g_clear_object (&app->appinfo); |
1721 | - g_clear_object (&app->source_actions); |
1722 | - g_clear_object (&app->menu); |
1723 | + g_clear_object (&app->bus); |
1724 | |
1725 | G_OBJECT_CLASS (messaging_menu_app_parent_class)->dispose (object); |
1726 | } |
1727 | @@ -420,6 +450,168 @@ |
1728 | } |
1729 | } |
1730 | |
1731 | +static gboolean |
1732 | +messaging_menu_app_list_sources (IndicatorMessagesApplication *app_interface, |
1733 | + GDBusMethodInvocation *invocation, |
1734 | + gpointer user_data) |
1735 | +{ |
1736 | + MessagingMenuApp *app = user_data; |
1737 | + GVariantBuilder builder; |
1738 | + GList *it; |
1739 | + |
1740 | + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(sssuxsb)")); |
1741 | + |
1742 | + for (it = app->sources; it; it = it->next) |
1743 | + g_variant_builder_add_value (&builder, source_to_variant (it->data)); |
1744 | + |
1745 | + indicator_messages_application_complete_list_sources (app_interface, |
1746 | + invocation, |
1747 | + g_variant_builder_end (&builder)); |
1748 | + |
1749 | + return TRUE; |
1750 | +} |
1751 | + |
1752 | +static gint |
1753 | +compare_source_id (gconstpointer a, |
1754 | + gconstpointer b) |
1755 | +{ |
1756 | + const Source *source = a; |
1757 | + const gchar *id = b; |
1758 | + |
1759 | + return strcmp (source->id, id); |
1760 | +} |
1761 | + |
1762 | +static gboolean |
1763 | +messaging_menu_app_remove_source_internal (MessagingMenuApp *app, |
1764 | + const gchar *source_id) |
1765 | +{ |
1766 | + GList *node; |
1767 | + |
1768 | + node = g_list_find_custom (app->sources, source_id, compare_source_id); |
1769 | + if (node) |
1770 | + { |
1771 | + source_free (node->data); |
1772 | + app->sources = g_list_delete_link (app->sources, node); |
1773 | + return TRUE; |
1774 | + } |
1775 | + |
1776 | + return FALSE; |
1777 | +} |
1778 | + |
1779 | +static gboolean |
1780 | +messaging_menu_app_remove_message_internal (MessagingMenuApp *app, |
1781 | + const gchar *message_id) |
1782 | +{ |
1783 | + return g_hash_table_remove (app->messages, message_id); |
1784 | +} |
1785 | + |
1786 | +static gboolean |
1787 | +messaging_menu_app_activate_source (IndicatorMessagesApplication *app_interface, |
1788 | + GDBusMethodInvocation *invocation, |
1789 | + const gchar *source_id, |
1790 | + gpointer user_data) |
1791 | +{ |
1792 | + MessagingMenuApp *app = user_data; |
1793 | + GQuark q = g_quark_from_string (source_id); |
1794 | + |
1795 | + /* Activate implies removing the source, no need for SourceRemoved */ |
1796 | + if (messaging_menu_app_remove_source_internal (app, source_id)) |
1797 | + g_signal_emit (app, signals[ACTIVATE_SOURCE], q, source_id); |
1798 | + |
1799 | + indicator_messages_application_complete_activate_source (app_interface, invocation); |
1800 | + |
1801 | + return TRUE; |
1802 | +} |
1803 | + |
1804 | +static gboolean |
1805 | +messaging_menu_app_list_messages (IndicatorMessagesApplication *app_interface, |
1806 | + GDBusMethodInvocation *invocation, |
1807 | + gpointer user_data) |
1808 | +{ |
1809 | + MessagingMenuApp *app = user_data; |
1810 | + GVariantBuilder builder; |
1811 | + GHashTableIter iter; |
1812 | + MessagingMenuMessage *message; |
1813 | + |
1814 | + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(sssssxaa{sv}b)")); |
1815 | + |
1816 | + g_hash_table_iter_init (&iter, app->messages); |
1817 | + while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &message)) |
1818 | + g_variant_builder_add_value (&builder, _messaging_menu_message_to_variant (message)); |
1819 | + |
1820 | + indicator_messages_application_complete_list_messages (app_interface, |
1821 | + invocation, |
1822 | + g_variant_builder_end (&builder)); |
1823 | + |
1824 | + return TRUE; |
1825 | +} |
1826 | + |
1827 | +static gboolean |
1828 | +messaging_menu_app_activate_message (IndicatorMessagesApplication *app_interface, |
1829 | + GDBusMethodInvocation *invocation, |
1830 | + const gchar *message_id, |
1831 | + const gchar *action_id, |
1832 | + GVariant *params, |
1833 | + gpointer user_data) |
1834 | +{ |
1835 | + MessagingMenuApp *app = user_data; |
1836 | + MessagingMenuMessage *msg; |
1837 | + |
1838 | + msg = g_hash_table_lookup (app->messages, message_id); |
1839 | + if (msg) |
1840 | + { |
1841 | + if (*action_id) |
1842 | + { |
1843 | + gchar *signal; |
1844 | + |
1845 | + signal = g_strconcat ("activate::", action_id, NULL); |
1846 | + |
1847 | + if (g_variant_n_children (params)) |
1848 | + { |
1849 | + GVariant *param; |
1850 | + |
1851 | + g_variant_get_child (params, 0, "v", ¶m); |
1852 | + g_signal_emit_by_name (msg, signal, action_id, param); |
1853 | + |
1854 | + g_variant_unref (param); |
1855 | + } |
1856 | + else |
1857 | + g_signal_emit_by_name (msg, signal, action_id, NULL); |
1858 | + |
1859 | + g_free (signal); |
1860 | + } |
1861 | + else |
1862 | + g_signal_emit_by_name (msg, "activate", NULL, NULL); |
1863 | + |
1864 | + |
1865 | + /* Activate implies removing the message, no need for MessageRemoved */ |
1866 | + messaging_menu_app_remove_message_internal (app, message_id); |
1867 | + } |
1868 | + |
1869 | + indicator_messages_application_complete_activate_message (app_interface, invocation); |
1870 | + |
1871 | + return TRUE; |
1872 | +} |
1873 | + |
1874 | +static gboolean |
1875 | +messaging_menu_app_dismiss (IndicatorMessagesApplication *app_interface, |
1876 | + GDBusMethodInvocation *invocation, |
1877 | + const gchar * const *sources, |
1878 | + const gchar * const *messages, |
1879 | + gpointer user_data) |
1880 | +{ |
1881 | + MessagingMenuApp *app = user_data; |
1882 | + const gchar * const *it; |
1883 | + |
1884 | + for (it = sources; *it; it++) |
1885 | + messaging_menu_app_remove_source_internal (app, *it); |
1886 | + |
1887 | + for (it = messages; *it; it++) |
1888 | + messaging_menu_app_remove_message_internal (app, *it); |
1889 | + |
1890 | + return TRUE; |
1891 | +} |
1892 | + |
1893 | static void |
1894 | messaging_menu_app_init (MessagingMenuApp *app) |
1895 | { |
1896 | @@ -427,15 +619,21 @@ |
1897 | app->status_set = FALSE; |
1898 | app->bus = NULL; |
1899 | |
1900 | - app->action_export_id = 0; |
1901 | - app->menu_export_id = 0; |
1902 | - |
1903 | - app->cancellable = g_cancellable_new (); |
1904 | - |
1905 | - app->source_actions = g_simple_action_group_new (); |
1906 | - app->menu = g_menu_new (); |
1907 | - |
1908 | - app->cancellable = g_cancellable_new (); |
1909 | + app->cancellable = g_cancellable_new (); |
1910 | + |
1911 | + app->app_interface = indicator_messages_application_skeleton_new (); |
1912 | + g_signal_connect (app->app_interface, "handle-list-sources", |
1913 | + G_CALLBACK (messaging_menu_app_list_sources), app); |
1914 | + g_signal_connect (app->app_interface, "handle-activate-source", |
1915 | + G_CALLBACK (messaging_menu_app_activate_source), app); |
1916 | + g_signal_connect (app->app_interface, "handle-list-messages", |
1917 | + G_CALLBACK (messaging_menu_app_list_messages), app); |
1918 | + g_signal_connect (app->app_interface, "handle-activate-message", |
1919 | + G_CALLBACK (messaging_menu_app_activate_message), app); |
1920 | + g_signal_connect (app->app_interface, "handle-dismiss", |
1921 | + G_CALLBACK (messaging_menu_app_dismiss), app); |
1922 | + |
1923 | + app->messages = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); |
1924 | |
1925 | app->watch_id = g_bus_watch_name (G_BUS_TYPE_SESSION, |
1926 | "com.canonical.indicator.messages", |
1927 | @@ -608,124 +806,73 @@ |
1928 | g_signal_emit (app, signals[STATUS_CHANGED], 0, status); |
1929 | } |
1930 | |
1931 | -static void |
1932 | -source_action_activated (GSimpleAction *action, |
1933 | - GVariant *parameter, |
1934 | - gpointer user_data) |
1935 | -{ |
1936 | - MessagingMenuApp *app = user_data; |
1937 | - const gchar *name = g_action_get_name (G_ACTION (action)); |
1938 | - GQuark q = g_quark_from_string (name); |
1939 | - |
1940 | - messaging_menu_app_remove_source (app, name); |
1941 | - |
1942 | - g_signal_emit (app, signals[ACTIVATE_SOURCE], q, name); |
1943 | -} |
1944 | - |
1945 | -static void |
1946 | -messaging_menu_app_insert_source_action (MessagingMenuApp *app, |
1947 | - gint position, |
1948 | - const gchar *id, |
1949 | - GIcon *icon, |
1950 | - const gchar *label, |
1951 | - GVariant *state) |
1952 | -{ |
1953 | - GSimpleAction *action; |
1954 | - GMenuItem *menuitem; |
1955 | +static Source * |
1956 | +messaging_menu_app_lookup_source (MessagingMenuApp *app, |
1957 | + const gchar *id) |
1958 | +{ |
1959 | + GList *node; |
1960 | + |
1961 | + node = g_list_find_custom (app->sources, id, compare_source_id); |
1962 | + |
1963 | + return node ? node->data : NULL; |
1964 | +} |
1965 | + |
1966 | +static Source * |
1967 | +messaging_menu_app_get_source (MessagingMenuApp *app, |
1968 | + const gchar *id) |
1969 | +{ |
1970 | + Source *source; |
1971 | + |
1972 | + source = messaging_menu_app_lookup_source (app, id); |
1973 | + if (!source) |
1974 | + g_warning ("a source with id '%s' doesn't exist", id); |
1975 | + |
1976 | + return source; |
1977 | +} |
1978 | + |
1979 | +static void |
1980 | +messaging_menu_app_notify_source_changed (MessagingMenuApp *app, |
1981 | + Source *source) |
1982 | +{ |
1983 | + indicator_messages_application_emit_source_changed (app->app_interface, |
1984 | + source_to_variant (source)); |
1985 | +} |
1986 | + |
1987 | +static void |
1988 | +messaging_menu_app_insert_source_internal (MessagingMenuApp *app, |
1989 | + gint position, |
1990 | + const gchar *id, |
1991 | + GIcon *icon, |
1992 | + const gchar *label, |
1993 | + guint count, |
1994 | + gint64 time, |
1995 | + const gchar *string) |
1996 | +{ |
1997 | + Source *source; |
1998 | |
1999 | g_return_if_fail (MESSAGING_MENU_IS_APP (app)); |
2000 | g_return_if_fail (id != NULL); |
2001 | + g_return_if_fail (label != NULL); |
2002 | |
2003 | - if (g_simple_action_group_lookup (app->source_actions, id)) |
2004 | + if (messaging_menu_app_lookup_source (app, id)) |
2005 | { |
2006 | g_warning ("a source with id '%s' already exists", id); |
2007 | return; |
2008 | } |
2009 | |
2010 | - action = g_simple_action_new_stateful (id, NULL, state); |
2011 | - g_signal_connect (action, "activate", |
2012 | - G_CALLBACK (source_action_activated), app); |
2013 | - g_simple_action_group_insert (app->source_actions, G_ACTION (action)); |
2014 | - g_object_unref (action); |
2015 | - |
2016 | - menuitem = g_menu_item_new (label, NULL); |
2017 | - g_menu_item_set_action_and_target_value (menuitem, id, NULL); |
2018 | - g_menu_item_set_attribute (menuitem, "x-canonical-type", "s", "ImSourceMenuItem"); |
2019 | + source = g_slice_new0 (Source); |
2020 | + source->id = g_strdup (id); |
2021 | + source->label = g_strdup (label); |
2022 | if (icon) |
2023 | - { |
2024 | - gchar *iconstr = g_icon_to_string (icon); |
2025 | - g_menu_item_set_attribute (menuitem, "x-canonical-icon", "s", iconstr); |
2026 | - g_free (iconstr); |
2027 | - } |
2028 | - g_menu_insert_item (app->menu, position, menuitem); |
2029 | - g_object_unref (menuitem); |
2030 | -} |
2031 | - |
2032 | -static GSimpleAction * |
2033 | -messaging_menu_app_get_source_action (MessagingMenuApp *app, |
2034 | - const gchar *source_id) |
2035 | - |
2036 | -{ |
2037 | - GAction *action; |
2038 | - |
2039 | - g_return_val_if_fail (MESSAGING_MENU_IS_APP (app), NULL); |
2040 | - g_return_val_if_fail (source_id != NULL, NULL); |
2041 | - |
2042 | - action = g_simple_action_group_lookup (app->source_actions, source_id); |
2043 | - if (action == NULL) |
2044 | - g_warning ("a source with id '%s' doesn't exist", source_id); |
2045 | - |
2046 | - return G_SIMPLE_ACTION (action); |
2047 | -} |
2048 | - |
2049 | -static void |
2050 | -messaging_menu_app_set_source_action (MessagingMenuApp *app, |
2051 | - const gchar *source_id, |
2052 | - guint count, |
2053 | - gint64 time, |
2054 | - const gchar *string) |
2055 | -{ |
2056 | - GSimpleAction *action; |
2057 | - GVariant *state; |
2058 | - gboolean draws_attention; |
2059 | - GVariant *new_state; |
2060 | - |
2061 | - action = messaging_menu_app_get_source_action (app, source_id); |
2062 | - if (!action) |
2063 | - return; |
2064 | - |
2065 | - state = g_action_get_state (G_ACTION (action)); |
2066 | - g_variant_get_child (state, 3, "b", &draws_attention); |
2067 | - |
2068 | - new_state = g_variant_new ("(uxsb)", count, time, string, draws_attention); |
2069 | - g_simple_action_set_state (action, new_state); |
2070 | - |
2071 | - g_variant_unref (state); |
2072 | -} |
2073 | - |
2074 | -static void |
2075 | -messaging_menu_app_set_draws_attention (MessagingMenuApp *app, |
2076 | - const gchar *source_id, |
2077 | - gboolean draws_attention) |
2078 | -{ |
2079 | - GSimpleAction *action; |
2080 | - GVariant *state; |
2081 | - guint count; |
2082 | - gint64 time; |
2083 | - const gchar *string; |
2084 | - GVariant *new_state; |
2085 | - |
2086 | - action = messaging_menu_app_get_source_action (app, source_id); |
2087 | - if (!action) |
2088 | - return; |
2089 | - |
2090 | - state = g_action_get_state (G_ACTION (action)); |
2091 | - g_variant_get (state, "(ux&sb)", &count, &time, &string, NULL); |
2092 | - |
2093 | - new_state = g_variant_new ("(uxsb)", count, time, string, draws_attention); |
2094 | - g_simple_action_set_state (action, new_state); |
2095 | - |
2096 | - g_variant_unref (state); |
2097 | + source->icon = g_object_ref (icon); |
2098 | + source->count = count; |
2099 | + source->time = time; |
2100 | + source->string = g_strdup (string); |
2101 | + app->sources = g_list_insert (app->sources, source, position); |
2102 | + |
2103 | + indicator_messages_application_emit_source_added (app->app_interface, |
2104 | + position, |
2105 | + source_to_variant (source)); |
2106 | } |
2107 | |
2108 | /** |
2109 | @@ -802,8 +949,7 @@ |
2110 | const gchar *label, |
2111 | guint count) |
2112 | { |
2113 | - messaging_menu_app_insert_source_action (app, position, id, icon, label, |
2114 | - g_variant_new ("(uxsb)", count, 0, "", FALSE)); |
2115 | + messaging_menu_app_insert_source_internal (app, position, id, icon, label, count, 0, ""); |
2116 | } |
2117 | |
2118 | /** |
2119 | @@ -857,8 +1003,7 @@ |
2120 | const gchar *label, |
2121 | gint64 time) |
2122 | { |
2123 | - messaging_menu_app_insert_source_action (app, position, id, icon, label, |
2124 | - g_variant_new ("(uxsb)", 0, time, "", FALSE)); |
2125 | + messaging_menu_app_insert_source_internal (app, position, id, icon, label, 0, time, ""); |
2126 | } |
2127 | |
2128 | /** |
2129 | @@ -914,8 +1059,7 @@ |
2130 | const gchar *label, |
2131 | const gchar *str) |
2132 | { |
2133 | - messaging_menu_app_insert_source_action (app, position, id, icon, label, |
2134 | - g_variant_new ("(uxsb)", 0, 0, str, FALSE)); |
2135 | + messaging_menu_app_insert_source_internal (app, position, id, icon, label, 0, 0, str); |
2136 | } |
2137 | |
2138 | /** |
2139 | @@ -955,34 +1099,11 @@ |
2140 | messaging_menu_app_remove_source (MessagingMenuApp *app, |
2141 | const gchar *source_id) |
2142 | { |
2143 | - int n_items; |
2144 | - int i; |
2145 | - |
2146 | g_return_if_fail (MESSAGING_MENU_IS_APP (app)); |
2147 | g_return_if_fail (source_id != NULL); |
2148 | |
2149 | - if (g_simple_action_group_lookup (app->source_actions, source_id) == NULL) |
2150 | - return; |
2151 | - |
2152 | - n_items = g_menu_model_get_n_items (G_MENU_MODEL (app->menu)); |
2153 | - for (i = 0; i < n_items; i++) |
2154 | - { |
2155 | - gchar *action; |
2156 | - |
2157 | - if (g_menu_model_get_item_attribute (G_MENU_MODEL (app->menu), i, |
2158 | - "action", "s", &action)) |
2159 | - { |
2160 | - if (!g_strcmp0 (action, source_id)) |
2161 | - { |
2162 | - g_menu_remove (app->menu, i); |
2163 | - break; |
2164 | - } |
2165 | - |
2166 | - g_free (action); |
2167 | - } |
2168 | - } |
2169 | - |
2170 | - g_simple_action_group_remove (app->source_actions, source_id); |
2171 | + if (messaging_menu_app_remove_source_internal (app, source_id)) |
2172 | + indicator_messages_application_emit_source_removed (app->app_interface, source_id); |
2173 | } |
2174 | |
2175 | /** |
2176 | @@ -999,46 +1120,7 @@ |
2177 | g_return_val_if_fail (MESSAGING_MENU_IS_APP (app), FALSE); |
2178 | g_return_val_if_fail (source_id != NULL, FALSE); |
2179 | |
2180 | - return g_simple_action_group_lookup (app->source_actions, source_id) != NULL; |
2181 | -} |
2182 | - |
2183 | -static GMenuItem * |
2184 | -g_menu_find_item_with_action (GMenu *menu, |
2185 | - const gchar *action, |
2186 | - gint *out_pos) |
2187 | -{ |
2188 | - gint i; |
2189 | - gint n_elements; |
2190 | - GMenuItem *item = NULL; |
2191 | - |
2192 | - n_elements = g_menu_model_get_n_items (G_MENU_MODEL (menu)); |
2193 | - |
2194 | - for (i = 0; i < n_elements && item == NULL; i++) |
2195 | - { |
2196 | - GVariant *attr; |
2197 | - |
2198 | - item = g_menu_item_new_from_model (G_MENU_MODEL (menu), i); |
2199 | - attr = g_menu_item_get_attribute_value (item, G_MENU_ATTRIBUTE_ACTION, G_VARIANT_TYPE_STRING); |
2200 | - |
2201 | - if (!g_str_equal (action, g_variant_get_string (attr, NULL))) |
2202 | - g_clear_object (&item); |
2203 | - |
2204 | - g_variant_unref (attr); |
2205 | - } |
2206 | - |
2207 | - if (item && out_pos) |
2208 | - *out_pos = i - 1; |
2209 | - |
2210 | - return item; |
2211 | -} |
2212 | - |
2213 | -static void |
2214 | -g_menu_replace_item (GMenu *menu, |
2215 | - gint pos, |
2216 | - GMenuItem *item) |
2217 | -{ |
2218 | - g_menu_remove (menu, pos); |
2219 | - g_menu_insert_item (menu, pos, item); |
2220 | + return messaging_menu_app_lookup_source (app, source_id) != NULL; |
2221 | } |
2222 | |
2223 | /** |
2224 | @@ -1054,21 +1136,19 @@ |
2225 | const gchar *source_id, |
2226 | const gchar *label) |
2227 | { |
2228 | - gint pos; |
2229 | - GMenuItem *item; |
2230 | + Source *source; |
2231 | |
2232 | g_return_if_fail (MESSAGING_MENU_IS_APP (app)); |
2233 | g_return_if_fail (source_id != NULL); |
2234 | g_return_if_fail (label != NULL); |
2235 | |
2236 | - item = g_menu_find_item_with_action (app->menu, source_id, &pos); |
2237 | - if (item == NULL) |
2238 | - return; |
2239 | - |
2240 | - g_menu_item_set_attribute (item, G_MENU_ATTRIBUTE_LABEL, "s", label); |
2241 | - g_menu_replace_item (app->menu, pos, item); |
2242 | - |
2243 | - g_object_unref (item); |
2244 | + source = messaging_menu_app_get_source (app, source_id); |
2245 | + if (source) |
2246 | + { |
2247 | + g_free (source->label); |
2248 | + source->label = g_strdup (label); |
2249 | + messaging_menu_app_notify_source_changed (app, source); |
2250 | + } |
2251 | } |
2252 | |
2253 | /** |
2254 | @@ -1084,33 +1164,19 @@ |
2255 | const gchar *source_id, |
2256 | GIcon *icon) |
2257 | { |
2258 | - gint pos; |
2259 | - GMenuItem *item; |
2260 | + Source *source; |
2261 | |
2262 | g_return_if_fail (MESSAGING_MENU_IS_APP (app)); |
2263 | g_return_if_fail (source_id != NULL); |
2264 | |
2265 | - item = g_menu_find_item_with_action (app->menu, source_id, &pos); |
2266 | - if (item == NULL) |
2267 | - return; |
2268 | - |
2269 | - if (icon) |
2270 | - { |
2271 | - gchar *iconstr; |
2272 | - |
2273 | - iconstr = g_icon_to_string (icon); |
2274 | - g_menu_item_set_attribute (item, "x-canonical-icon", "s", iconstr); |
2275 | - |
2276 | - g_free (iconstr); |
2277 | - } |
2278 | - else |
2279 | - { |
2280 | - g_menu_item_set_attribute_value (item, "x-canonical-icon", NULL); |
2281 | - } |
2282 | - |
2283 | - g_menu_replace_item (app->menu, pos, item); |
2284 | - |
2285 | - g_object_unref (item); |
2286 | + source = messaging_menu_app_get_source (app, source_id); |
2287 | + if (source) |
2288 | + { |
2289 | + g_clear_object (&source->icon); |
2290 | + if (icon) |
2291 | + source->icon = g_object_ref (icon); |
2292 | + messaging_menu_app_notify_source_changed (app, source); |
2293 | + } |
2294 | } |
2295 | |
2296 | /** |
2297 | @@ -1125,7 +1191,17 @@ |
2298 | const gchar *source_id, |
2299 | guint count) |
2300 | { |
2301 | - messaging_menu_app_set_source_action (app, source_id, count, 0, ""); |
2302 | + Source *source; |
2303 | + |
2304 | + g_return_if_fail (MESSAGING_MENU_IS_APP (app)); |
2305 | + g_return_if_fail (source_id != NULL); |
2306 | + |
2307 | + source = messaging_menu_app_get_source (app, source_id); |
2308 | + if (source) |
2309 | + { |
2310 | + source->count = count; |
2311 | + messaging_menu_app_notify_source_changed (app, source); |
2312 | + } |
2313 | } |
2314 | |
2315 | /** |
2316 | @@ -1141,7 +1217,17 @@ |
2317 | const gchar *source_id, |
2318 | gint64 time) |
2319 | { |
2320 | - messaging_menu_app_set_source_action (app, source_id, 0, time, ""); |
2321 | + Source *source; |
2322 | + |
2323 | + g_return_if_fail (MESSAGING_MENU_IS_APP (app)); |
2324 | + g_return_if_fail (source_id != NULL); |
2325 | + |
2326 | + source = messaging_menu_app_get_source (app, source_id); |
2327 | + if (source) |
2328 | + { |
2329 | + source->time = time; |
2330 | + messaging_menu_app_notify_source_changed (app, source); |
2331 | + } |
2332 | } |
2333 | |
2334 | /** |
2335 | @@ -1157,7 +1243,18 @@ |
2336 | const gchar *source_id, |
2337 | const gchar *str) |
2338 | { |
2339 | - messaging_menu_app_set_source_action (app, source_id, 0, 0, str); |
2340 | + Source *source; |
2341 | + |
2342 | + g_return_if_fail (MESSAGING_MENU_IS_APP (app)); |
2343 | + g_return_if_fail (source_id != NULL); |
2344 | + |
2345 | + source = messaging_menu_app_get_source (app, source_id); |
2346 | + if (source) |
2347 | + { |
2348 | + g_free (source->string); |
2349 | + source->string = g_strdup (str); |
2350 | + messaging_menu_app_notify_source_changed (app, source); |
2351 | + } |
2352 | } |
2353 | |
2354 | /** |
2355 | @@ -1175,7 +1272,17 @@ |
2356 | messaging_menu_app_draw_attention (MessagingMenuApp *app, |
2357 | const gchar *source_id) |
2358 | { |
2359 | - messaging_menu_app_set_draws_attention (app, source_id, TRUE); |
2360 | + Source *source; |
2361 | + |
2362 | + g_return_if_fail (MESSAGING_MENU_IS_APP (app)); |
2363 | + g_return_if_fail (source_id != NULL); |
2364 | + |
2365 | + source = messaging_menu_app_get_source (app, source_id); |
2366 | + if (source) |
2367 | + { |
2368 | + source->draws_attention = TRUE; |
2369 | + messaging_menu_app_notify_source_changed (app, source); |
2370 | + } |
2371 | } |
2372 | |
2373 | /** |
2374 | @@ -1196,5 +1303,131 @@ |
2375 | messaging_menu_app_remove_attention (MessagingMenuApp *app, |
2376 | const gchar *source_id) |
2377 | { |
2378 | - messaging_menu_app_set_draws_attention (app, source_id, FALSE); |
2379 | + Source *source; |
2380 | + |
2381 | + g_return_if_fail (MESSAGING_MENU_IS_APP (app)); |
2382 | + g_return_if_fail (source_id != NULL); |
2383 | + |
2384 | + source = messaging_menu_app_get_source (app, source_id); |
2385 | + if (source) |
2386 | + { |
2387 | + source->draws_attention = FALSE; |
2388 | + messaging_menu_app_notify_source_changed (app, source); |
2389 | + } |
2390 | +} |
2391 | + |
2392 | +/** |
2393 | + * messaging_menu_app_append_message: |
2394 | + * @app: a #MessagingMenuApp |
2395 | + * @msg: the #MessagingMenuMessage to append |
2396 | + * @source_id: (allow-none): the source id to which @msg is added, or NULL |
2397 | + * @notify: whether a notification bubble should be shown for this |
2398 | + * message |
2399 | + * |
2400 | + * Appends @msg to the source with id @source_id of @app. The messaging |
2401 | + * menu might not display this message immediately if other messages are |
2402 | + * queued before this one. |
2403 | + * |
2404 | + * If @source_id has a count associated with it, that count will be |
2405 | + * increased by one. |
2406 | + * |
2407 | + * If @source_id is %NULL, @msg won't be associated with a source. |
2408 | + */ |
2409 | +void |
2410 | +messaging_menu_app_append_message (MessagingMenuApp *app, |
2411 | + MessagingMenuMessage *msg, |
2412 | + const gchar *source_id, |
2413 | + gboolean notify) |
2414 | +{ |
2415 | + const gchar *id; |
2416 | + |
2417 | + g_return_if_fail (MESSAGING_MENU_IS_APP (app)); |
2418 | + g_return_if_fail (MESSAGING_MENU_IS_MESSAGE (msg)); |
2419 | + |
2420 | + id = messaging_menu_message_get_id (msg); |
2421 | + |
2422 | + if (g_hash_table_lookup (app->messages, id)) |
2423 | + { |
2424 | + g_warning ("a message with id '%s' already exists", id); |
2425 | + return; |
2426 | + } |
2427 | + |
2428 | + g_hash_table_insert (app->messages, g_strdup (id), g_object_ref (msg)); |
2429 | + indicator_messages_application_emit_message_added (app->app_interface, |
2430 | + _messaging_menu_message_to_variant (msg)); |
2431 | + |
2432 | + if (source_id) |
2433 | + { |
2434 | + Source *source; |
2435 | + |
2436 | + source = messaging_menu_app_get_source (app, source_id); |
2437 | + if (source && source->count >= 0) |
2438 | + { |
2439 | + source->count++; |
2440 | + messaging_menu_app_notify_source_changed (app, source); |
2441 | + } |
2442 | + } |
2443 | +} |
2444 | + |
2445 | +/** |
2446 | + * messaging_menu_app_get_message: |
2447 | + * @app: a #MessagingMenuApp |
2448 | + * @id: id of the message to retrieve |
2449 | + * |
2450 | + * Retrieves the message with @id, that was added with |
2451 | + * messaging_menu_app_append_message(). |
2452 | + * |
2453 | + * Returns: (transfer none) (allow-none): the #MessagingMenuApp with |
2454 | + * @id, or %NULL |
2455 | + */ |
2456 | +MessagingMenuMessage * |
2457 | +messaging_menu_app_get_message (MessagingMenuApp *app, |
2458 | + const gchar *id) |
2459 | +{ |
2460 | + g_return_val_if_fail (MESSAGING_MENU_IS_APP (app), NULL); |
2461 | + g_return_val_if_fail (id != NULL, NULL); |
2462 | + |
2463 | + return g_hash_table_lookup (app->messages, id); |
2464 | +} |
2465 | + |
2466 | +/** |
2467 | + * messaging_menu_app_remove_message: |
2468 | + * @app: a #MessagingMenuApp |
2469 | + * @msg: the #MessagingMenuMessage to remove |
2470 | + * |
2471 | + * Removes @msg from @app. |
2472 | + * |
2473 | + * If @source_id has a count associated with it, that count will be |
2474 | + * decreased by one. |
2475 | + */ |
2476 | +void |
2477 | +messaging_menu_app_remove_message (MessagingMenuApp *app, |
2478 | + MessagingMenuMessage *msg) |
2479 | +{ |
2480 | + /* take a ref of @msg here to make sure the pointer returned by |
2481 | + * _get_id() is valid for the duration of remove_message_by_id. */ |
2482 | + g_object_ref (msg); |
2483 | + messaging_menu_app_remove_message_by_id (app, messaging_menu_message_get_id (msg)); |
2484 | + g_object_unref (msg); |
2485 | +} |
2486 | + |
2487 | +/** |
2488 | + * messaging_menu_app_remove_message_by_id: |
2489 | + * @app: a #MessagingMenuApp |
2490 | + * @id: the unique id of @msg |
2491 | + * |
2492 | + * Removes the message with the id @id from @app. |
2493 | + * |
2494 | + * If @source_id has a count associated with it, that count will be |
2495 | + * decreased by one. |
2496 | + */ |
2497 | +void |
2498 | +messaging_menu_app_remove_message_by_id (MessagingMenuApp *app, |
2499 | + const gchar *id) |
2500 | +{ |
2501 | + g_return_if_fail (MESSAGING_MENU_IS_APP (app)); |
2502 | + g_return_if_fail (id != NULL); |
2503 | + |
2504 | + if (messaging_menu_app_remove_message_internal (app, id)) |
2505 | + indicator_messages_application_emit_message_removed (app->app_interface, id); |
2506 | } |
2507 | |
2508 | === renamed file 'libmessaging-menu/messaging-menu.h' => 'libmessaging-menu/messaging-menu-app.h' |
2509 | --- libmessaging-menu/messaging-menu.h 2013-08-20 08:53:01 +0000 |
2510 | +++ libmessaging-menu/messaging-menu-app.h 2013-08-21 02:09:27 +0000 |
2511 | @@ -17,10 +17,11 @@ |
2512 | * Lars Uebernickel <lars.uebernickel@canonical.com> |
2513 | */ |
2514 | |
2515 | -#ifndef __messaging_menu_h__ |
2516 | -#define __messaging_menu_h__ |
2517 | +#ifndef __messaging_menu_app_h__ |
2518 | +#define __messaging_menu_app_h__ |
2519 | |
2520 | #include <gio/gio.h> |
2521 | +#include "messaging-menu-message.h" |
2522 | |
2523 | G_BEGIN_DECLS |
2524 | |
2525 | @@ -143,6 +144,20 @@ |
2526 | void messaging_menu_app_remove_attention (MessagingMenuApp *app, |
2527 | const gchar *source_id); |
2528 | |
2529 | +void messaging_menu_app_append_message (MessagingMenuApp *app, |
2530 | + MessagingMenuMessage *msg, |
2531 | + const gchar *source_id, |
2532 | + gboolean notify); |
2533 | + |
2534 | +MessagingMenuMessage * messaging_menu_app_get_message (MessagingMenuApp *app, |
2535 | + const gchar *id); |
2536 | + |
2537 | +void messaging_menu_app_remove_message (MessagingMenuApp *app, |
2538 | + MessagingMenuMessage *msg); |
2539 | + |
2540 | +void messaging_menu_app_remove_message_by_id (MessagingMenuApp *app, |
2541 | + const gchar *id); |
2542 | + |
2543 | G_END_DECLS |
2544 | |
2545 | #endif |
2546 | |
2547 | === added file 'libmessaging-menu/messaging-menu-message.c' |
2548 | --- libmessaging-menu/messaging-menu-message.c 1970-01-01 00:00:00 +0000 |
2549 | +++ libmessaging-menu/messaging-menu-message.c 2013-08-21 02:09:27 +0000 |
2550 | @@ -0,0 +1,547 @@ |
2551 | +/* |
2552 | + * Copyright 2012 Canonical Ltd. |
2553 | + * |
2554 | + * This program is free software: you can redistribute it and/or modify it |
2555 | + * under the terms of the GNU General Public License version 3, as |
2556 | + * published by the Free Software Foundation. |
2557 | + * |
2558 | + * This program is distributed in the hope that it will be useful, but |
2559 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
2560 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
2561 | + * PURPOSE. See the GNU General Public License for more details. |
2562 | + * |
2563 | + * You should have received a copy of the GNU General Public License along |
2564 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
2565 | + * |
2566 | + * Authors: |
2567 | + * Lars Uebernickel <lars.uebernickel@canonical.com> |
2568 | + */ |
2569 | + |
2570 | +#include "messaging-menu-message.h" |
2571 | + |
2572 | +typedef GObjectClass MessagingMenuMessageClass; |
2573 | + |
2574 | +struct _MessagingMenuMessage |
2575 | +{ |
2576 | + GObject parent; |
2577 | + |
2578 | + gchar *id; |
2579 | + GIcon *icon; |
2580 | + gchar *title; |
2581 | + gchar *subtitle; |
2582 | + gchar *body; |
2583 | + gint64 time; |
2584 | + gboolean draws_attention; |
2585 | + |
2586 | + GSList *actions; |
2587 | +}; |
2588 | + |
2589 | +G_DEFINE_TYPE (MessagingMenuMessage, messaging_menu_message, G_TYPE_OBJECT); |
2590 | + |
2591 | +enum |
2592 | +{ |
2593 | + PROP_0, |
2594 | + PROP_ID, |
2595 | + PROP_ICON, |
2596 | + PROP_TITLE, |
2597 | + PROP_SUBTITLE, |
2598 | + PROP_BODY, |
2599 | + PROP_TIME, |
2600 | + PROP_DRAWS_ATTENTION, |
2601 | + NUM_PROPERTIES |
2602 | +}; |
2603 | + |
2604 | +static GParamSpec *properties[NUM_PROPERTIES]; |
2605 | + |
2606 | +typedef struct |
2607 | +{ |
2608 | + gchar *id; |
2609 | + gchar *label; |
2610 | + GVariantType *parameter_type; |
2611 | + GVariant *parameter_hint; |
2612 | +} Action; |
2613 | + |
2614 | +static void |
2615 | +action_free (gpointer data) |
2616 | +{ |
2617 | + Action *action = data; |
2618 | + |
2619 | + g_free (action->id); |
2620 | + g_free (action->label); |
2621 | + |
2622 | + if (action->parameter_type) |
2623 | + g_variant_type_free (action->parameter_type); |
2624 | + |
2625 | + if (action->parameter_hint) |
2626 | + g_variant_unref (action->parameter_hint); |
2627 | + |
2628 | + g_slice_free (Action, action); |
2629 | +} |
2630 | + |
2631 | +static void |
2632 | +messaging_menu_message_dispose (GObject *object) |
2633 | +{ |
2634 | + MessagingMenuMessage *msg = MESSAGING_MENU_MESSAGE (object); |
2635 | + |
2636 | + g_clear_object (&msg->icon); |
2637 | + |
2638 | + G_OBJECT_CLASS (messaging_menu_message_parent_class)->dispose (object); |
2639 | +} |
2640 | + |
2641 | +static void |
2642 | +messaging_menu_message_finalize (GObject *object) |
2643 | +{ |
2644 | + MessagingMenuMessage *msg = MESSAGING_MENU_MESSAGE (object); |
2645 | + |
2646 | + g_free (msg->id); |
2647 | + g_free (msg->title); |
2648 | + g_free (msg->subtitle); |
2649 | + g_free (msg->body); |
2650 | + |
2651 | + g_slist_free_full (msg->actions, action_free); |
2652 | + msg->actions = NULL; |
2653 | + |
2654 | + G_OBJECT_CLASS (messaging_menu_message_parent_class)->finalize (object); |
2655 | +} |
2656 | + |
2657 | +static void |
2658 | +messaging_menu_message_get_property (GObject *object, |
2659 | + guint property_id, |
2660 | + GValue *value, |
2661 | + GParamSpec *pspec) |
2662 | +{ |
2663 | + MessagingMenuMessage *msg = MESSAGING_MENU_MESSAGE (object); |
2664 | + |
2665 | + switch (property_id) |
2666 | + { |
2667 | + case PROP_ID: |
2668 | + g_value_set_string (value, msg->id); |
2669 | + break; |
2670 | + |
2671 | + case PROP_ICON: |
2672 | + g_value_set_object (value, msg->icon); |
2673 | + break; |
2674 | + |
2675 | + case PROP_TITLE: |
2676 | + g_value_set_string (value, msg->title); |
2677 | + break; |
2678 | + |
2679 | + case PROP_SUBTITLE: |
2680 | + g_value_set_string (value, msg->subtitle); |
2681 | + break; |
2682 | + |
2683 | + case PROP_BODY: |
2684 | + g_value_set_string (value, msg->body); |
2685 | + |
2686 | + case PROP_TIME: |
2687 | + g_value_set_int64 (value, msg->time); |
2688 | + break; |
2689 | + |
2690 | + case PROP_DRAWS_ATTENTION: |
2691 | + g_value_set_boolean (value, msg->draws_attention); |
2692 | + break; |
2693 | + |
2694 | + default: |
2695 | + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); |
2696 | + } |
2697 | +} |
2698 | + |
2699 | +static void |
2700 | +messaging_menu_message_set_property (GObject *object, |
2701 | + guint property_id, |
2702 | + const GValue *value, |
2703 | + GParamSpec *pspec) |
2704 | +{ |
2705 | + MessagingMenuMessage *msg = MESSAGING_MENU_MESSAGE (object); |
2706 | + |
2707 | + switch (property_id) |
2708 | + { |
2709 | + case PROP_ID: |
2710 | + msg->id = g_value_dup_string (value); |
2711 | + break; |
2712 | + |
2713 | + case PROP_ICON: |
2714 | + msg->icon = g_value_dup_object (value); |
2715 | + break; |
2716 | + |
2717 | + case PROP_TITLE: |
2718 | + msg->title = g_value_dup_string (value); |
2719 | + break; |
2720 | + |
2721 | + case PROP_SUBTITLE: |
2722 | + msg->subtitle = g_value_dup_string (value); |
2723 | + break; |
2724 | + |
2725 | + case PROP_BODY: |
2726 | + msg->body = g_value_dup_string (value); |
2727 | + |
2728 | + case PROP_TIME: |
2729 | + msg->time = g_value_get_int64 (value); |
2730 | + break; |
2731 | + |
2732 | + case PROP_DRAWS_ATTENTION: |
2733 | + messaging_menu_message_set_draws_attention (msg, g_value_get_boolean (value)); |
2734 | + break; |
2735 | + |
2736 | + default: |
2737 | + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); |
2738 | + } |
2739 | +} |
2740 | + |
2741 | +static void |
2742 | +messaging_menu_message_class_init (MessagingMenuMessageClass *klass) |
2743 | +{ |
2744 | + GObjectClass *object_class = G_OBJECT_CLASS (klass); |
2745 | + |
2746 | + object_class->dispose = messaging_menu_message_dispose; |
2747 | + object_class->finalize = messaging_menu_message_finalize; |
2748 | + object_class->get_property = messaging_menu_message_get_property; |
2749 | + object_class->set_property = messaging_menu_message_set_property; |
2750 | + |
2751 | + properties[PROP_ID] = g_param_spec_string ("id", "Id", |
2752 | + "Unique id of the message", |
2753 | + NULL, |
2754 | + G_PARAM_CONSTRUCT_ONLY | |
2755 | + G_PARAM_READWRITE | |
2756 | + G_PARAM_STATIC_STRINGS); |
2757 | + |
2758 | + properties[PROP_ICON] = g_param_spec_object ("icon", "Icon", |
2759 | + "Icon of the message", |
2760 | + G_TYPE_ICON, |
2761 | + G_PARAM_CONSTRUCT_ONLY | |
2762 | + G_PARAM_READWRITE | |
2763 | + G_PARAM_STATIC_STRINGS); |
2764 | + |
2765 | + properties[PROP_TITLE] = g_param_spec_string ("title", "Title", |
2766 | + "Title of the message", |
2767 | + NULL, |
2768 | + G_PARAM_CONSTRUCT_ONLY | |
2769 | + G_PARAM_READWRITE | |
2770 | + G_PARAM_STATIC_STRINGS); |
2771 | + |
2772 | + properties[PROP_SUBTITLE] = g_param_spec_string ("subtitle", "Subtitle", |
2773 | + "Subtitle of the message", |
2774 | + NULL, |
2775 | + G_PARAM_CONSTRUCT_ONLY | |
2776 | + G_PARAM_READWRITE | |
2777 | + G_PARAM_STATIC_STRINGS); |
2778 | + |
2779 | + properties[PROP_BODY] = g_param_spec_string ("body", "Body", |
2780 | + "First lines of the body of the message", |
2781 | + NULL, |
2782 | + G_PARAM_CONSTRUCT_ONLY | |
2783 | + G_PARAM_READWRITE | |
2784 | + G_PARAM_STATIC_STRINGS); |
2785 | + |
2786 | + properties[PROP_TIME] = g_param_spec_int64 ("time", "Time", |
2787 | + "Time the message was sent, in microseconds", 0, G_MAXINT64, 0, |
2788 | + G_PARAM_CONSTRUCT_ONLY | |
2789 | + G_PARAM_READWRITE | |
2790 | + G_PARAM_STATIC_STRINGS); |
2791 | + |
2792 | + properties[PROP_DRAWS_ATTENTION] = g_param_spec_boolean ("draws-attention", "Draws attention", |
2793 | + "Whether the message should draw attention", |
2794 | + FALSE, |
2795 | + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); |
2796 | + |
2797 | + g_object_class_install_properties (klass, NUM_PROPERTIES, properties); |
2798 | + |
2799 | + /** |
2800 | + * MessagingMenuMessage::activate: |
2801 | + * @msg: the #MessagingMenuMessage |
2802 | + * @action: (allow-none): the id of activated action, or %NULL |
2803 | + * @parameter: (allow-none): activation parameter, or %NULL |
2804 | + * |
2805 | + * Emitted when the user has activated the message. The message is |
2806 | + * immediately removed from the application's menu, handlers of this |
2807 | + * signal do not need to call messaging_menu_app_remove_message(). |
2808 | + */ |
2809 | + g_signal_new ("activate", |
2810 | + MESSAGING_MENU_TYPE_MESSAGE, |
2811 | + G_SIGNAL_RUN_FIRST | G_SIGNAL_DETAILED, |
2812 | + 0, |
2813 | + NULL, NULL, |
2814 | + g_cclosure_marshal_generic, |
2815 | + G_TYPE_NONE, 2, |
2816 | + G_TYPE_STRING, |
2817 | + G_TYPE_VARIANT); |
2818 | +} |
2819 | + |
2820 | +static void |
2821 | +messaging_menu_message_init (MessagingMenuMessage *self) |
2822 | +{ |
2823 | +} |
2824 | + |
2825 | +/** |
2826 | + * messaging_menu_message_new: |
2827 | + * @id: unique id of the message |
2828 | + * @icon: (transfer full) (allow-none): a #GIcon representing the message |
2829 | + * @title: the title of the message |
2830 | + * @subtitle: (allow-none): the subtitle of the message |
2831 | + * @body: (allow-none): the message body |
2832 | + * @time: the time the message was received |
2833 | + * |
2834 | + * Creates a new #MessagingMenuMessage. |
2835 | + * |
2836 | + * Returns: (transfer full): a new #MessagingMenuMessage |
2837 | + */ |
2838 | +MessagingMenuMessage * |
2839 | +messaging_menu_message_new (const gchar *id, |
2840 | + GIcon *icon, |
2841 | + const gchar *title, |
2842 | + const gchar *subtitle, |
2843 | + const gchar *body, |
2844 | + gint64 time) |
2845 | +{ |
2846 | + g_return_val_if_fail (id != NULL, NULL); |
2847 | + g_return_val_if_fail (title != NULL, NULL); |
2848 | + |
2849 | + return g_object_new (MESSAGING_MENU_TYPE_MESSAGE, |
2850 | + "id", id, |
2851 | + "icon", icon, |
2852 | + "title", title, |
2853 | + "subtitle", subtitle, |
2854 | + "body", body, |
2855 | + "time", time, |
2856 | + NULL); |
2857 | +} |
2858 | + |
2859 | +/** |
2860 | + * messaging_menu_message_get_id: |
2861 | + * @msg: a #MessagingMenuMessage |
2862 | + * |
2863 | + * Returns: the unique id of @msg |
2864 | + */ |
2865 | +const gchar * |
2866 | +messaging_menu_message_get_id (MessagingMenuMessage *msg) |
2867 | +{ |
2868 | + g_return_val_if_fail (MESSAGING_MENU_IS_MESSAGE (msg), NULL); |
2869 | + |
2870 | + return msg->id; |
2871 | +} |
2872 | + |
2873 | +/** |
2874 | + * messaging_menu_message_get_icon: |
2875 | + * @msg: a #MessagingMenuMessage |
2876 | + * |
2877 | + * Returns: (transfer none): the icon of @msg |
2878 | + */ |
2879 | +GIcon * |
2880 | +messaging_menu_message_get_icon (MessagingMenuMessage *msg) |
2881 | +{ |
2882 | + g_return_val_if_fail (MESSAGING_MENU_IS_MESSAGE (msg), NULL); |
2883 | + |
2884 | + return msg->icon; |
2885 | +} |
2886 | + |
2887 | +/** |
2888 | + * messaging_menu_message_get_title: |
2889 | + * @msg: a #MessagingMenuMessage |
2890 | + * |
2891 | + * Returns: the title of @msg |
2892 | + */ |
2893 | +const gchar * |
2894 | +messaging_menu_message_get_title (MessagingMenuMessage *msg) |
2895 | +{ |
2896 | + g_return_val_if_fail (MESSAGING_MENU_IS_MESSAGE (msg), NULL); |
2897 | + |
2898 | + return msg->title; |
2899 | +} |
2900 | + |
2901 | +/** |
2902 | + * messaging_menu_message_get_subtitle: |
2903 | + * @msg: a #MessagingMenuMessage |
2904 | + * |
2905 | + * Returns: the subtitle of @msg |
2906 | + */ |
2907 | +const gchar * |
2908 | +messaging_menu_message_get_subtitle (MessagingMenuMessage *msg) |
2909 | +{ |
2910 | + g_return_val_if_fail (MESSAGING_MENU_IS_MESSAGE (msg), NULL); |
2911 | + |
2912 | + return msg->subtitle; |
2913 | +} |
2914 | + |
2915 | +/** |
2916 | + * messaging_menu_message_get_body: |
2917 | + * @msg: a #MessagingMenuMessage |
2918 | + * |
2919 | + * Returns: the body of @msg |
2920 | + */ |
2921 | +const gchar * |
2922 | +messaging_menu_message_get_body (MessagingMenuMessage *msg) |
2923 | +{ |
2924 | + g_return_val_if_fail (MESSAGING_MENU_IS_MESSAGE (msg), NULL); |
2925 | + |
2926 | + return msg->body; |
2927 | +} |
2928 | + |
2929 | +/** |
2930 | + * messaging_menu_message_get_time: |
2931 | + * @msg: a #MessagingMenuMessage |
2932 | + * |
2933 | + * Returns: the time at which @msg was received |
2934 | + */ |
2935 | +gint64 |
2936 | +messaging_menu_message_get_time (MessagingMenuMessage *msg) |
2937 | +{ |
2938 | + g_return_val_if_fail (MESSAGING_MENU_IS_MESSAGE (msg), 0); |
2939 | + |
2940 | + return msg->time; |
2941 | +} |
2942 | + |
2943 | +/** |
2944 | + * messaging_menu_message_get_draws_attention: |
2945 | + * @msg: a #MessagingMenuMessage |
2946 | + * |
2947 | + * Returns: whether @msg is drawing attention |
2948 | + */ |
2949 | +gboolean |
2950 | +messaging_menu_message_get_draws_attention (MessagingMenuMessage *msg) |
2951 | +{ |
2952 | + g_return_val_if_fail (MESSAGING_MENU_IS_MESSAGE (msg), FALSE); |
2953 | + |
2954 | + return msg->draws_attention; |
2955 | +} |
2956 | + |
2957 | +/** |
2958 | + * messaging_menu_message_set_draws_attention: |
2959 | + * @msg: a #MessagingMenuMessage |
2960 | + * @draws_attention: whether @msg should draw attention |
2961 | + * |
2962 | + * Sets whether @msg is drawing attention. |
2963 | + */ |
2964 | +void |
2965 | +messaging_menu_message_set_draws_attention (MessagingMenuMessage *msg, |
2966 | + gboolean draws_attention) |
2967 | +{ |
2968 | + g_return_if_fail (MESSAGING_MENU_IS_MESSAGE (msg)); |
2969 | + |
2970 | + msg->draws_attention = draws_attention; |
2971 | + g_object_notify_by_pspec (G_OBJECT (msg), properties[PROP_DRAWS_ATTENTION]); |
2972 | +} |
2973 | + |
2974 | +/** |
2975 | + * messaging_menu_message_add_action: |
2976 | + * @msg: a #MessagingMenuMessage |
2977 | + * @id: unique id of the action |
2978 | + * @label: (allow-none): label of the action |
2979 | + * @parameter_type: (allow-none): a #GVariantType |
2980 | + * @parameter_hint: (allow-none): a #GVariant suggesting a valid range |
2981 | + * for parameters |
2982 | + * |
2983 | + * Adds an action with @id and @label to @message. Actions are an |
2984 | + * alternative way for users to activate a message. Note that messages |
2985 | + * can still be activated without an action. |
2986 | + * |
2987 | + * If @parameter_type is non-%NULL, the action is able to receive user |
2988 | + * input in addition to simply activating the action. Currently, only |
2989 | + * string parameters are supported. |
2990 | + * |
2991 | + * A list of predefined parameters can be supplied as a #GVariant array |
2992 | + * of @parameter_type in @parameter_hint. If @parameter_hint is |
2993 | + * floating, it will be consumed. |
2994 | + * |
2995 | + * It is recommended to add at most two actions to a message. |
2996 | + */ |
2997 | +void |
2998 | +messaging_menu_message_add_action (MessagingMenuMessage *msg, |
2999 | + const gchar *id, |
3000 | + const gchar *label, |
3001 | + const GVariantType *parameter_type, |
3002 | + GVariant *parameter_hint) |
3003 | +{ |
3004 | + Action *action; |
3005 | + |
3006 | + g_return_if_fail (MESSAGING_MENU_IS_MESSAGE (msg)); |
3007 | + g_return_if_fail (id != NULL); |
3008 | + |
3009 | + action = g_slice_new (Action); |
3010 | + action->id = g_strdup (id); |
3011 | + action->label = g_strdup (label); |
3012 | + action->parameter_type = parameter_type ? g_variant_type_copy (parameter_type) : NULL; |
3013 | + action->parameter_hint = parameter_hint ? g_variant_ref_sink (parameter_hint) : NULL; |
3014 | + |
3015 | + msg->actions = g_slist_append (msg->actions, action); |
3016 | +} |
3017 | + |
3018 | +static GVariant * |
3019 | +action_to_variant (Action *action) |
3020 | +{ |
3021 | + GVariantBuilder builder; |
3022 | + |
3023 | + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}")); |
3024 | + |
3025 | + g_variant_builder_add (&builder, "{sv}", "name", g_variant_new_string (action->id)); |
3026 | + |
3027 | + if (action->label) |
3028 | + g_variant_builder_add (&builder, "{sv}", "label", g_variant_new_string (action->label)); |
3029 | + |
3030 | + if (action->parameter_type) |
3031 | + { |
3032 | + gchar *type = g_variant_type_dup_string (action->parameter_type); |
3033 | + g_variant_builder_add (&builder, "{sv}", "parameter-type", g_variant_new_signature (type)); |
3034 | + g_free (type); |
3035 | + } |
3036 | + |
3037 | + if (action->parameter_hint) |
3038 | + g_variant_builder_add (&builder, "{sv}", "parameter-hint", action->parameter_hint); |
3039 | + |
3040 | + return g_variant_builder_end (&builder); |
3041 | +} |
3042 | + |
3043 | +/*<internal> |
3044 | + * _messaging_menu_message_to_variant: |
3045 | + * @msg: a #MessagingMenuMessage |
3046 | + * |
3047 | + * Serializes @msg to a #GVariant of the form (sssssxaa{sv}b): |
3048 | + * |
3049 | + * id |
3050 | + * icon |
3051 | + * title |
3052 | + * subtitle |
3053 | + * body |
3054 | + * time |
3055 | + * array of action dictionaries |
3056 | + * draws_attention |
3057 | + * |
3058 | + * Returns: a new floating #GVariant instance |
3059 | + */ |
3060 | +GVariant * |
3061 | +_messaging_menu_message_to_variant (MessagingMenuMessage *msg) |
3062 | +{ |
3063 | + GVariantBuilder builder; |
3064 | + GSList *it; |
3065 | + |
3066 | + g_return_val_if_fail (MESSAGING_MENU_IS_MESSAGE (msg), NULL); |
3067 | + |
3068 | + g_variant_builder_init (&builder, G_VARIANT_TYPE ("(sssssxaa{sv}b)")); |
3069 | + |
3070 | + g_variant_builder_add (&builder, "s", msg->id); |
3071 | + |
3072 | + if (msg->icon) |
3073 | + { |
3074 | + gchar *iconstr; |
3075 | + |
3076 | + iconstr = g_icon_to_string (msg->icon); |
3077 | + g_variant_builder_add (&builder, "s", iconstr); |
3078 | + |
3079 | + g_free (iconstr); |
3080 | + } |
3081 | + else |
3082 | + g_variant_builder_add (&builder, "s", ""); |
3083 | + |
3084 | + g_variant_builder_add (&builder, "s", msg->title ? msg->title : ""); |
3085 | + g_variant_builder_add (&builder, "s", msg->subtitle ? msg->subtitle : ""); |
3086 | + g_variant_builder_add (&builder, "s", msg->body ? msg->body : ""); |
3087 | + g_variant_builder_add (&builder, "x", msg->time); |
3088 | + |
3089 | + g_variant_builder_open (&builder, G_VARIANT_TYPE ("aa{sv}")); |
3090 | + for (it = msg->actions; it; it = it->next) |
3091 | + g_variant_builder_add_value (&builder, action_to_variant (it->data)); |
3092 | + g_variant_builder_close (&builder); |
3093 | + |
3094 | + g_variant_builder_add (&builder, "b", msg->draws_attention); |
3095 | + |
3096 | + return g_variant_builder_end (&builder); |
3097 | +} |
3098 | |
3099 | === added file 'libmessaging-menu/messaging-menu-message.h' |
3100 | --- libmessaging-menu/messaging-menu-message.h 1970-01-01 00:00:00 +0000 |
3101 | +++ libmessaging-menu/messaging-menu-message.h 2013-08-21 02:09:27 +0000 |
3102 | @@ -0,0 +1,70 @@ |
3103 | +/* |
3104 | + * Copyright 2012 Canonical Ltd. |
3105 | + * |
3106 | + * This program is free software: you can redistribute it and/or modify it |
3107 | + * under the terms of the GNU General Public License version 3, as |
3108 | + * published by the Free Software Foundation. |
3109 | + * |
3110 | + * This program is distributed in the hope that it will be useful, but |
3111 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
3112 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
3113 | + * PURPOSE. See the GNU General Public License for more details. |
3114 | + * |
3115 | + * You should have received a copy of the GNU General Public License along |
3116 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
3117 | + * |
3118 | + * Authors: |
3119 | + * Lars Uebernickel <lars.uebernickel@canonical.com> |
3120 | + */ |
3121 | + |
3122 | +#ifndef __messaging_menu_message_h__ |
3123 | +#define __messaging_menu_message_h__ |
3124 | + |
3125 | +#include <gio/gio.h> |
3126 | + |
3127 | +G_BEGIN_DECLS |
3128 | + |
3129 | +#define MESSAGING_MENU_TYPE_MESSAGE (messaging_menu_message_get_type ()) |
3130 | +#define MESSAGING_MENU_MESSAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MESSAGING_MENU_TYPE_MESSAGE, MessagingMenuMessage)) |
3131 | +#define MESSAGING_MENU_MESSAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MESSAGING_MENU_TYPE_MESSAGE, MessagingMenuMessageClass)) |
3132 | +#define MESSAGING_MENU_IS_MESSAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MESSAGING_MENU_TYPE_MESSAGE)) |
3133 | +#define MESSAGING_MENU_IS_MESSAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MESSAGING_MENU_TYPE_MESSAGE)) |
3134 | +#define MESSAGING_MENU_MESSAGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MESSAGING_MENU_TYPE_MESSAGE, MessagingMenuMessageClass)) |
3135 | + |
3136 | +typedef struct _MessagingMenuMessage MessagingMenuMessage; |
3137 | + |
3138 | +GType messaging_menu_message_get_type (void) G_GNUC_CONST; |
3139 | + |
3140 | +MessagingMenuMessage * messaging_menu_message_new (const gchar *id, |
3141 | + GIcon *icon, |
3142 | + const gchar *title, |
3143 | + const gchar *subtitle, |
3144 | + const gchar *body, |
3145 | + gint64 time); |
3146 | + |
3147 | +const gchar * messaging_menu_message_get_id (MessagingMenuMessage *msg); |
3148 | + |
3149 | +GIcon * messaging_menu_message_get_icon (MessagingMenuMessage *msg); |
3150 | + |
3151 | +const gchar * messaging_menu_message_get_title (MessagingMenuMessage *msg); |
3152 | + |
3153 | +const gchar * messaging_menu_message_get_subtitle (MessagingMenuMessage *msg); |
3154 | + |
3155 | +const gchar * messaging_menu_message_get_body (MessagingMenuMessage *msg); |
3156 | + |
3157 | +gint64 messaging_menu_message_get_time (MessagingMenuMessage *msg); |
3158 | + |
3159 | +gboolean messaging_menu_message_get_draws_attention (MessagingMenuMessage *msg); |
3160 | + |
3161 | +void messaging_menu_message_set_draws_attention (MessagingMenuMessage *msg, |
3162 | + gboolean draws_attention); |
3163 | + |
3164 | +void messaging_menu_message_add_action (MessagingMenuMessage *msg, |
3165 | + const gchar *id, |
3166 | + const gchar *label, |
3167 | + const GVariantType *parameter_type, |
3168 | + GVariant *parameter_hint); |
3169 | + |
3170 | +G_END_DECLS |
3171 | + |
3172 | +#endif |
3173 | |
3174 | === added file 'libmessaging-menu/messaging-menu.h' |
3175 | --- libmessaging-menu/messaging-menu.h 1970-01-01 00:00:00 +0000 |
3176 | +++ libmessaging-menu/messaging-menu.h 2013-08-21 02:09:27 +0000 |
3177 | @@ -0,0 +1,25 @@ |
3178 | +/* |
3179 | + * Copyright 2012 Canonical Ltd. |
3180 | + * |
3181 | + * This program is free software: you can redistribute it and/or modify it |
3182 | + * under the terms of the GNU General Public License version 3, as |
3183 | + * published by the Free Software Foundation. |
3184 | + * |
3185 | + * This program is distributed in the hope that it will be useful, but |
3186 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
3187 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
3188 | + * PURPOSE. See the GNU General Public License for more details. |
3189 | + * |
3190 | + * You should have received a copy of the GNU General Public License along |
3191 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
3192 | + * |
3193 | + * Authors: |
3194 | + * Lars Uebernickel <lars.uebernickel@canonical.com> |
3195 | + */ |
3196 | + |
3197 | +#ifndef __messaging_menu_h__ |
3198 | +#define __messaging_menu_h__ |
3199 | + |
3200 | +#include "messaging-menu-app.h" |
3201 | + |
3202 | +#endif |
3203 | |
3204 | === modified file 'po/POTFILES.in' |
3205 | --- po/POTFILES.in 2013-08-20 08:53:01 +0000 |
3206 | +++ po/POTFILES.in 2013-08-21 02:09:27 +0000 |
3207 | @@ -1,3 +1,15 @@ |
3208 | [encoding: UTF-8] |
3209 | -src/indicator-messages.c |
3210 | +common/indicator-messages-service.c |
3211 | +common/indicator-messages-application.c |
3212 | +test/indicator-messages-service-activate.c |
3213 | +src/im-phone-menu.c |
3214 | +src/app-section.c |
3215 | src/messages-service.c |
3216 | +src/im-desktop-menu.c |
3217 | +src/im-menu.c |
3218 | +src/im-application-list.c |
3219 | +src/gsettingsstrv.c |
3220 | +src/gmenuutils.c |
3221 | +src/gactionmuxer.c |
3222 | +libmessaging-menu/messaging-menu-message.c |
3223 | +libmessaging-menu/messaging-menu-app.c |
3224 | |
3225 | === removed file 'po/indicator-messages.pot' |
3226 | --- po/indicator-messages.pot 2013-08-20 08:53:01 +0000 |
3227 | +++ po/indicator-messages.pot 1970-01-01 00:00:00 +0000 |
3228 | @@ -1,46 +0,0 @@ |
3229 | -# SOME DESCRIPTIVE TITLE. |
3230 | -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
3231 | -# This file is distributed under the same license as the PACKAGE package. |
3232 | -# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. |
3233 | -# |
3234 | -#, fuzzy |
3235 | -msgid "" |
3236 | -msgstr "" |
3237 | -"Project-Id-Version: PACKAGE VERSION\n" |
3238 | -"Report-Msgid-Bugs-To: \n" |
3239 | -"POT-Creation-Date: 2012-11-16 14:53+0100\n" |
3240 | -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" |
3241 | -"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" |
3242 | -"Language-Team: LANGUAGE <LL@li.org>\n" |
3243 | -"Language: \n" |
3244 | -"MIME-Version: 1.0\n" |
3245 | -"Content-Type: text/plain; charset=CHARSET\n" |
3246 | -"Content-Transfer-Encoding: 8bit\n" |
3247 | - |
3248 | -#: ../src/messages-service.c:329 |
3249 | -msgid "Messages" |
3250 | -msgstr "" |
3251 | - |
3252 | -#: ../src/messages-service.c:552 |
3253 | -msgid "Available" |
3254 | -msgstr "" |
3255 | - |
3256 | -#: ../src/messages-service.c:553 |
3257 | -msgid "Away" |
3258 | -msgstr "" |
3259 | - |
3260 | -#: ../src/messages-service.c:554 |
3261 | -msgid "Busy" |
3262 | -msgstr "" |
3263 | - |
3264 | -#: ../src/messages-service.c:555 |
3265 | -msgid "Invisible" |
3266 | -msgstr "" |
3267 | - |
3268 | -#: ../src/messages-service.c:556 |
3269 | -msgid "Offline" |
3270 | -msgstr "" |
3271 | - |
3272 | -#: ../src/messages-service.c:659 |
3273 | -msgid "Clear" |
3274 | -msgstr "" |
3275 | |
3276 | === modified file 'src/Makefile.am' |
3277 | --- src/Makefile.am 2013-08-20 08:53:01 +0000 |
3278 | +++ src/Makefile.am 2013-08-21 02:09:27 +0000 |
3279 | @@ -1,53 +1,10 @@ |
3280 | |
3281 | -BUILT_SOURCES = |
3282 | EXTRA_DIST = |
3283 | -CLEANFILES = |
3284 | -DISTCLEANFILES = |
3285 | |
3286 | libexec_PROGRAMS = indicator-messages-service |
3287 | |
3288 | - |
3289 | -###################################### |
3290 | -# Building the messages indicator |
3291 | -###################################### |
3292 | - |
3293 | -messaginglibdir = $(INDICATORDIR) |
3294 | -messaginglib_LTLIBRARIES = libmessaging.la |
3295 | -libmessaging_la_SOURCES = \ |
3296 | - indicator-messages.c \ |
3297 | - ido-menu-item.c \ |
3298 | - ido-menu-item.h \ |
3299 | - im-app-menu-item.c \ |
3300 | - im-app-menu-item.h \ |
3301 | - im-source-menu-item.c \ |
3302 | - im-source-menu-item.h \ |
3303 | - ido-detail-label.c \ |
3304 | - ido-detail-label.h \ |
3305 | - indicator-messages-service.c \ |
3306 | - indicator-messages-service.h |
3307 | - dbus-data.h |
3308 | -libmessaging_la_CFLAGS = \ |
3309 | - $(APPLET_CFLAGS) \ |
3310 | - $(COVERAGE_CFLAGS) \ |
3311 | - -Wall \ |
3312 | - -Wl,-Bsymbolic-functions \ |
3313 | - -Wl,-z,defs \ |
3314 | - -Wl,--as-needed \ |
3315 | - -Werror \ |
3316 | - -DG_LOG_DOMAIN=\"Indicator-Messages\" |
3317 | -libmessaging_la_LIBADD = $(APPLET_LIBS) -lm |
3318 | -libmessaging_la_LDFLAGS = \ |
3319 | - $(COVERAGE_LDFLAGS) \ |
3320 | - -module -avoid-version |
3321 | - |
3322 | -###################################### |
3323 | -# Building the messages service |
3324 | -###################################### |
3325 | - |
3326 | indicator_messages_service_SOURCES = \ |
3327 | messages-service.c \ |
3328 | - indicator-messages-service.c \ |
3329 | - indicator-messages-service.h \ |
3330 | app-section.c \ |
3331 | app-section.h \ |
3332 | dbus-data.h \ |
3333 | @@ -56,11 +13,22 @@ |
3334 | gsettingsstrv.c \ |
3335 | gsettingsstrv.h \ |
3336 | gmenuutils.c \ |
3337 | - gmenuutils.h |
3338 | + gmenuutils.h \ |
3339 | + im-menu.c \ |
3340 | + im-menu.h \ |
3341 | + im-phone-menu.c \ |
3342 | + im-phone-menu.h \ |
3343 | + im-desktop-menu.c \ |
3344 | + im-desktop-menu.h \ |
3345 | + im-application-list.c \ |
3346 | + im-application-list.h \ |
3347 | + indicator-desktop-shortcuts.c \ |
3348 | + indicator-desktop-shortcuts.h |
3349 | |
3350 | indicator_messages_service_CFLAGS = \ |
3351 | $(APPLET_CFLAGS) \ |
3352 | $(COVERAGE_CFLAGS) \ |
3353 | + -I$(top_builddir)/common \ |
3354 | -Wall \ |
3355 | -Wl,-Bsymbolic-functions \ |
3356 | -Wl,-z,defs \ |
3357 | @@ -69,26 +37,11 @@ |
3358 | -DG_LOG_DOMAIN=\"Indicator-Messages\" |
3359 | |
3360 | indicator_messages_service_LDADD = \ |
3361 | + $(top_builddir)/common/libmessaging-common.la \ |
3362 | $(APPLET_LIBS) |
3363 | |
3364 | indicator_messages_service_LDFLAGS = \ |
3365 | $(COVERAGE_LDFLAGS) |
3366 | |
3367 | -indicator-messages-service.c: $(top_srcdir)/src/messages-service.xml |
3368 | - $(AM_V_GEN) gdbus-codegen \ |
3369 | - --interface-prefix com.canonical.indicator.messages. \ |
3370 | - --generate-c-code indicator-messages-service \ |
3371 | - --c-namespace IndicatorMessages \ |
3372 | - $^ |
3373 | -indicator-messages-service.h: indicator-messages-service.c |
3374 | - |
3375 | -BUILT_SOURCES += \ |
3376 | - indicator-messages-service.c \ |
3377 | - indicator-messages-service.h |
3378 | - |
3379 | EXTRA_DIST += \ |
3380 | messages-service.xml |
3381 | - |
3382 | -CLEANFILES += \ |
3383 | - $(BUILT_SOURCES) |
3384 | - |
3385 | |
3386 | === modified file 'src/app-section.c' |
3387 | --- src/app-section.c 2013-08-20 08:53:01 +0000 |
3388 | +++ src/app-section.c 2013-08-21 02:09:27 +0000 |
3389 | @@ -34,6 +34,7 @@ |
3390 | #include "dbus-data.h" |
3391 | #include "gmenuutils.h" |
3392 | #include "gactionmuxer.h" |
3393 | +#include "indicator-messages-application.h" |
3394 | |
3395 | struct _AppSectionPrivate |
3396 | { |
3397 | @@ -42,11 +43,14 @@ |
3398 | |
3399 | IndicatorDesktopShortcuts * ids; |
3400 | |
3401 | + GCancellable *app_proxy_cancellable; |
3402 | + IndicatorMessagesApplication *app_proxy; |
3403 | + |
3404 | GMenu *menu; |
3405 | - GMenuModel *source_menu; |
3406 | + GMenu *source_menu; |
3407 | |
3408 | GSimpleActionGroup *static_shortcuts; |
3409 | - GActionGroup *source_actions; |
3410 | + GSimpleActionGroup *source_actions; |
3411 | GActionMuxer *muxer; |
3412 | |
3413 | gboolean draws_attention; |
3414 | @@ -90,19 +94,6 @@ |
3415 | gpointer user_data); |
3416 | static void app_section_set_app_info (AppSection *self, |
3417 | GDesktopAppInfo *appinfo); |
3418 | -static gboolean any_action_draws_attention (GActionGroup *group, |
3419 | - const gchar *ignored_action); |
3420 | -static void action_added (GActionGroup *group, |
3421 | - const gchar *action_name, |
3422 | - gpointer user_data); |
3423 | -static void action_state_changed (GActionGroup *group, |
3424 | - const gchar *action_name, |
3425 | - GVariant *value, |
3426 | - gpointer user_data); |
3427 | -static void action_removed (GActionGroup *group, |
3428 | - const gchar *action_name, |
3429 | - gpointer user_data); |
3430 | -static gboolean action_draws_attention (GVariant *state); |
3431 | static void desktop_file_changed_cb (GFileMonitor *monitor, |
3432 | GFile *file, |
3433 | GFile *other_file, |
3434 | @@ -170,6 +161,7 @@ |
3435 | app_section_init (AppSection *self) |
3436 | { |
3437 | AppSectionPrivate *priv; |
3438 | + GMenuItem *item; |
3439 | |
3440 | self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, |
3441 | APP_SECTION_TYPE, |
3442 | @@ -179,10 +171,19 @@ |
3443 | priv->appinfo = NULL; |
3444 | |
3445 | priv->menu = g_menu_new (); |
3446 | + |
3447 | + priv->source_menu = g_menu_new (); |
3448 | + item = g_menu_item_new_section (NULL, G_MENU_MODEL (priv->source_menu)); |
3449 | + g_menu_item_set_attribute (item, "action-namespace", "s", "source"); |
3450 | + g_menu_append_item (priv->menu, item); |
3451 | + g_object_unref (item); |
3452 | + |
3453 | priv->static_shortcuts = g_simple_action_group_new (); |
3454 | + priv->source_actions = g_simple_action_group_new (); |
3455 | |
3456 | priv->muxer = g_action_muxer_new (); |
3457 | g_action_muxer_insert (priv->muxer, NULL, G_ACTION_GROUP (priv->static_shortcuts)); |
3458 | + g_action_muxer_insert (priv->muxer, "source", G_ACTION_GROUP (priv->source_actions)); |
3459 | |
3460 | priv->draws_attention = FALSE; |
3461 | |
3462 | @@ -249,32 +250,30 @@ |
3463 | AppSection * self = APP_SECTION(object); |
3464 | AppSectionPrivate * priv = self->priv; |
3465 | |
3466 | + if (priv->app_proxy_cancellable) { |
3467 | + g_cancellable_cancel (priv->app_proxy_cancellable); |
3468 | + g_clear_object (&priv->app_proxy_cancellable); |
3469 | + } |
3470 | + |
3471 | if (priv->desktop_file_monitor) { |
3472 | g_signal_handlers_disconnect_by_func (priv->desktop_file_monitor, desktop_file_changed_cb, self); |
3473 | g_clear_object (&priv->desktop_file_monitor); |
3474 | } |
3475 | |
3476 | + g_clear_object (&priv->app_proxy); |
3477 | + |
3478 | g_clear_object (&priv->menu); |
3479 | + g_clear_object (&priv->source_menu); |
3480 | g_clear_object (&priv->static_shortcuts); |
3481 | + g_clear_object (&priv->source_actions); |
3482 | |
3483 | if (priv->name_watch_id) { |
3484 | g_bus_unwatch_name (priv->name_watch_id); |
3485 | priv->name_watch_id = 0; |
3486 | } |
3487 | |
3488 | - if (priv->source_actions) { |
3489 | - g_action_muxer_remove (priv->muxer, "source"); |
3490 | - g_object_disconnect (priv->source_actions, |
3491 | - "any_signal::action-added", action_added, self, |
3492 | - "any_signal::action-state-changed", action_state_changed, self, |
3493 | - "any_signal::action-removed", action_removed, self, |
3494 | - NULL); |
3495 | - g_clear_object (&priv->source_actions); |
3496 | - } |
3497 | - |
3498 | g_clear_object (&priv->muxer); |
3499 | |
3500 | - g_clear_object (&priv->source_menu); |
3501 | g_clear_object (&priv->ids); |
3502 | g_clear_object (&priv->appinfo); |
3503 | |
3504 | @@ -314,14 +313,12 @@ |
3505 | |
3506 | g_return_if_fail(priv->ids != NULL); |
3507 | |
3508 | - GAppLaunchContext *context = get_launch_context (g_variant_get_uint32 (param)); |
3509 | - |
3510 | - if (!indicator_desktop_shortcuts_nick_exec_with_context(priv->ids, nick, context)) { |
3511 | + if (!indicator_desktop_shortcuts_nick_exec_with_context(priv->ids, nick, NULL)) { |
3512 | g_warning("Unable to execute nick '%s' for desktop file '%s'", |
3513 | nick, g_desktop_app_info_get_filename (priv->appinfo)); |
3514 | } |
3515 | |
3516 | - g_object_unref (context); |
3517 | + return; |
3518 | } |
3519 | |
3520 | static void |
3521 | @@ -414,7 +411,9 @@ |
3522 | item = g_menu_item_new (g_app_info_get_name (G_APP_INFO (priv->appinfo)), "launch"); |
3523 | g_menu_item_set_attribute (item, "x-canonical-type", "s", "ImAppMenuItem"); |
3524 | iconstr = g_icon_to_string (g_app_info_get_icon (G_APP_INFO (priv->appinfo))); |
3525 | - g_menu_item_set_attribute (item, "x-canonical-icon", "s", iconstr); |
3526 | + if (iconstr != NULL) { |
3527 | + g_menu_item_set_attribute (item, "x-canonical-icon", "s", iconstr); |
3528 | + } |
3529 | g_free (iconstr); |
3530 | |
3531 | g_menu_append_item (priv->menu, item); |
3532 | @@ -445,6 +444,11 @@ |
3533 | g_free(name); |
3534 | } |
3535 | |
3536 | + item = g_menu_item_new_section (NULL, G_MENU_MODEL (priv->source_menu)); |
3537 | + g_menu_item_set_attribute (item, "action-namespace", "s", "source"); |
3538 | + g_menu_append_item (priv->menu, item); |
3539 | + g_object_unref (item); |
3540 | + |
3541 | keyfile = g_file_new_for_path (g_desktop_app_info_get_filename (priv->appinfo)); |
3542 | g_file_load_contents_async (keyfile, NULL, keyfile_loaded, self); |
3543 | |
3544 | @@ -583,39 +587,8 @@ |
3545 | void |
3546 | app_section_clear_draws_attention (AppSection *self) |
3547 | { |
3548 | - AppSectionPrivate * priv = self->priv; |
3549 | - gchar **action_names; |
3550 | - gchar **it; |
3551 | - |
3552 | - if (priv->source_actions == NULL) |
3553 | - return; |
3554 | - |
3555 | - action_names = g_action_group_list_actions (priv->source_actions); |
3556 | - |
3557 | - for (it = action_names; *it; it++) { |
3558 | - GVariant *state; |
3559 | - |
3560 | - state = g_action_group_get_action_state (priv->source_actions, *it); |
3561 | - if (!state) |
3562 | - continue; |
3563 | - |
3564 | - /* clear draws-attention while preserving other state */ |
3565 | - if (action_draws_attention (state)) { |
3566 | - guint32 count; |
3567 | - gint64 time; |
3568 | - const gchar *str; |
3569 | - GVariant *new_state; |
3570 | - |
3571 | - g_variant_get (state, "(ux&sb)", &count, &time, &str, NULL); |
3572 | - |
3573 | - new_state = g_variant_new ("(uxsb)", count, time, str, FALSE); |
3574 | - g_action_group_change_action_state (priv->source_actions, *it, new_state); |
3575 | - } |
3576 | - |
3577 | - g_variant_unref (state); |
3578 | - } |
3579 | - |
3580 | - g_strfreev (action_names); |
3581 | + self->priv->draws_attention = FALSE; |
3582 | + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_DRAWS_ATTENTION]); |
3583 | } |
3584 | |
3585 | static void |
3586 | @@ -628,6 +601,230 @@ |
3587 | app_section_unset_object_path (self); |
3588 | } |
3589 | |
3590 | +static void |
3591 | +update_draws_attention (AppSection *self) |
3592 | +{ |
3593 | + AppSectionPrivate *priv = self->priv; |
3594 | + gchar **actions; |
3595 | + gchar **it; |
3596 | + gboolean draws_attention = FALSE; |
3597 | + |
3598 | + actions = g_action_group_list_actions (G_ACTION_GROUP (priv->source_actions)); |
3599 | + |
3600 | + for (it = actions; *it; it++) { |
3601 | + GVariant *state; |
3602 | + |
3603 | + state = g_action_group_get_action_state (G_ACTION_GROUP (priv->source_actions), *it); |
3604 | + if (state) { |
3605 | + gboolean b; |
3606 | + g_variant_get (state, "(uxsb)", NULL, NULL, NULL, &b); |
3607 | + draws_attention = b || draws_attention; |
3608 | + g_variant_unref (state); |
3609 | + } |
3610 | + |
3611 | + if (draws_attention) |
3612 | + break; |
3613 | + } |
3614 | + |
3615 | + if (draws_attention != priv->draws_attention) { |
3616 | + priv->draws_attention = draws_attention; |
3617 | + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_DRAWS_ATTENTION]); |
3618 | + } |
3619 | + |
3620 | + g_strfreev (actions); |
3621 | +} |
3622 | + |
3623 | +static void |
3624 | +remove_source (AppSection *self, |
3625 | + const gchar *id) |
3626 | +{ |
3627 | + AppSectionPrivate *priv = self->priv; |
3628 | + guint n_items; |
3629 | + guint i; |
3630 | + |
3631 | + n_items = g_menu_model_get_n_items (G_MENU_MODEL (priv->source_menu)); |
3632 | + for (i = 0; i < n_items; i++) { |
3633 | + gchar *action; |
3634 | + gboolean found = FALSE; |
3635 | + |
3636 | + if (g_menu_model_get_item_attribute (G_MENU_MODEL (priv->source_menu), i, |
3637 | + G_MENU_ATTRIBUTE_ACTION, "s", &action)) { |
3638 | + found = g_str_equal (action, id); |
3639 | + g_free (action); |
3640 | + } |
3641 | + |
3642 | + if (found) { |
3643 | + g_menu_remove (priv->source_menu, i); |
3644 | + break; |
3645 | + } |
3646 | + } |
3647 | + |
3648 | + g_simple_action_group_remove (priv->source_actions, id); |
3649 | + update_draws_attention (self); |
3650 | +} |
3651 | + |
3652 | +static void |
3653 | +source_action_activated (GSimpleAction *action, |
3654 | + GVariant *parameter, |
3655 | + gpointer user_data) |
3656 | +{ |
3657 | + AppSection *self = APP_SECTION (user_data); |
3658 | + AppSectionPrivate *priv = APP_SECTION (user_data)->priv; |
3659 | + |
3660 | + g_return_if_fail (priv->app_proxy != NULL); |
3661 | + |
3662 | + indicator_messages_application_call_activate_source (priv->app_proxy, |
3663 | + g_action_get_name (G_ACTION (action)), |
3664 | + priv->app_proxy_cancellable, |
3665 | + NULL, NULL); |
3666 | + |
3667 | + remove_source (self, g_action_get_name (G_ACTION (action))); |
3668 | +} |
3669 | + |
3670 | +static void |
3671 | +sources_listed (GObject *source_object, |
3672 | + GAsyncResult *result, |
3673 | + gpointer user_data) |
3674 | +{ |
3675 | + AppSection *self = user_data; |
3676 | + AppSectionPrivate *priv = self->priv; |
3677 | + GVariant *sources = NULL; |
3678 | + GError *error = NULL; |
3679 | + GVariantIter iter; |
3680 | + const gchar *id; |
3681 | + const gchar *label; |
3682 | + const gchar *iconstr; |
3683 | + guint32 count; |
3684 | + gint64 time; |
3685 | + const gchar *string; |
3686 | + gboolean draws_attention; |
3687 | + |
3688 | + if (!indicator_messages_application_call_list_sources_finish (INDICATOR_MESSAGES_APPLICATION (source_object), |
3689 | + &sources, result, &error)) |
3690 | + { |
3691 | + g_warning ("could not fetch the list of sources: %s", error->message); |
3692 | + g_error_free (error); |
3693 | + return; |
3694 | + } |
3695 | + |
3696 | + g_menu_clear (priv->source_menu); |
3697 | + g_simple_action_group_clear (priv->source_actions); |
3698 | + priv->draws_attention = FALSE; |
3699 | + |
3700 | + g_variant_iter_init (&iter, sources); |
3701 | + while (g_variant_iter_next (&iter, "(&s&s&sux&sb)", &id, &label, &iconstr, |
3702 | + &count, &time, &string, &draws_attention)) |
3703 | + { |
3704 | + GVariant *state; |
3705 | + GSimpleAction *action; |
3706 | + GMenuItem *item; |
3707 | + |
3708 | + state = g_variant_new ("(uxsb)", count, time, string, draws_attention); |
3709 | + action = g_simple_action_new_stateful (id, NULL, state); |
3710 | + g_signal_connect (action, "activate", G_CALLBACK (source_action_activated), self); |
3711 | + g_simple_action_group_insert (priv->source_actions, G_ACTION (action)); |
3712 | + |
3713 | + item = g_menu_item_new (label, id); |
3714 | + g_menu_item_set_attribute (item, "x-canonical-type", "s", "ImSourceMenuItem"); |
3715 | + g_menu_append_item (priv->source_menu, item); |
3716 | + |
3717 | + priv->draws_attention = priv->draws_attention || draws_attention; |
3718 | + |
3719 | + g_object_unref (item); |
3720 | + g_object_unref (action); |
3721 | + } |
3722 | + |
3723 | + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_DRAWS_ATTENTION]); |
3724 | + |
3725 | + g_variant_unref (sources); |
3726 | +} |
3727 | + |
3728 | +static void |
3729 | +source_added (IndicatorMessagesApplication *app, |
3730 | + const gchar *id, |
3731 | + const gchar *label, |
3732 | + const gchar *iconstr, |
3733 | + guint count, |
3734 | + gint64 time, |
3735 | + const gchar *string, |
3736 | + gboolean draws_attention, |
3737 | + gpointer user_data) |
3738 | +{ |
3739 | + AppSection *self = user_data; |
3740 | + AppSectionPrivate *priv = self->priv; |
3741 | + GVariant *state; |
3742 | + GSimpleAction *action; |
3743 | + |
3744 | + /* TODO put label and icon into the action as well */ |
3745 | + |
3746 | + state = g_variant_new ("(uxsb)", count, time, string, draws_attention); |
3747 | + action = g_simple_action_new_stateful (id, NULL, state); |
3748 | + |
3749 | + g_simple_action_group_insert (priv->source_actions, G_ACTION (action)); |
3750 | + |
3751 | + if (draws_attention && !priv->draws_attention) { |
3752 | + priv->draws_attention = TRUE; |
3753 | + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_DRAWS_ATTENTION]); |
3754 | + } |
3755 | + |
3756 | + g_object_unref (action); |
3757 | +} |
3758 | +static void |
3759 | +source_changed (IndicatorMessagesApplication *app, |
3760 | + const gchar *id, |
3761 | + const gchar *label, |
3762 | + const gchar *iconstr, |
3763 | + guint count, |
3764 | + gint64 time, |
3765 | + const gchar *string, |
3766 | + gboolean draws_attention, |
3767 | + gpointer user_data) |
3768 | +{ |
3769 | + AppSection *self = user_data; |
3770 | + AppSectionPrivate *priv = self->priv; |
3771 | + GVariant *state; |
3772 | + |
3773 | + /* TODO put label and icon into the action as well */ |
3774 | + |
3775 | + state = g_variant_new ("(uxsb)", count, time, string, draws_attention); |
3776 | + g_action_group_change_action_state (G_ACTION_GROUP (priv->source_actions), id, state); |
3777 | + |
3778 | + update_draws_attention (self); |
3779 | +} |
3780 | + |
3781 | +static void |
3782 | +source_removed (IndicatorMessagesApplication *app, |
3783 | + const gchar *id, |
3784 | + gpointer user_data) |
3785 | +{ |
3786 | + AppSection *self = user_data; |
3787 | + |
3788 | + remove_source (self, id); |
3789 | +} |
3790 | + |
3791 | +static void |
3792 | +app_proxy_created (GObject *source_object, |
3793 | + GAsyncResult *result, |
3794 | + gpointer user_data) |
3795 | +{ |
3796 | + AppSectionPrivate *priv = APP_SECTION (user_data)->priv; |
3797 | + GError *error = NULL; |
3798 | + |
3799 | + priv->app_proxy = indicator_messages_application_proxy_new_finish (result, &error); |
3800 | + if (!priv->app_proxy) { |
3801 | + g_warning ("could not create application proxy: %s", error->message); |
3802 | + g_error_free (error); |
3803 | + return; |
3804 | + } |
3805 | + |
3806 | + indicator_messages_application_call_list_sources (priv->app_proxy, priv->app_proxy_cancellable, |
3807 | + sources_listed, user_data); |
3808 | + |
3809 | + g_signal_connect (priv->app_proxy, "source-added", G_CALLBACK (source_added), user_data); |
3810 | + g_signal_connect (priv->app_proxy, "source-changed", G_CALLBACK (source_changed), user_data); |
3811 | + g_signal_connect (priv->app_proxy, "source-removed", G_CALLBACK (source_removed), user_data); |
3812 | +} |
3813 | + |
3814 | /* |
3815 | * app_section_set_object_path: |
3816 | * @self: an #AppSection |
3817 | @@ -646,27 +843,20 @@ |
3818 | const gchar *object_path) |
3819 | { |
3820 | AppSectionPrivate *priv = self->priv; |
3821 | - GMenuItem *item; |
3822 | |
3823 | g_object_freeze_notify (G_OBJECT (self)); |
3824 | app_section_unset_object_path (self); |
3825 | |
3826 | - priv->source_actions = G_ACTION_GROUP (g_dbus_action_group_get (bus, bus_name, object_path)); |
3827 | - g_action_muxer_insert (priv->muxer, "source", priv->source_actions); |
3828 | - |
3829 | - priv->draws_attention = any_action_draws_attention (priv->source_actions, NULL); |
3830 | - g_object_connect (priv->source_actions, |
3831 | - "signal::action-added", action_added, self, |
3832 | - "signal::action-state-changed", action_state_changed, self, |
3833 | - "signal::action-removed", action_removed, self, |
3834 | - NULL); |
3835 | - |
3836 | - priv->source_menu = G_MENU_MODEL (g_dbus_menu_model_get (bus, bus_name, object_path)); |
3837 | - |
3838 | - item = g_menu_item_new_section (NULL, priv->source_menu); |
3839 | - g_menu_item_set_attribute (item, "action-namespace", "s", "source"); |
3840 | - g_menu_append_item (priv->menu, item); |
3841 | - g_object_unref (item); |
3842 | + priv->app_proxy_cancellable = g_cancellable_new (); |
3843 | + indicator_messages_application_proxy_new (bus, |
3844 | + G_DBUS_PROXY_FLAGS_NONE, |
3845 | + bus_name, |
3846 | + object_path, |
3847 | + priv->app_proxy_cancellable, |
3848 | + app_proxy_created, |
3849 | + self); |
3850 | + |
3851 | + priv->draws_attention = FALSE; |
3852 | |
3853 | priv->name_watch_id = g_bus_watch_name_on_connection (bus, bus_name, 0, |
3854 | NULL, application_vanished, |
3855 | @@ -694,26 +884,19 @@ |
3856 | { |
3857 | AppSectionPrivate *priv = self->priv; |
3858 | |
3859 | + if (priv->app_proxy_cancellable) { |
3860 | + g_cancellable_cancel (priv->app_proxy_cancellable); |
3861 | + g_clear_object (&priv->app_proxy_cancellable); |
3862 | + } |
3863 | + g_clear_object (&priv->app_proxy); |
3864 | + |
3865 | if (priv->name_watch_id) { |
3866 | g_bus_unwatch_name (priv->name_watch_id); |
3867 | priv->name_watch_id = 0; |
3868 | } |
3869 | |
3870 | - if (priv->source_actions) { |
3871 | - g_object_disconnect (priv->source_actions, |
3872 | - "any_signal::action-added", action_added, self, |
3873 | - "any_signal::action-state-changed", action_state_changed, self, |
3874 | - "any_signal::action-removed", action_removed, self, |
3875 | - NULL); |
3876 | - g_clear_object (&priv->source_actions); |
3877 | - } |
3878 | - |
3879 | - if (priv->source_menu) { |
3880 | - /* the last menu item points is linked to the app's menumodel */ |
3881 | - gint n_items = g_menu_model_get_n_items (G_MENU_MODEL (priv->menu)); |
3882 | - g_menu_remove (priv->menu, n_items -1); |
3883 | - g_clear_object (&priv->source_menu); |
3884 | - } |
3885 | + g_simple_action_group_clear (priv->source_actions); |
3886 | + g_menu_clear (priv->source_menu); |
3887 | |
3888 | priv->draws_attention = FALSE; |
3889 | g_clear_pointer (&priv->chat_status, g_free); |
3890 | @@ -727,85 +910,6 @@ |
3891 | "launch", g_variant_new_boolean (FALSE)); |
3892 | } |
3893 | |
3894 | -static gboolean |
3895 | -action_draws_attention (GVariant *state) |
3896 | -{ |
3897 | - gboolean attention; |
3898 | - |
3899 | - if (state && g_variant_is_of_type (state, G_VARIANT_TYPE ("(uxsb)"))) |
3900 | - g_variant_get_child (state, 3, "b", &attention); |
3901 | - else |
3902 | - attention = FALSE; |
3903 | - |
3904 | - return attention; |
3905 | -} |
3906 | - |
3907 | -static gboolean |
3908 | -any_action_draws_attention (GActionGroup *group, |
3909 | - const gchar *ignored_action) |
3910 | -{ |
3911 | - gchar **actions; |
3912 | - gchar **it; |
3913 | - gboolean attention = FALSE; |
3914 | - |
3915 | - actions = g_action_group_list_actions (group); |
3916 | - |
3917 | - for (it = actions; *it && !attention; it++) { |
3918 | - GVariant *state; |
3919 | - |
3920 | - if (ignored_action && g_str_equal (ignored_action, *it)) |
3921 | - continue; |
3922 | - |
3923 | - state = g_action_group_get_action_state (group, *it); |
3924 | - if (state) { |
3925 | - attention = action_draws_attention (state); |
3926 | - g_variant_unref (state); |
3927 | - } |
3928 | - } |
3929 | - |
3930 | - g_strfreev (actions); |
3931 | - return attention; |
3932 | -} |
3933 | - |
3934 | -static void |
3935 | -action_added (GActionGroup *group, |
3936 | - const gchar *action_name, |
3937 | - gpointer user_data) |
3938 | -{ |
3939 | - AppSection *self = user_data; |
3940 | - GVariant *state; |
3941 | - |
3942 | - state = g_action_group_get_action_state (group, action_name); |
3943 | - if (state) { |
3944 | - self->priv->draws_attention |= action_draws_attention (state); |
3945 | - g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_DRAWS_ATTENTION]); |
3946 | - g_variant_unref (state); |
3947 | - } |
3948 | -} |
3949 | - |
3950 | -static void |
3951 | -action_state_changed (GActionGroup *group, |
3952 | - const gchar *action_name, |
3953 | - GVariant *value, |
3954 | - gpointer user_data) |
3955 | -{ |
3956 | - AppSection *self = user_data; |
3957 | - |
3958 | - self->priv->draws_attention = any_action_draws_attention (group, NULL); |
3959 | - g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_DRAWS_ATTENTION]); |
3960 | -} |
3961 | - |
3962 | -static void |
3963 | -action_removed (GActionGroup *group, |
3964 | - const gchar *action_name, |
3965 | - gpointer user_data) |
3966 | -{ |
3967 | - AppSection *self = user_data; |
3968 | - |
3969 | - self->priv->draws_attention = any_action_draws_attention (group, action_name); |
3970 | - g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_DRAWS_ATTENTION]); |
3971 | -} |
3972 | - |
3973 | gboolean |
3974 | app_section_get_uses_chat_status (AppSection *self) |
3975 | { |
3976 | |
3977 | === modified file 'src/dbus-data.h' |
3978 | --- src/dbus-data.h 2013-08-20 08:53:01 +0000 |
3979 | +++ src/dbus-data.h 2013-08-21 02:09:27 +0000 |
3980 | @@ -1,9 +1,24 @@ |
3981 | +/* |
3982 | + * Copyright 2012-2013 Canonical Ltd. |
3983 | + * |
3984 | + * This program is free software: you can redistribute it and/or modify it |
3985 | + * under the terms of the GNU General Public License version 3, as published |
3986 | + * by the Free Software Foundation. |
3987 | + * |
3988 | + * This program is distributed in the hope that it will be useful, but |
3989 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
3990 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
3991 | + * PURPOSE. See the GNU General Public License for more details. |
3992 | + * |
3993 | + * You should have received a copy of the GNU General Public License along |
3994 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
3995 | + */ |
3996 | |
3997 | #ifndef __DBUS_DATA_H__ |
3998 | #define __DBUS_DATA_H__ 1 |
3999 | |
4000 | #define INDICATOR_MESSAGES_DBUS_NAME "com.canonical.indicator.messages" |
4001 | -#define INDICATOR_MESSAGES_DBUS_OBJECT "/com/canonical/indicator/messages/menu" |
4002 | +#define INDICATOR_MESSAGES_DBUS_OBJECT "/com/canonical/indicator/messages" |
4003 | |
4004 | #define INDICATOR_MESSAGES_DBUS_SERVICE_OBJECT "/com/canonical/indicator/messages/service" |
4005 | #define INDICATOR_MESSAGES_DBUS_SERVICE_INTERFACE "com.canonical.indicator.messages.service" |
4006 | |
4007 | === modified file 'src/gactionmuxer.c' |
4008 | --- src/gactionmuxer.c 2013-08-20 08:53:01 +0000 |
4009 | +++ src/gactionmuxer.c 2013-08-21 02:09:27 +0000 |
4010 | @@ -483,3 +483,11 @@ |
4011 | g_clear_object (&muxer->global_actions); |
4012 | } |
4013 | |
4014 | +GActionGroup * |
4015 | +g_action_muxer_get_group (GActionMuxer *muxer, |
4016 | + const gchar *prefix) |
4017 | +{ |
4018 | + g_return_val_if_fail (G_IS_ACTION_MUXER (muxer), NULL); |
4019 | + |
4020 | + return prefix ? g_hash_table_lookup (muxer->groups, prefix) : muxer->global_actions; |
4021 | +} |
4022 | |
4023 | === modified file 'src/gactionmuxer.h' |
4024 | --- src/gactionmuxer.h 2013-08-20 08:53:01 +0000 |
4025 | +++ src/gactionmuxer.h 2013-08-21 02:09:27 +0000 |
4026 | @@ -40,5 +40,8 @@ |
4027 | void g_action_muxer_remove (GActionMuxer *muxer, |
4028 | const gchar *prefix); |
4029 | |
4030 | +GActionGroup * g_action_muxer_get_group (GActionMuxer *muxer, |
4031 | + const gchar *prefix); |
4032 | + |
4033 | #endif |
4034 | |
4035 | |
4036 | === modified file 'src/gmenuutils.c' |
4037 | --- src/gmenuutils.c 2013-08-20 08:53:01 +0000 |
4038 | +++ src/gmenuutils.c 2013-08-21 02:09:27 +0000 |
4039 | @@ -79,7 +79,7 @@ |
4040 | GMenuItem *item; |
4041 | |
4042 | item = g_menu_item_new (label, detailed_action); |
4043 | - g_menu_item_set_attribute (item, "x-canonical-icon", "s", icon_name); |
4044 | + g_menu_item_set_attribute (item, "icon", "s", icon_name); |
4045 | |
4046 | g_menu_append_item (menu, item); |
4047 | |
4048 | |
4049 | === removed file 'src/ido-detail-label.c' |
4050 | --- src/ido-detail-label.c 2013-08-20 08:53:01 +0000 |
4051 | +++ src/ido-detail-label.c 1970-01-01 00:00:00 +0000 |
4052 | @@ -1,401 +0,0 @@ |
4053 | -/* |
4054 | - * Copyright 2012 Canonical Ltd. |
4055 | - * |
4056 | - * This program is free software: you can redistribute it and/or modify it |
4057 | - * under the terms of the GNU General Public License version 3, as published |
4058 | - * by the Free Software Foundation. |
4059 | - * |
4060 | - * This program is distributed in the hope that it will be useful, but |
4061 | - * WITHOUT ANY WARRANTY; without even the implied warranties of |
4062 | - * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
4063 | - * PURPOSE. See the GNU General Public License for more details. |
4064 | - * |
4065 | - * You should have received a copy of the GNU General Public License along |
4066 | - * with this program. If not, see <http://www.gnu.org/licenses/>. |
4067 | - * |
4068 | - * Authors: |
4069 | - * Lars Uebernickel <lars.uebernickel@canonical.com> |
4070 | - */ |
4071 | - |
4072 | -#include "ido-detail-label.h" |
4073 | - |
4074 | -#include <math.h> |
4075 | - |
4076 | -G_DEFINE_TYPE (IdoDetailLabel, ido_detail_label, GTK_TYPE_WIDGET) |
4077 | - |
4078 | -struct _IdoDetailLabelPrivate |
4079 | -{ |
4080 | - gchar *text; |
4081 | - PangoLayout *layout; |
4082 | - gboolean draw_lozenge; |
4083 | -}; |
4084 | - |
4085 | -enum |
4086 | -{ |
4087 | - PROP_0, |
4088 | - PROP_TEXT, |
4089 | - NUM_PROPERTIES |
4090 | -}; |
4091 | - |
4092 | -static GParamSpec *properties[NUM_PROPERTIES]; |
4093 | - |
4094 | -static void |
4095 | -ido_detail_label_get_property (GObject *object, |
4096 | - guint property_id, |
4097 | - GValue *value, |
4098 | - GParamSpec *pspec) |
4099 | -{ |
4100 | - IdoDetailLabel *self = IDO_DETAIL_LABEL (object); |
4101 | - |
4102 | - switch (property_id) |
4103 | - { |
4104 | - case PROP_TEXT: |
4105 | - g_value_set_string (value, self->priv->text); |
4106 | - break; |
4107 | - |
4108 | - default: |
4109 | - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); |
4110 | - } |
4111 | -} |
4112 | - |
4113 | -static void |
4114 | -ido_detail_label_set_property (GObject *object, |
4115 | - guint property_id, |
4116 | - const GValue *value, |
4117 | - GParamSpec *pspec) |
4118 | -{ |
4119 | - IdoDetailLabel *self = IDO_DETAIL_LABEL (object); |
4120 | - |
4121 | - switch (property_id) |
4122 | - { |
4123 | - case PROP_TEXT: |
4124 | - ido_detail_label_set_text (self, g_value_get_string (value)); |
4125 | - break; |
4126 | - |
4127 | - default: |
4128 | - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); |
4129 | - } |
4130 | -} |
4131 | - |
4132 | - |
4133 | -static void |
4134 | -ido_detail_label_finalize (GObject *object) |
4135 | -{ |
4136 | - IdoDetailLabelPrivate *priv = IDO_DETAIL_LABEL (object)->priv; |
4137 | - |
4138 | - g_free (priv->text); |
4139 | - |
4140 | - G_OBJECT_CLASS (ido_detail_label_parent_class)->finalize (object); |
4141 | -} |
4142 | - |
4143 | -static void |
4144 | -ido_detail_label_dispose (GObject *object) |
4145 | -{ |
4146 | - IdoDetailLabelPrivate *priv = IDO_DETAIL_LABEL (object)->priv; |
4147 | - |
4148 | - g_clear_object (&priv->layout); |
4149 | - |
4150 | - G_OBJECT_CLASS (ido_detail_label_parent_class)->dispose (object); |
4151 | -} |
4152 | - |
4153 | -static void |
4154 | -ido_detail_label_ensure_layout (IdoDetailLabel *label) |
4155 | -{ |
4156 | - IdoDetailLabelPrivate *priv = label->priv; |
4157 | - |
4158 | - if (priv->layout == NULL) |
4159 | - { |
4160 | - priv->layout = gtk_widget_create_pango_layout (GTK_WIDGET (label), priv->text); |
4161 | - pango_layout_set_alignment (priv->layout, PANGO_ALIGN_CENTER); |
4162 | - pango_layout_set_ellipsize (priv->layout, PANGO_ELLIPSIZE_END); |
4163 | - pango_layout_set_height (priv->layout, -1); |
4164 | - |
4165 | - // TODO update layout on "style-updated" and "direction-changed" |
4166 | - } |
4167 | -} |
4168 | - |
4169 | -static void |
4170 | -cairo_lozenge (cairo_t *cr, |
4171 | - double x, |
4172 | - double y, |
4173 | - double w, |
4174 | - double h, |
4175 | - double radius) |
4176 | -{ |
4177 | - double x1 = x + w - radius; |
4178 | - double x2 = x + radius; |
4179 | - double y1 = y + radius; |
4180 | - double y2 = y + h - radius; |
4181 | - |
4182 | - cairo_move_to (cr, x + radius, y); |
4183 | - cairo_arc (cr, x1, y1, radius, G_PI * 1.5, G_PI * 2); |
4184 | - cairo_arc (cr, x1, y2, radius, 0, G_PI * 0.5); |
4185 | - cairo_arc (cr, x2, y2, radius, G_PI * 0.5, G_PI); |
4186 | - cairo_arc (cr, x2, y1, radius, G_PI, G_PI * 1.5); |
4187 | -} |
4188 | - |
4189 | -static PangoFontMetrics * |
4190 | -gtk_widget_get_font_metrics (GtkWidget *widget, |
4191 | - PangoContext *context) |
4192 | -{ |
4193 | - PangoFontDescription *font; |
4194 | - PangoFontMetrics *metrics; |
4195 | - |
4196 | - gtk_style_context_get (gtk_widget_get_style_context (widget), |
4197 | - gtk_widget_get_state_flags (widget), |
4198 | - "font", &font, NULL); |
4199 | - |
4200 | - metrics = pango_context_get_metrics (context, |
4201 | - font, |
4202 | - pango_context_get_language (context)); |
4203 | - |
4204 | - pango_font_description_free (font); |
4205 | - return metrics; |
4206 | -} |
4207 | - |
4208 | -static gint |
4209 | -ido_detail_label_get_minimum_text_width (IdoDetailLabel *label) |
4210 | -{ |
4211 | - IdoDetailLabelPrivate *priv = label->priv; |
4212 | - PangoContext *context; |
4213 | - PangoFontMetrics *metrics; |
4214 | - gint char_width; |
4215 | - gint w; |
4216 | - |
4217 | - context = pango_layout_get_context (priv->layout); |
4218 | - metrics = gtk_widget_get_font_metrics (GTK_WIDGET (label), context); |
4219 | - char_width = pango_font_metrics_get_approximate_digit_width (metrics); |
4220 | - |
4221 | - w = 2 * char_width / PANGO_SCALE; |
4222 | - pango_font_metrics_unref (metrics); |
4223 | - return w; |
4224 | -} |
4225 | - |
4226 | -static gboolean |
4227 | -ido_detail_label_draw (GtkWidget *widget, |
4228 | - cairo_t *cr) |
4229 | -{ |
4230 | - IdoDetailLabel *label = IDO_DETAIL_LABEL (widget); |
4231 | - IdoDetailLabelPrivate *priv = IDO_DETAIL_LABEL (widget)->priv; |
4232 | - PangoRectangle extents; |
4233 | - GtkAllocation allocation; |
4234 | - double x, w, h, radius; |
4235 | - GdkRGBA color; |
4236 | - |
4237 | - if (!priv->text || !*priv->text) |
4238 | - return TRUE; |
4239 | - |
4240 | - gtk_widget_get_allocation (widget, &allocation); |
4241 | - |
4242 | - ido_detail_label_ensure_layout (IDO_DETAIL_LABEL (widget)); |
4243 | - |
4244 | - pango_layout_get_extents (priv->layout, NULL, &extents); |
4245 | - pango_extents_to_pixels (&extents, NULL); |
4246 | - |
4247 | - h = MIN (allocation.height, extents.height); |
4248 | - radius = floor (h / 2.0); |
4249 | - w = MAX (ido_detail_label_get_minimum_text_width (label), extents.width) + 2.0 * radius; |
4250 | - x = allocation.width - w; |
4251 | - |
4252 | - pango_layout_set_width (priv->layout, (allocation.width - 2 * radius) * PANGO_SCALE); |
4253 | - pango_layout_get_extents (priv->layout, NULL, &extents); |
4254 | - pango_extents_to_pixels (&extents, NULL); |
4255 | - |
4256 | - gtk_style_context_get_color (gtk_widget_get_style_context (widget), |
4257 | - gtk_widget_get_state_flags (widget), |
4258 | - &color); |
4259 | - gdk_cairo_set_source_rgba (cr, &color); |
4260 | - |
4261 | - cairo_set_line_width (cr, 1.0); |
4262 | - cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD); |
4263 | - |
4264 | - if (priv->draw_lozenge) |
4265 | - cairo_lozenge (cr, x, 0.0, w, h, radius); |
4266 | - |
4267 | - cairo_move_to (cr, x + radius, (allocation.height - extents.height) / 2.0); |
4268 | - pango_cairo_layout_path (cr, priv->layout); |
4269 | - cairo_fill (cr); |
4270 | - |
4271 | - return TRUE; |
4272 | -} |
4273 | - |
4274 | -static void |
4275 | -ido_detail_label_get_preferred_width (GtkWidget *widget, |
4276 | - gint *minimum, |
4277 | - gint *natural) |
4278 | -{ |
4279 | - IdoDetailLabelPrivate *priv = IDO_DETAIL_LABEL (widget)->priv; |
4280 | - PangoRectangle extents; |
4281 | - double radius; |
4282 | - |
4283 | - ido_detail_label_ensure_layout (IDO_DETAIL_LABEL (widget)); |
4284 | - |
4285 | - pango_layout_get_extents (priv->layout, NULL, &extents); |
4286 | - pango_extents_to_pixels (&extents, NULL); |
4287 | - |
4288 | - radius = floor (extents.height / 2.0); |
4289 | - |
4290 | - *minimum = ido_detail_label_get_minimum_text_width (IDO_DETAIL_LABEL (widget)) + 2.0 * radius; |
4291 | - *natural = MAX (*minimum, extents.width + 2.0 * radius); |
4292 | -} |
4293 | - |
4294 | -static void |
4295 | -ido_detail_label_get_preferred_height (GtkWidget *widget, |
4296 | - gint *minimum, |
4297 | - gint *natural) |
4298 | -{ |
4299 | - IdoDetailLabelPrivate *priv = IDO_DETAIL_LABEL (widget)->priv; |
4300 | - PangoContext *context; |
4301 | - PangoFontMetrics *metrics; |
4302 | - PangoRectangle extents; |
4303 | - |
4304 | - ido_detail_label_ensure_layout (IDO_DETAIL_LABEL (widget)); |
4305 | - |
4306 | - pango_layout_get_extents (priv->layout, NULL, &extents); |
4307 | - pango_extents_to_pixels (&extents, NULL); |
4308 | - context = pango_layout_get_context (priv->layout); |
4309 | - metrics = gtk_widget_get_font_metrics (widget, context); |
4310 | - |
4311 | - *minimum = *natural = (pango_font_metrics_get_ascent (metrics) + |
4312 | - pango_font_metrics_get_descent (metrics)) / PANGO_SCALE; |
4313 | - |
4314 | - pango_font_metrics_unref (metrics); |
4315 | -} |
4316 | - |
4317 | -static void |
4318 | -ido_detail_label_class_init (IdoDetailLabelClass *klass) |
4319 | -{ |
4320 | - GObjectClass *object_class = G_OBJECT_CLASS (klass); |
4321 | - GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); |
4322 | - |
4323 | - object_class->get_property = ido_detail_label_get_property; |
4324 | - object_class->set_property = ido_detail_label_set_property; |
4325 | - object_class->finalize = ido_detail_label_finalize; |
4326 | - object_class->dispose = ido_detail_label_dispose; |
4327 | - |
4328 | - widget_class->draw = ido_detail_label_draw; |
4329 | - widget_class->get_preferred_width = ido_detail_label_get_preferred_width; |
4330 | - widget_class->get_preferred_height = ido_detail_label_get_preferred_height; |
4331 | - |
4332 | - g_type_class_add_private (klass, sizeof (IdoDetailLabelPrivate)); |
4333 | - |
4334 | - properties[PROP_TEXT] = g_param_spec_string ("text", |
4335 | - "Text", |
4336 | - "The text of the label", |
4337 | - NULL, |
4338 | - G_PARAM_READWRITE | |
4339 | - G_PARAM_STATIC_STRINGS); |
4340 | - |
4341 | - g_object_class_install_properties (object_class, NUM_PROPERTIES, properties); |
4342 | -} |
4343 | - |
4344 | -static void |
4345 | -ido_detail_label_init (IdoDetailLabel *self) |
4346 | -{ |
4347 | - self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, |
4348 | - IDO_TYPE_DETAIL_LABEL, |
4349 | - IdoDetailLabelPrivate); |
4350 | - |
4351 | - gtk_widget_set_has_window (GTK_WIDGET (self), FALSE); |
4352 | -} |
4353 | - |
4354 | -GtkWidget * |
4355 | -ido_detail_label_new (const gchar *label) |
4356 | -{ |
4357 | - return g_object_new (IDO_TYPE_DETAIL_LABEL, |
4358 | - "text", label, |
4359 | - NULL); |
4360 | -} |
4361 | - |
4362 | -const gchar * |
4363 | -ido_detail_label_get_text (IdoDetailLabel *label) |
4364 | -{ |
4365 | - g_return_val_if_fail (IDO_IS_DETAIL_LABEL (label), NULL); |
4366 | - return label->priv->text; |
4367 | -} |
4368 | - |
4369 | -/* collapse_whitespace: |
4370 | - * @str: the source string |
4371 | - * |
4372 | - * Collapses all occurences of consecutive whitespace charactes in @str |
4373 | - * into a single space. |
4374 | - * |
4375 | - * Returns: (transfer full): a newly-allocated string |
4376 | - */ |
4377 | -static gchar * |
4378 | -collapse_whitespace (const gchar *str) |
4379 | -{ |
4380 | - GString *result; |
4381 | - gboolean in_space = FALSE; |
4382 | - |
4383 | - if (str == NULL) |
4384 | - return NULL; |
4385 | - |
4386 | - result = g_string_new (""); |
4387 | - |
4388 | - while (*str) |
4389 | - { |
4390 | - gunichar c = g_utf8_get_char_validated (str, -1); |
4391 | - |
4392 | - if (c < 0) |
4393 | - break; |
4394 | - |
4395 | - if (!g_unichar_isspace (c)) |
4396 | - { |
4397 | - g_string_append_unichar (result, c); |
4398 | - in_space = FALSE; |
4399 | - } |
4400 | - else if (!in_space) |
4401 | - { |
4402 | - g_string_append_c (result, ' '); |
4403 | - in_space = TRUE; |
4404 | - } |
4405 | - |
4406 | - str = g_utf8_next_char (str); |
4407 | - } |
4408 | - |
4409 | - return g_string_free (result, FALSE); |
4410 | -} |
4411 | - |
4412 | -static void |
4413 | -ido_detail_label_set_text_impl (IdoDetailLabel *label, |
4414 | - const gchar *text, |
4415 | - gboolean draw_lozenge) |
4416 | -{ |
4417 | - IdoDetailLabelPrivate * priv = label->priv; |
4418 | - |
4419 | - g_clear_object (&priv->layout); |
4420 | - g_free (priv->text); |
4421 | - |
4422 | - priv->text = g_strdup (text); |
4423 | - priv->draw_lozenge = draw_lozenge; |
4424 | - |
4425 | - g_object_notify_by_pspec (G_OBJECT (label), properties[PROP_TEXT]); |
4426 | - gtk_widget_queue_resize (GTK_WIDGET (label)); |
4427 | -} |
4428 | - |
4429 | -void |
4430 | -ido_detail_label_set_text (IdoDetailLabel *label, |
4431 | - const gchar *text) |
4432 | -{ |
4433 | - gchar *str; |
4434 | - |
4435 | - g_return_if_fail (IDO_IS_DETAIL_LABEL (label)); |
4436 | - |
4437 | - str = collapse_whitespace (text); |
4438 | - ido_detail_label_set_text_impl (label, str, FALSE); |
4439 | - g_free (str); |
4440 | -} |
4441 | - |
4442 | -void |
4443 | -ido_detail_label_set_count (IdoDetailLabel *label, |
4444 | - gint count) |
4445 | -{ |
4446 | - gchar *text; |
4447 | - |
4448 | - g_return_if_fail (IDO_IS_DETAIL_LABEL (label)); |
4449 | - |
4450 | - text = g_strdup_printf ("%d", count); |
4451 | - ido_detail_label_set_text_impl (label, text, TRUE); |
4452 | - g_free (text); |
4453 | -} |
4454 | |
4455 | === removed file 'src/ido-detail-label.h' |
4456 | --- src/ido-detail-label.h 2013-08-20 08:53:01 +0000 |
4457 | +++ src/ido-detail-label.h 1970-01-01 00:00:00 +0000 |
4458 | @@ -1,59 +0,0 @@ |
4459 | -/* |
4460 | - * Copyright 2012 Canonical Ltd. |
4461 | - * |
4462 | - * This program is free software: you can redistribute it and/or modify it |
4463 | - * under the terms of the GNU General Public License version 3, as published |
4464 | - * by the Free Software Foundation. |
4465 | - * |
4466 | - * This program is distributed in the hope that it will be useful, but |
4467 | - * WITHOUT ANY WARRANTY; without even the implied warranties of |
4468 | - * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
4469 | - * PURPOSE. See the GNU General Public License for more details. |
4470 | - * |
4471 | - * You should have received a copy of the GNU General Public License along |
4472 | - * with this program. If not, see <http://www.gnu.org/licenses/>. |
4473 | - * |
4474 | - * Authors: |
4475 | - * Lars Uebernickel <lars.uebernickel@canonical.com> |
4476 | - */ |
4477 | - |
4478 | -#ifndef __IDO_DETAIL_LABEL_H__ |
4479 | -#define __IDO_DETAIL_LABEL_H__ |
4480 | - |
4481 | -#include <gtk/gtk.h> |
4482 | - |
4483 | -#define IDO_TYPE_DETAIL_LABEL (ido_detail_label_get_type()) |
4484 | -#define IDO_DETAIL_LABEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), IDO_TYPE_DETAIL_LABEL, IdoDetailLabel)) |
4485 | -#define IDO_DETAIL_LABEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), IDO_TYPE_DETAIL_LABEL, IdoDetailLabelClass)) |
4486 | -#define IDO_IS_DETAIL_LABEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), IDO_TYPE_DETAIL_LABEL)) |
4487 | -#define IDO_IS_DETAIL_LABEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), IDO_TYPE_DETAIL_LABEL)) |
4488 | -#define IDO_DETAIL_LABEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), IDO_TYPE_DETAIL_LABEL, IdoDetailLabelClass)) |
4489 | - |
4490 | -typedef struct _IdoDetailLabel IdoDetailLabel; |
4491 | -typedef struct _IdoDetailLabelClass IdoDetailLabelClass; |
4492 | -typedef struct _IdoDetailLabelPrivate IdoDetailLabelPrivate; |
4493 | - |
4494 | -struct _IdoDetailLabel |
4495 | -{ |
4496 | - GtkWidget parent; |
4497 | - IdoDetailLabelPrivate *priv; |
4498 | -}; |
4499 | - |
4500 | -struct _IdoDetailLabelClass |
4501 | -{ |
4502 | - GtkWidgetClass parent_class; |
4503 | -}; |
4504 | - |
4505 | -GType ido_detail_label_get_type (void) G_GNUC_CONST; |
4506 | - |
4507 | -GtkWidget * ido_detail_label_new (const gchar *str); |
4508 | - |
4509 | -const gchar * ido_detail_label_get_text (IdoDetailLabel *label); |
4510 | - |
4511 | -void ido_detail_label_set_text (IdoDetailLabel *label, |
4512 | - const gchar *text); |
4513 | - |
4514 | -void ido_detail_label_set_count (IdoDetailLabel *label, |
4515 | - gint count); |
4516 | - |
4517 | -#endif |
4518 | |
4519 | === removed file 'src/ido-menu-item.c' |
4520 | --- src/ido-menu-item.c 2013-08-20 08:53:01 +0000 |
4521 | +++ src/ido-menu-item.c 1970-01-01 00:00:00 +0000 |
4522 | @@ -1,439 +0,0 @@ |
4523 | -/* |
4524 | - * Copyright 2012 Canonical Ltd. |
4525 | - * |
4526 | - * This program is free software: you can redistribute it and/or modify it |
4527 | - * under the terms of the GNU General Public License version 3, as published |
4528 | - * by the Free Software Foundation. |
4529 | - * |
4530 | - * This program is distributed in the hope that it will be useful, but |
4531 | - * WITHOUT ANY WARRANTY; without even the implied warranties of |
4532 | - * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
4533 | - * PURPOSE. See the GNU General Public License for more details. |
4534 | - * |
4535 | - * You should have received a copy of the GNU General Public License along |
4536 | - * with this program. If not, see <http://www.gnu.org/licenses/>. |
4537 | - * |
4538 | - * Authors: |
4539 | - * Lars Uebernickel <lars.uebernickel@canonical.com> |
4540 | - */ |
4541 | - |
4542 | -#include "ido-menu-item.h" |
4543 | - |
4544 | -struct _IdoMenuItemPrivate |
4545 | -{ |
4546 | - GActionGroup *action_group; |
4547 | - gchar *action; |
4548 | - GVariant *target; |
4549 | - |
4550 | - GtkWidget *icon; |
4551 | - GtkWidget *label; |
4552 | - |
4553 | - gboolean has_indicator; |
4554 | - gboolean in_set_active; |
4555 | -}; |
4556 | - |
4557 | -enum |
4558 | -{ |
4559 | - PROP_0, |
4560 | - PROP_MENU_ITEM, |
4561 | - PROP_ACTION_GROUP, |
4562 | - NUM_PROPERTIES |
4563 | -}; |
4564 | - |
4565 | -static GParamSpec *properties[NUM_PROPERTIES]; |
4566 | - |
4567 | -G_DEFINE_TYPE (IdoMenuItem, ido_menu_item, GTK_TYPE_CHECK_MENU_ITEM); |
4568 | - |
4569 | -static void |
4570 | -ido_menu_item_constructed (GObject *object) |
4571 | -{ |
4572 | - IdoMenuItemPrivate *priv = IDO_MENU_ITEM (object)->priv; |
4573 | - GtkWidget *grid; |
4574 | - |
4575 | - priv->icon = g_object_ref (gtk_image_new ()); |
4576 | - gtk_widget_set_margin_right (priv->icon, 6); |
4577 | - |
4578 | - priv->label = g_object_ref (gtk_label_new ("")); |
4579 | - |
4580 | - grid = gtk_grid_new (); |
4581 | - gtk_grid_attach (GTK_GRID (grid), priv->icon, 0, 0, 1, 1); |
4582 | - gtk_grid_attach (GTK_GRID (grid), priv->label, 1, 0, 1, 1); |
4583 | - |
4584 | - gtk_container_add (GTK_CONTAINER (object), grid); |
4585 | - gtk_widget_show_all (grid); |
4586 | - |
4587 | - G_OBJECT_CLASS (ido_menu_item_parent_class)->constructed (object); |
4588 | -} |
4589 | - |
4590 | -static void |
4591 | -ido_menu_item_set_active (IdoMenuItem *self, |
4592 | - gboolean active) |
4593 | -{ |
4594 | - /* HACK gtk_check_menu_item_set_active calls gtk_menu_item_activate. |
4595 | - * Make sure our activate handler doesn't toggle the action as a |
4596 | - * result of calling this function. */ |
4597 | - |
4598 | - self->priv->in_set_active = TRUE; |
4599 | - gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (self), active); |
4600 | - self->priv->in_set_active = FALSE; |
4601 | -} |
4602 | - |
4603 | -static void |
4604 | -ido_menu_item_set_has_indicator (IdoMenuItem *self, |
4605 | - gboolean has_indicator) |
4606 | -{ |
4607 | - if (has_indicator == self->priv->has_indicator) |
4608 | - return; |
4609 | - |
4610 | - self->priv->has_indicator = has_indicator; |
4611 | - |
4612 | - gtk_widget_queue_resize (GTK_WIDGET (self)); |
4613 | -} |
4614 | - |
4615 | -static void |
4616 | -ido_menu_item_set_state (IdoMenuItem *self, |
4617 | - GVariant *state) |
4618 | -{ |
4619 | - IdoMenuItemPrivate *priv = self->priv; |
4620 | - |
4621 | - if (priv->target) |
4622 | - { |
4623 | - ido_menu_item_set_has_indicator (self, TRUE); |
4624 | - ido_menu_item_set_active (self, FALSE); |
4625 | - gtk_check_menu_item_set_draw_as_radio (GTK_CHECK_MENU_ITEM (self), TRUE); |
4626 | - gtk_check_menu_item_set_inconsistent (GTK_CHECK_MENU_ITEM (self), FALSE); |
4627 | - |
4628 | - if (g_variant_is_of_type (state, G_VARIANT_TYPE_STRING)) |
4629 | - { |
4630 | - ido_menu_item_set_active (self, g_variant_equal (priv->target, state)); |
4631 | - } |
4632 | - else if (g_variant_is_of_type (state, G_VARIANT_TYPE ("as")) && |
4633 | - g_variant_is_of_type (priv->target, G_VARIANT_TYPE_STRING)) |
4634 | - { |
4635 | - const gchar *target_str; |
4636 | - const gchar **state_strs; |
4637 | - const gchar **it; |
4638 | - |
4639 | - target_str = g_variant_get_string (priv->target, NULL); |
4640 | - state_strs = g_variant_get_strv (state, NULL); |
4641 | - |
4642 | - it = state_strs; |
4643 | - while (*it != NULL && !g_str_equal (*it, target_str)) |
4644 | - it++; |
4645 | - |
4646 | - if (*it != NULL) |
4647 | - { |
4648 | - ido_menu_item_set_active (self, TRUE); |
4649 | - gtk_check_menu_item_set_inconsistent (GTK_CHECK_MENU_ITEM (self), |
4650 | - g_strv_length ((gchar **)state_strs) > 1); |
4651 | - } |
4652 | - |
4653 | - g_free (state_strs); |
4654 | - } |
4655 | - } |
4656 | - else if (g_variant_is_of_type (state, G_VARIANT_TYPE_BOOLEAN)) |
4657 | - { |
4658 | - ido_menu_item_set_has_indicator (self, TRUE); |
4659 | - gtk_check_menu_item_set_draw_as_radio (GTK_CHECK_MENU_ITEM (self), FALSE); |
4660 | - ido_menu_item_set_active (self, g_variant_get_boolean (state)); |
4661 | - } |
4662 | - else |
4663 | - { |
4664 | - ido_menu_item_set_has_indicator (self, FALSE); |
4665 | - } |
4666 | -} |
4667 | - |
4668 | -static void |
4669 | -ido_menu_item_set_action_name (IdoMenuItem *self, |
4670 | - const gchar *action_name) |
4671 | -{ |
4672 | - IdoMenuItemPrivate *priv = self->priv; |
4673 | - gboolean enabled = FALSE; |
4674 | - GVariant *state; |
4675 | - const GVariantType *param_type; |
4676 | - |
4677 | - if (priv->action != NULL) |
4678 | - g_free (priv->action); |
4679 | - |
4680 | - priv->action = g_strdup (action_name); |
4681 | - |
4682 | - if (priv->action_group != NULL && priv->action != NULL && |
4683 | - g_action_group_query_action (priv->action_group, priv->action, |
4684 | - &enabled, ¶m_type, NULL, NULL, &state)) |
4685 | - { |
4686 | - gtk_widget_set_sensitive (GTK_WIDGET (self), enabled); |
4687 | - |
4688 | - if (state) |
4689 | - { |
4690 | - ido_menu_item_set_state (self, state); |
4691 | - g_variant_unref (state); |
4692 | - } |
4693 | - } |
4694 | - else |
4695 | - { |
4696 | - ido_menu_item_set_active (self, FALSE); |
4697 | - gtk_widget_set_sensitive (GTK_WIDGET (self), FALSE); |
4698 | - ido_menu_item_set_has_indicator (self, FALSE); |
4699 | - } |
4700 | -} |
4701 | - |
4702 | -static void |
4703 | -ido_menu_item_action_added (GActionGroup *action_group, |
4704 | - gchar *action_name, |
4705 | - gpointer user_data) |
4706 | -{ |
4707 | - IdoMenuItem *self = user_data; |
4708 | - |
4709 | - if (g_strcmp0 (self->priv->action, action_name) == 0) |
4710 | - ido_menu_item_set_action_name (self, action_name); |
4711 | -} |
4712 | - |
4713 | -static void |
4714 | -ido_menu_item_action_removed (GActionGroup *action_group, |
4715 | - gchar *action_name, |
4716 | - gpointer user_data) |
4717 | -{ |
4718 | - IdoMenuItem *self = user_data; |
4719 | - |
4720 | - if (g_strcmp0 (self->priv->action, action_name) == 0) |
4721 | - { |
4722 | - gtk_widget_set_sensitive (GTK_WIDGET (self), FALSE); |
4723 | - } |
4724 | -} |
4725 | - |
4726 | -static void |
4727 | -ido_menu_item_action_enabled_changed (GActionGroup *action_group, |
4728 | - gchar *action_name, |
4729 | - gboolean enabled, |
4730 | - gpointer user_data) |
4731 | -{ |
4732 | - IdoMenuItem *self = user_data; |
4733 | - |
4734 | - if (g_strcmp0 (self->priv->action, action_name) == 0) |
4735 | - gtk_widget_set_sensitive (GTK_WIDGET (self), enabled); |
4736 | -} |
4737 | - |
4738 | -static void |
4739 | -ido_menu_item_action_state_changed (GActionGroup *action_group, |
4740 | - gchar *action_name, |
4741 | - GVariant *value, |
4742 | - gpointer user_data) |
4743 | -{ |
4744 | - IdoMenuItem *self = user_data; |
4745 | - |
4746 | - if (g_strcmp0 (self->priv->action, action_name) == 0) |
4747 | - ido_menu_item_set_state (self, value); |
4748 | -} |
4749 | - |
4750 | -static void |
4751 | -ido_menu_set_property (GObject *object, |
4752 | - guint property_id, |
4753 | - const GValue *value, |
4754 | - GParamSpec *pspec) |
4755 | -{ |
4756 | - IdoMenuItem *self = IDO_MENU_ITEM (object); |
4757 | - |
4758 | - switch (property_id) |
4759 | - { |
4760 | - case PROP_MENU_ITEM: |
4761 | - ido_menu_item_set_menu_item (self, G_MENU_ITEM (g_value_get_object (value))); |
4762 | - break; |
4763 | - |
4764 | - case PROP_ACTION_GROUP: |
4765 | - ido_menu_item_set_action_group (self, G_ACTION_GROUP (g_value_get_object (value))); |
4766 | - break; |
4767 | - |
4768 | - default: |
4769 | - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); |
4770 | - } |
4771 | -} |
4772 | - |
4773 | -static void |
4774 | -ido_menu_item_dispose (GObject *object) |
4775 | -{ |
4776 | - IdoMenuItem *self = IDO_MENU_ITEM (object); |
4777 | - |
4778 | - if (self->priv->action_group) |
4779 | - ido_menu_item_set_action_group (self, NULL); |
4780 | - |
4781 | - g_clear_object (&self->priv->icon); |
4782 | - g_clear_object (&self->priv->label); |
4783 | - |
4784 | - if (self->priv->target) |
4785 | - { |
4786 | - g_variant_unref (self->priv->target); |
4787 | - self->priv->target = NULL; |
4788 | - } |
4789 | - |
4790 | - G_OBJECT_CLASS (ido_menu_item_parent_class)->dispose (object); |
4791 | -} |
4792 | - |
4793 | -static void |
4794 | -ido_menu_item_finalize (GObject *object) |
4795 | -{ |
4796 | - IdoMenuItemPrivate *priv = IDO_MENU_ITEM (object)->priv; |
4797 | - |
4798 | - g_free (priv->action); |
4799 | - |
4800 | - G_OBJECT_CLASS (ido_menu_item_parent_class)->finalize (object); |
4801 | -} |
4802 | - |
4803 | -static void |
4804 | -ido_menu_item_activate (GtkMenuItem *item) |
4805 | -{ |
4806 | - IdoMenuItemPrivate *priv = IDO_MENU_ITEM (item)->priv; |
4807 | - GVariant *parameter; |
4808 | - |
4809 | - /* see ido_menu_item_set_active */ |
4810 | - if (!priv->in_set_active && priv->action && priv->action_group) |
4811 | - { |
4812 | - guint32 event_time = gtk_get_current_event_time (); |
4813 | - |
4814 | - if (priv->target) |
4815 | - { |
4816 | - parameter = priv->target; |
4817 | - } |
4818 | - else |
4819 | - { |
4820 | - parameter = g_variant_new_uint32 (event_time); |
4821 | - } |
4822 | - |
4823 | - g_action_group_activate_action (priv->action_group, priv->action, parameter); |
4824 | - } |
4825 | - |
4826 | - if (priv->in_set_active) |
4827 | - GTK_MENU_ITEM_CLASS (ido_menu_item_parent_class)->activate (item); |
4828 | -} |
4829 | - |
4830 | -static void |
4831 | -ido_menu_item_draw_indicator (GtkCheckMenuItem *item, |
4832 | - cairo_t *cr) |
4833 | -{ |
4834 | - IdoMenuItem *self = IDO_MENU_ITEM (item); |
4835 | - |
4836 | - if (self->priv->has_indicator) |
4837 | - GTK_CHECK_MENU_ITEM_CLASS (ido_menu_item_parent_class) |
4838 | - ->draw_indicator (item, cr); |
4839 | -} |
4840 | - |
4841 | -static void |
4842 | -ido_menu_item_class_init (IdoMenuItemClass *klass) |
4843 | -{ |
4844 | - GObjectClass *object_class = G_OBJECT_CLASS (klass); |
4845 | - GtkMenuItemClass *menu_item_class = GTK_MENU_ITEM_CLASS (klass); |
4846 | - GtkCheckMenuItemClass *check_class = GTK_CHECK_MENU_ITEM_CLASS (klass); |
4847 | - |
4848 | - g_type_class_add_private (klass, sizeof (IdoMenuItemPrivate)); |
4849 | - |
4850 | - object_class->constructed = ido_menu_item_constructed; |
4851 | - object_class->set_property = ido_menu_set_property; |
4852 | - object_class->dispose = ido_menu_item_dispose; |
4853 | - object_class->finalize = ido_menu_item_finalize; |
4854 | - |
4855 | - menu_item_class->activate = ido_menu_item_activate; |
4856 | - |
4857 | - check_class->draw_indicator = ido_menu_item_draw_indicator; |
4858 | - |
4859 | - properties[PROP_MENU_ITEM] = g_param_spec_object ("menu-item", |
4860 | - "Menu item", |
4861 | - "The model GMenuItem for this menu item", |
4862 | - G_TYPE_MENU_ITEM, |
4863 | - G_PARAM_WRITABLE | |
4864 | - G_PARAM_STATIC_STRINGS); |
4865 | - |
4866 | - properties[PROP_ACTION_GROUP] = g_param_spec_object ("action-group", |
4867 | - "Action group", |
4868 | - "The action group associated with this menu item", |
4869 | - G_TYPE_ACTION_GROUP, |
4870 | - G_PARAM_WRITABLE | |
4871 | - G_PARAM_STATIC_STRINGS); |
4872 | - |
4873 | - g_object_class_install_properties (object_class, NUM_PROPERTIES, properties); |
4874 | -} |
4875 | - |
4876 | -static void |
4877 | -ido_menu_item_init (IdoMenuItem *self) |
4878 | -{ |
4879 | - self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, |
4880 | - IDO_TYPE_MENU_ITEM, |
4881 | - IdoMenuItemPrivate); |
4882 | -} |
4883 | - |
4884 | -void |
4885 | -ido_menu_item_set_menu_item (IdoMenuItem *self, |
4886 | - GMenuItem *menuitem) |
4887 | -{ |
4888 | - gchar *iconstr = NULL; |
4889 | - GIcon *icon = NULL; |
4890 | - gchar *label = NULL; |
4891 | - gchar *action = NULL; |
4892 | - |
4893 | - if (g_menu_item_get_attribute (menuitem, "x-canonical-icon", "s", &iconstr)) |
4894 | - { |
4895 | - GError *error; |
4896 | - |
4897 | - /* only indent the label if icon is set to "" */ |
4898 | - if (iconstr[0] == '\0') |
4899 | - { |
4900 | - gint width; |
4901 | - |
4902 | - gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &width, NULL); |
4903 | - gtk_widget_set_size_request (self->priv->icon, width, -1); |
4904 | - } |
4905 | - else |
4906 | - { |
4907 | - icon = g_icon_new_for_string (iconstr, &error); |
4908 | - if (icon == NULL) |
4909 | - { |
4910 | - g_warning ("unable to set icon: %s", error->message); |
4911 | - g_error_free (error); |
4912 | - } |
4913 | - } |
4914 | - g_free (iconstr); |
4915 | - } |
4916 | - gtk_image_set_from_gicon (GTK_IMAGE (self->priv->icon), icon, GTK_ICON_SIZE_MENU); |
4917 | - |
4918 | - g_menu_item_get_attribute (menuitem, "label", "s", &label); |
4919 | - gtk_label_set_label (GTK_LABEL (self->priv->label), label ? label : ""); |
4920 | - |
4921 | - self->priv->target = g_menu_item_get_attribute_value (menuitem, "target", NULL); |
4922 | - |
4923 | - g_menu_item_get_attribute (menuitem, "action", "s", &action); |
4924 | - ido_menu_item_set_action_name (self, action); |
4925 | - |
4926 | - if (icon) |
4927 | - g_object_unref (icon); |
4928 | - g_free (label); |
4929 | - g_free (action); |
4930 | -} |
4931 | - |
4932 | -void |
4933 | -ido_menu_item_set_action_group (IdoMenuItem *self, |
4934 | - GActionGroup *action_group) |
4935 | -{ |
4936 | - IdoMenuItemPrivate *priv = self->priv; |
4937 | - |
4938 | - if (priv->action_group != NULL) |
4939 | - { |
4940 | - g_signal_handlers_disconnect_by_func (priv->action_group, ido_menu_item_action_added, self); |
4941 | - g_signal_handlers_disconnect_by_func (priv->action_group, ido_menu_item_action_removed, self); |
4942 | - g_signal_handlers_disconnect_by_func (priv->action_group, ido_menu_item_action_enabled_changed, self); |
4943 | - g_signal_handlers_disconnect_by_func (priv->action_group, ido_menu_item_action_state_changed, self); |
4944 | - |
4945 | - g_clear_object (&priv->action_group); |
4946 | - } |
4947 | - |
4948 | - if (action_group != NULL) |
4949 | - { |
4950 | - priv->action_group = g_object_ref (action_group); |
4951 | - |
4952 | - g_signal_connect (priv->action_group, "action-added", |
4953 | - G_CALLBACK (ido_menu_item_action_added), self); |
4954 | - g_signal_connect (priv->action_group, "action-removed", |
4955 | - G_CALLBACK (ido_menu_item_action_removed), self); |
4956 | - g_signal_connect (priv->action_group, "action-enabled-changed", |
4957 | - G_CALLBACK (ido_menu_item_action_enabled_changed), self); |
4958 | - g_signal_connect (priv->action_group, "action-state-changed", |
4959 | - G_CALLBACK (ido_menu_item_action_state_changed), self); |
4960 | - } |
4961 | -} |
4962 | |
4963 | === removed file 'src/ido-menu-item.h' |
4964 | --- src/ido-menu-item.h 2013-08-20 08:53:01 +0000 |
4965 | +++ src/ido-menu-item.h 1970-01-01 00:00:00 +0000 |
4966 | @@ -1,54 +0,0 @@ |
4967 | -/* |
4968 | - * Copyright 2012 Canonical Ltd. |
4969 | - * |
4970 | - * This program is free software: you can redistribute it and/or modify it |
4971 | - * under the terms of the GNU General Public License version 3, as published |
4972 | - * by the Free Software Foundation. |
4973 | - * |
4974 | - * This program is distributed in the hope that it will be useful, but |
4975 | - * WITHOUT ANY WARRANTY; without even the implied warranties of |
4976 | - * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
4977 | - * PURPOSE. See the GNU General Public License for more details. |
4978 | - * |
4979 | - * You should have received a copy of the GNU General Public License along |
4980 | - * with this program. If not, see <http://www.gnu.org/licenses/>. |
4981 | - * |
4982 | - * Authors: |
4983 | - * Lars Uebernickel <lars.uebernickel@canonical.com> |
4984 | - */ |
4985 | - |
4986 | -#ifndef __IDO_MENU_ITEM_H__ |
4987 | -#define __IDO_MENU_ITEM_H__ |
4988 | - |
4989 | -#include <gtk/gtk.h> |
4990 | - |
4991 | -#define IDO_TYPE_MENU_ITEM (ido_menu_item_get_type ()) |
4992 | -#define IDO_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), IDO_TYPE_MENU_ITEM, IdoMenuItem)) |
4993 | -#define IDO_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), IDO_TYPE_MENU_ITEM, IdoMenuItemClass)) |
4994 | -#define IS_IDO_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), IDO_TYPE_MENU_ITEM)) |
4995 | -#define IS_IDO_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), IDO_TYPE_MENU_ITEM)) |
4996 | -#define IDO_MENU_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), IDO_TYPE_MENU_ITEM, IdoMenuItemClass)) |
4997 | - |
4998 | -typedef struct _IdoMenuItem IdoMenuItem; |
4999 | -typedef struct _IdoMenuItemClass IdoMenuItemClass; |
5000 | -typedef struct _IdoMenuItemPrivate IdoMenuItemPrivate; |
Thanks Pete, there is a merge conflict in src/im- desktop- menu.c there though. Would it also be possible to have the previous branch re-used? e.g show the fix as a different commit, would make things easier to review