├── .gitignore ├── .uncrustify ├── AUTHORS ├── LICENSE ├── README.md ├── data ├── appmenu.ui ├── icons │ ├── 16x16 │ │ └── news.png │ ├── 22x22 │ │ └── news.png │ ├── 24x24 │ │ └── news.png │ ├── 256x256 │ │ └── news.png │ ├── 32x32 │ │ └── news.png │ ├── 48x48 │ │ └── news.png │ ├── 512x512 │ │ └── news.png │ ├── gnome-news.svg │ ├── hicolor_apps_symbolic_gnome-news-symbolic.svg │ └── meson.build ├── meson.build ├── news-resource.xml ├── org.gnome.News.desktop ├── screenshots │ ├── feed.png │ ├── list.png │ ├── news-article.png │ ├── news-flow.png │ ├── news-list.png │ ├── newsv2.png │ ├── search.png │ └── start.png ├── theme │ ├── Adwaita.css │ └── articlebox.html └── ui │ ├── article.ui │ ├── articlerow.ui │ └── window.ui ├── meson.build ├── package └── PKGBUILD └── src ├── controller.vala ├── feed.vala ├── main.vala ├── meson.build ├── post.vala ├── tracker.vala ├── ui ├── application-window.vala ├── application.vala ├── article-box.vala ├── article-list.vala ├── article-view.vala ├── feed-view.vala ├── new-view.vala ├── search-view.vala ├── star-view.vala ├── switchable.vala ├── updateable.vala └── widget-factory.vala └── worker ├── company.vala ├── image-loader.vala └── worker.vala /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | 3 | -------------------------------------------------------------------------------- /.uncrustify: -------------------------------------------------------------------------------- 1 | # Uncrustify 0.60 2 | # Rules for vala 3 | # Version: 0.5 4 | 5 | # 6 | # General options 7 | # 8 | 9 | # The type of line endings 10 | newlines = auto # auto/lf/crlf/cr 11 | 12 | # The original size of tabs in the input 13 | input_tab_size = 8 # number 14 | 15 | # The size of tabs in the output (only used if align_with_tabs=true) 16 | output_tab_size = 4 # number 17 | 18 | # The ASCII value of the string escape char, usually 92 (\) or 94 (^). (Pawn) 19 | string_escape_char = 92 # number 20 | 21 | # Alternate string escape char for Pawn. Only works right before the quote char. 22 | string_escape_char2 = 0 # number 23 | 24 | # Allow interpreting '>=' and '>>=' as part of a template in 'void f(list>=val);'. 25 | # If true (default), 'assert(x<0 && y>=3)' will be broken. 26 | # Improvements to template detection may make this option obsolete. 27 | tok_split_gte = false # false/true 28 | 29 | # Control what to do with the UTF-8 BOM (recommend 'remove') 30 | utf8_bom = ignore # ignore/add/remove/force 31 | 32 | # If the file contains bytes with values between 128 and 255, but is not UTF-8, then output as UTF-8 33 | utf8_byte = false # false/true 34 | 35 | # Force the output encoding to UTF-8 36 | utf8_force = false # false/true 37 | 38 | # 39 | # Indenting 40 | # 41 | 42 | # The number of columns to indent per level. 43 | # Usually 2, 3, 4, or 8. 44 | indent_columns = 4 # number 45 | 46 | # The continuation indent. If non-zero, this overrides the indent of '(' and '=' continuation indents. 47 | # For FreeBSD, this is set to 4. Negative value is absolute and not increased for each ( level 48 | indent_continue = 0 # number 49 | 50 | # How to use tabs when indenting code 51 | # 0=spaces only 52 | # 1=indent with tabs to brace level, align with spaces 53 | # 2=indent and align with tabs, using spaces when not on a tabstop 54 | indent_with_tabs = 0 # number 55 | 56 | # Comments that are not a brace level are indented with tabs on a tabstop. 57 | # Requires indent_with_tabs=2. If false, will use spaces. 58 | indent_cmt_with_tabs = false # false/true 59 | 60 | # Whether to indent strings broken by '\' so that they line up 61 | indent_align_string = false # false/true 62 | 63 | # The number of spaces to indent multi-line XML strings. 64 | # Requires indent_align_string=True 65 | indent_xml_string = 0 # number 66 | 67 | # Spaces to indent '{' from level 68 | indent_brace = 0 # number 69 | 70 | # Whether braces are indented to the body level 71 | indent_braces = false # false/true 72 | 73 | # Disabled indenting function braces if indent_braces is true 74 | indent_braces_no_func = false # false/true 75 | 76 | # Disabled indenting class braces if indent_braces is true 77 | indent_braces_no_class = false # false/true 78 | 79 | # Disabled indenting struct braces if indent_braces is true 80 | indent_braces_no_struct = false # false/true 81 | 82 | # Indent based on the size of the brace parent, i.e. 'if' => 3 spaces, 'for' => 4 spaces, etc. 83 | indent_brace_parent = false # false/true 84 | 85 | # Whether the 'namespace' body is indented 86 | indent_namespace = true # false/true 87 | 88 | # The number of spaces to indent a namespace block 89 | indent_namespace_level = 0 # number 90 | 91 | # If the body of the namespace is longer than this number, it won't be indented. 92 | # Requires indent_namespace=true. Default=0 (no limit) 93 | indent_namespace_limit = 0 # number 94 | 95 | # Whether the 'extern "C"' body is indented 96 | indent_extern = false # false/true 97 | 98 | # Whether the 'class' body is indented 99 | indent_class = true # false/true 100 | 101 | # Whether to indent the stuff after a leading class colon 102 | indent_class_colon = false # false/true 103 | # Whether to indent the stuff after a leading class initializer colon 104 | indent_constr_colon = false # false/true 105 | 106 | # Virtual indent from the ':' for member initializers. Default is 2 107 | indent_ctor_init_leading = 2 # number 108 | 109 | # Additional indenting for constructor initializer list 110 | indent_ctor_init = 0 # number 111 | 112 | # False=treat 'else\nif' as 'else if' for indenting purposes 113 | # True=indent the 'if' one level 114 | indent_else_if = false # false/true 115 | 116 | # Amount to indent variable declarations after a open brace. neg=relative, pos=absolute 117 | indent_var_def_blk = 0 # number 118 | 119 | # Indent continued variable declarations instead of aligning. 120 | indent_var_def_cont = false # false/true 121 | 122 | # True: force indentation of function definition to start in column 1 123 | # False: use the default behavior 124 | indent_func_def_force_col1 = false # false/true 125 | 126 | # True: indent continued function call parameters one indent level 127 | # False: align parameters under the open paren 128 | indent_func_call_param = false # false/true 129 | 130 | # Same as indent_func_call_param, but for function defs 131 | indent_func_def_param = false # false/true 132 | 133 | # Same as indent_func_call_param, but for function protos 134 | indent_func_proto_param = false # false/true 135 | 136 | # Same as indent_func_call_param, but for class declarations 137 | indent_func_class_param = false # false/true 138 | 139 | # Same as indent_func_call_param, but for class variable constructors 140 | indent_func_ctor_var_param = false # false/true 141 | 142 | # Same as indent_func_call_param, but for templates 143 | indent_template_param = false # false/true 144 | 145 | # Double the indent for indent_func_xxx_param options 146 | indent_func_param_double = false # false/true 147 | 148 | # Indentation column for standalone 'const' function decl/proto qualifier 149 | indent_func_const = 0 # number 150 | 151 | # Indentation column for standalone 'throw' function decl/proto qualifier 152 | indent_func_throw = 0 # number 153 | 154 | # The number of spaces to indent a continued '->' or '.' 155 | # Usually set to 0, 1, or indent_columns. 156 | indent_member = 1 # number 157 | 158 | # Spaces to indent single line ('//') comments on lines before code 159 | indent_sing_line_comments = 0 # number 160 | 161 | # If set, will indent trailing single line ('//') comments relative 162 | # to the code instead of trying to keep the same absolute column 163 | indent_relative_single_line_comments = false # false/true 164 | 165 | # Spaces to indent 'case' from 'switch' 166 | # Usually 0 or indent_columns. 167 | indent_switch_case = 0 # number 168 | 169 | # Spaces to shift the 'case' line, without affecting any other lines 170 | # Usually 0. 171 | indent_case_shift = 0 # number 172 | 173 | # Spaces to indent '{' from 'case'. 174 | # By default, the brace will appear under the 'c' in case. 175 | # Usually set to 0 or indent_columns. 176 | indent_case_brace = 0 # number 177 | 178 | # Whether to indent comments found in first column 179 | indent_col1_comment = false # false/true 180 | 181 | # How to indent goto labels 182 | # >0 : absolute column where 1 is the leftmost column 183 | # <=0 : subtract from brace indent 184 | indent_label = 1 # number 185 | 186 | # Same as indent_label, but for access specifiers that are followed by a colon 187 | indent_access_spec = 1 # number 188 | 189 | # Indent the code after an access specifier by one level. 190 | # If set, this option forces 'indent_access_spec=0' 191 | indent_access_spec_body = false # false/true 192 | 193 | # If an open paren is followed by a newline, indent the next line so that it lines up after the open paren (not recommended) 194 | indent_paren_nl = false # false/true 195 | 196 | # Controls the indent of a close paren after a newline. 197 | # 0: Indent to body level 198 | # 1: Align under the open paren 199 | # 2: Indent to the brace level 200 | indent_paren_close = 0 # number 201 | 202 | # Controls the indent of a comma when inside a paren.If TRUE, aligns under the open paren 203 | indent_comma_paren = false # false/true 204 | 205 | # Controls the indent of a BOOL operator when inside a paren.If TRUE, aligns under the open paren 206 | indent_bool_paren = false # false/true 207 | 208 | # If 'indent_bool_paren' is true, controls the indent of the first expression. If TRUE, aligns the first expression to the following ones 209 | indent_first_bool_expr = false # false/true 210 | 211 | # If an open square is followed by a newline, indent the next line so that it lines up after the open square (not recommended) 212 | indent_square_nl = false # false/true 213 | 214 | # Don't change the relative indent of ESQL/C 'EXEC SQL' bodies 215 | indent_preserve_sql = false # false/true 216 | 217 | # Align continued statements at the '='. Default=True 218 | # If FALSE or the '=' is followed by a newline, the next line is indent one tab. 219 | indent_align_assign = true # false/true 220 | 221 | # Indent OC blocks at brace level instead of usual rules. 222 | indent_oc_block = false # false/true 223 | 224 | # Indent OC blocks in a message relative to the parameter name. 225 | # 0=use indent_oc_block rules, 1+=spaces to indent 226 | indent_oc_block_msg = 0 # number 227 | 228 | # Minimum indent for subsequent parameters 229 | indent_oc_msg_colon = 0 # number 230 | 231 | # Objective C 232 | 233 | # If true, prioritize aligning with initial colon (and stripping spaces from lines, if necessary). 234 | # Default is true. 235 | indent_oc_msg_prioritize_first_colon = true 236 | 237 | # If indent_oc_block_msg and this option are on, blocks will be indented the way that Xcode does by default (from keyword if the parameter is on its own line; otherwise, from the previous indentation level). 238 | indent_oc_block_msg_xcode_style = true 239 | 240 | # If indent_oc_block_msg and this option are on, blocks will be indented from where the brace is relative to a msg keyword. 241 | indent_oc_block_msg_from_keyword = true 242 | 243 | # If indent_oc_block_msg and this option are on, blocks will be indented from where the brace is relative to a msg colon. 244 | indent_oc_block_msg_from_colon = true 245 | 246 | # If indent_oc_block_msg and this option are on, blocks will be indented from where the block caret is. 247 | indent_oc_block_msg_from_caret = true 248 | 249 | # If indent_oc_block_msg and this option are on, blocks will be indented from where the brace is. 250 | indent_oc_block_msg_from_brace = true 251 | 252 | # 253 | # Spacing options 254 | # 255 | 256 | # Add or remove space around arithmetic operator '+', '-', '/', '*', etc 257 | sp_arith = force # ignore/add/remove/force 258 | 259 | # Add or remove space around assignment operator '=', '+=', etc 260 | sp_assign = force # ignore/add/remove/force 261 | 262 | # Add or remove space around '=' in C++11 lambda capture specifications. Overrides sp_assign 263 | sp_cpp_lambda_assign = force # ignore/add/remove/force 264 | 265 | # Add or remove space after the capture specification in C++11 lambda. 266 | sp_cpp_lambda_paren = force # ignore/add/remove/force 267 | 268 | # Add or remove space around assignment operator '=' in a prototype 269 | sp_assign_default = force # ignore/add/remove/force 270 | 271 | # Add or remove space before assignment operator '=', '+=', etc. Overrides sp_assign. 272 | sp_before_assign = force # ignore/add/remove/force 273 | 274 | # Add or remove space after assignment operator '=', '+=', etc. Overrides sp_assign. 275 | sp_after_assign = force # ignore/add/remove/force 276 | 277 | # Add or remove space around assignment '=' in enum 278 | sp_enum_assign = force # ignore/add/remove/force 279 | 280 | # Add or remove space before assignment '=' in enum. Overrides sp_enum_assign. 281 | sp_enum_before_assign = ignore # ignore/add/remove/force 282 | 283 | # Add or remove space after assignment '=' in enum. Overrides sp_enum_assign. 284 | sp_enum_after_assign = force # ignore/add/remove/force 285 | 286 | # Add or remove space around preprocessor '##' concatenation operator. Default=Add 287 | sp_pp_concat = add # ignore/add/remove/force 288 | 289 | # Add or remove space after preprocessor '#' stringify operator. Also affects the '#@' charizing operator. 290 | sp_pp_stringify = ignore # ignore/add/remove/force 291 | 292 | # Add or remove space before preprocessor '#' stringify operator as in '#define x(y) L#y'. 293 | sp_before_pp_stringify = ignore # ignore/add/remove/force 294 | 295 | # Add or remove space around boolean operators '&&' and '||' 296 | sp_bool = force # ignore/add/remove/force 297 | 298 | # Add or remove space around compare operator '<', '>', '==', etc 299 | sp_compare = force # ignore/add/remove/force 300 | 301 | # Add or remove space inside '(' and ')' 302 | sp_inside_paren = remove # ignore/add/remove/force 303 | 304 | # Add or remove space between nested parens 305 | sp_paren_paren = remove # ignore/add/remove/force 306 | 307 | # Add or remove space between back-to-back parens: ')(' vs ') (' 308 | sp_cparen_oparen = remove # ignore/add/remove/force 309 | # Whether to balance spaces inside nested parens 310 | sp_balance_nested_parens = false # false/true 311 | 312 | # Add or remove space between ')' and '{' 313 | sp_paren_brace = force # ignore/add/remove/force 314 | 315 | # Add or remove space before pointer star '*' 316 | sp_before_ptr_star = force # ignore/add/remove/force 317 | 318 | # Add or remove space before pointer star '*' that isn't followed by a variable name 319 | # If set to 'ignore', sp_before_ptr_star is used instead. 320 | sp_before_unnamed_ptr_star = force # ignore/add/remove/force 321 | 322 | # Add or remove space between pointer stars '*' 323 | sp_between_ptr_star = force # ignore/add/remove/force 324 | 325 | # Add or remove space after pointer star '*', if followed by a word. 326 | sp_after_ptr_star = force # ignore/add/remove/force 327 | 328 | # Add or remove space after a pointer star '*', if followed by a func proto/def. 329 | sp_after_ptr_star_func = force # ignore/add/remove/force 330 | 331 | # Add or remove space after a pointer star '*', if followed by an open paren (function types). 332 | sp_ptr_star_paren = force # ignore/add/remove/force 333 | 334 | # Add or remove space before a pointer star '*', if followed by a func proto/def. 335 | sp_before_ptr_star_func = force # ignore/add/remove/force 336 | 337 | # Add or remove space before a reference sign '&' 338 | sp_before_byref = force # ignore/add/remove/force 339 | 340 | # Add or remove space before a reference sign '&' that isn't followed by a variable name 341 | # If set to 'ignore', sp_before_byref is used instead. 342 | sp_before_unnamed_byref = ignore # ignore/add/remove/force 343 | 344 | # Add or remove space after reference sign '&', if followed by a word. 345 | sp_after_byref = ignore # ignore/add/remove/force 346 | 347 | # Add or remove space after a reference sign '&', if followed by a func proto/def. 348 | sp_after_byref_func = remove # ignore/add/remove/force 349 | 350 | # Add or remove space before a reference sign '&', if followed by a func proto/def. 351 | sp_before_byref_func = force # ignore/add/remove/force 352 | 353 | # Add or remove space between type and word. Default=Force 354 | sp_after_type = force # ignore/add/remove/force 355 | 356 | # Add or remove space before the paren in the D constructs 'template Foo(' and 'class Foo('. 357 | sp_before_template_paren = ignore # ignore/add/remove/force 358 | 359 | # Add or remove space in 'template <' vs 'template<'. 360 | # If set to ignore, sp_before_angle is used. 361 | sp_template_angle = ignore # ignore/add/remove/force 362 | 363 | # Add or remove space before '<>' 364 | sp_before_angle = remove # ignore/add/remove/force 365 | 366 | # Add or remove space inside '<' and '>' 367 | sp_inside_angle = remove # ignore/add/remove/force 368 | 369 | # Add or remove space after '<>' 370 | sp_after_angle = remove # ignore/add/remove/force 371 | 372 | # Add or remove space between '<>' and '(' as found in 'new List();' 373 | sp_angle_paren = remove # ignore/add/remove/force 374 | 375 | # Add or remove space between '<>' and a word as in 'List m;' 376 | sp_angle_word = force # ignore/add/remove/force 377 | 378 | # Add or remove space between '>' and '>' in '>>' (template stuff C++/C# only). Default=Add 379 | sp_angle_shift = add # ignore/add/remove/force 380 | 381 | # Permit removal of the space between '>>' in 'foo >' (C++11 only). Default=False 382 | # sp_angle_shift cannot remove the space without this option. 383 | sp_permit_cpp11_shift = false # false/true 384 | 385 | # Add or remove space before '(' of 'if', 'for', 'switch', and 'while' 386 | sp_before_sparen = remove # ignore/add/remove/force 387 | 388 | # Add or remove space inside if-condition '(' and ')' 389 | sp_inside_sparen = add # ignore/add/remove/force 390 | 391 | # Add or remove space before if-condition ')'. Overrides sp_inside_sparen. 392 | sp_inside_sparen_close = ignore # ignore/add/remove/force 393 | 394 | # Add or remove space before if-condition '('. Overrides sp_inside_sparen. 395 | sp_inside_sparen_open = ignore # ignore/add/remove/force 396 | 397 | # Add or remove space after ')' of 'if', 'for', 'switch', and 'while' 398 | sp_after_sparen = remove # ignore/add/remove/force 399 | 400 | # Add or remove space between ')' and '{' of 'if', 'for', 'switch', and 'while' 401 | sp_sparen_brace = remove # ignore/add/remove/force 402 | 403 | # Add or remove space between 'invariant' and '(' in the D language. 404 | sp_invariant_paren = ignore # ignore/add/remove/force 405 | 406 | # Add or remove space after the ')' in 'invariant (C) c' in the D language. 407 | sp_after_invariant_paren = ignore # ignore/add/remove/force 408 | 409 | # Add or remove space before empty statement ';' on 'if', 'for' and 'while' 410 | sp_special_semi = remove # ignore/add/remove/force 411 | 412 | # Add or remove space before ';'. Default=Remove 413 | sp_before_semi = remove # ignore/add/remove/force 414 | 415 | # Add or remove space before ';' in non-empty 'for' statements 416 | sp_before_semi_for = force # ignore/add/remove/force 417 | 418 | # Add or remove space before a semicolon of an empty part of a for statement. 419 | sp_before_semi_for_empty = force # ignore/add/remove/force 420 | 421 | # Add or remove space after ';', except when followed by a comment. Default=Add 422 | sp_after_semi = add # ignore/add/remove/force 423 | 424 | # Add or remove space after ';' in non-empty 'for' statements. Default=Force 425 | sp_after_semi_for = force # ignore/add/remove/force 426 | 427 | # Add or remove space after the final semicolon of an empty part of a for statement: for ( ; ; ). 428 | sp_after_semi_for_empty = force # ignore/add/remove/force 429 | 430 | # Add or remove space before '[' (except '[]') 431 | sp_before_square = remove # ignore/add/remove/force 432 | 433 | # Add or remove space before '[]' 434 | sp_before_squares = remove # ignore/add/remove/force 435 | 436 | # Add or remove space inside a non-empty '[' and ']' 437 | sp_inside_square = remove # ignore/add/remove/force 438 | 439 | # Add or remove space after ',' 440 | sp_after_comma = force # ignore/add/remove/force 441 | 442 | # Add or remove space before ',' 443 | sp_before_comma = remove # ignore/add/remove/force 444 | 445 | # Add or remove space between an open paren and comma: '(,' vs '( ,' 446 | sp_paren_comma = force # ignore/add/remove/force 447 | 448 | # Add or remove space before the variadic '...' when preceded by a non-punctuator 449 | sp_before_ellipsis = remove # ignore/add/remove/force 450 | 451 | # Add or remove space after class ':' 452 | sp_after_class_colon = force # ignore/add/remove/force 453 | 454 | # Add or remove space before class ':' 455 | sp_before_class_colon = force # ignore/add/remove/force 456 | 457 | # Add or remove space after class constructor ':' 458 | sp_after_constr_colon = ignore # ignore/add/remove/force 459 | 460 | # Add or remove space before class constructor ':' 461 | sp_before_constr_colon = ignore # ignore/add/remove/force 462 | 463 | # Add or remove space before case ':'. Default=Remove 464 | sp_before_case_colon = remove # ignore/add/remove/force 465 | 466 | # Add or remove space between 'operator' and operator sign 467 | sp_after_operator = force # ignore/add/remove/force 468 | 469 | # Add or remove space between the operator symbol and the open paren, as in 'operator ++(' 470 | sp_after_operator_sym = ignore # ignore/add/remove/force 471 | 472 | # Add or remove space after C/D cast, i.e. 'cast(int)a' vs 'cast(int) a' or '(int)a' vs '(int) a' 473 | sp_after_cast = force # ignore/add/remove/force 474 | 475 | # Add or remove spaces inside cast parens 476 | sp_inside_paren_cast = remove # ignore/add/remove/force 477 | 478 | # Add or remove space between the type and open paren in a C++ cast, i.e. 'int(exp)' vs 'int (exp)' 479 | sp_cpp_cast_paren = ignore # ignore/add/remove/force 480 | 481 | # Add or remove space between 'sizeof' and '(' 482 | sp_sizeof_paren = force # ignore/add/remove/force 483 | 484 | # Add or remove space after the tag keyword (Pawn) 485 | sp_after_tag = ignore # ignore/add/remove/force 486 | 487 | # Add or remove space inside enum '{' and '}' 488 | sp_inside_braces_enum = force # ignore/add/remove/force 489 | 490 | # Add or remove space inside struct/union '{' force '}' 491 | sp_inside_braces_struct = force # ignore/add/remove/force 492 | 493 | # Add or remove space inside '{' and '}' 494 | sp_inside_braces = force # ignore/add/remove/force 495 | 496 | # Add or remove space inside '{}' 497 | sp_inside_braces_empty = remove # ignore/add/remove/force 498 | 499 | # Add or remove space between return type and function name 500 | # A minimum of 1 is forced except for pointer return types. 501 | sp_type_func = remove # ignore/add/remove/force 502 | 503 | # Add or remove space between function name and '(' on function declaration 504 | sp_func_proto_paren = remove # ignore/add/remove/force 505 | 506 | # CARL duplicates ERROR ?? 507 | # Add or remove space between function name and '(' on function definition 508 | sp_func_def_paren = remove # ignore/add/remove/force 509 | 510 | # Add or remove space inside empty function '()' 511 | sp_inside_fparens = remove # ignore/add/remove/force 512 | 513 | # Add or remove space inside function '(' and ')' 514 | sp_inside_fparen = remove # ignore/add/remove/force 515 | 516 | # Add or remove space inside the first parens in the function type: 'void (*x)(...)' 517 | sp_inside_tparen = remove # ignore/add/remove/force 518 | 519 | # Add or remove between the parens in the function type: 'void (*x)(...)' 520 | sp_after_tparen_close = remove # ignore/add/remove/force 521 | 522 | # Add or remove space between ']' and '(' when part of a function call. 523 | sp_square_fparen = remove # ignore/add/remove/force 524 | 525 | # Add or remove space between ')' and '{' of function 526 | sp_fparen_brace = force # ignore/add/remove/force 527 | 528 | # Add or remove space between function name and '(' on function calls 529 | sp_func_call_paren = force # ignore/add/remove/force 530 | 531 | # Add or remove space between function name and '()' on function calls without parameters. 532 | # If set to 'ignore' (the default), sp_func_call_paren is used. 533 | sp_func_call_paren_empty = force # ignore/add/remove/force 534 | 535 | # Add or remove space between the user function name and '(' on function calls 536 | # You need to set a keyword to be a user function, like this: 'set func_call_user _' in the config file. 537 | sp_func_call_user_paren = ignore # ignore/add/remove/force 538 | 539 | # Add or remove space between a constructor/destructor and the open paren 540 | sp_func_class_paren = force # ignore/add/remove/force 541 | 542 | # Add or remove space between 'return' and '(' 543 | sp_return_paren = force # ignore/add/remove/force 544 | 545 | # Add or remove space between '__attribute__' and '(' 546 | sp_attribute_paren = force # ignore/add/remove/force 547 | 548 | # Add or remove space between 'defined' and '(' in '#if defined (FOO)' 549 | sp_defined_paren = force # ignore/add/remove/force 550 | 551 | # Add or remove space between 'throw' and '(' in 'throw (something)' 552 | sp_throw_paren = force # ignore/add/remove/force 553 | 554 | # Add or remove space between 'throw' and anything other than '(' as in '@throw [...];' 555 | sp_after_throw = force # ignore/add/remove/force 556 | 557 | # Add or remove space between 'catch' and '(' in 'catch (something) { }' 558 | # If set to ignore, sp_before_sparen is used. 559 | sp_catch_paren = force # ignore/add/remove/force 560 | 561 | # D 562 | # Add or remove space between 'version' and '(' in 'version (something) { }' (D language) 563 | # If set to ignore, sp_before_sparen is used. 564 | sp_version_paren = ignore # ignore/add/remove/force 565 | 566 | # D 567 | # Add or remove space between 'scope' and '(' in 'scope (something) { }' (D language) 568 | # If set to ignore, sp_before_sparen is used. 569 | sp_scope_paren = ignore # ignore/add/remove/force 570 | 571 | # Add or remove space between macro and value 572 | sp_macro = ignore # ignore/add/remove/force 573 | 574 | # MACRO 575 | # Add or remove space between macro function ')' and value 576 | sp_macro_func = ignore # ignore/add/remove/force 577 | 578 | # Add or remove space between 'else' and '{' if on the same line 579 | sp_else_brace = force # ignore/add/remove/force 580 | 581 | # Add or remove space between '}' and 'else' if on the same line 582 | sp_brace_else = force # ignore/add/remove/force 583 | 584 | # Add or remove space between '}' and the name of a typedef on the same line 585 | sp_brace_typedef = force # ignore/add/remove/force 586 | 587 | # Add or remove space between 'catch' and '{' if on the same line 588 | sp_catch_brace = force # ignore/add/remove/force 589 | 590 | # Add or remove space between '}' and 'catch' if on the same line 591 | sp_brace_catch = force # ignore/add/remove/force 592 | 593 | # Add or remove space between 'finally' and '{' if on the same line 594 | sp_finally_brace = force # ignore/add/remove/force 595 | 596 | # Add or remove space between '}' and 'finally' if on the same line 597 | sp_brace_finally = force # ignore/add/remove/force 598 | 599 | # Add or remove space between 'try' and '{' if on the same line 600 | sp_try_brace = force # ignore/add/remove/force 601 | 602 | # Add or remove space between get/set and '{' if on the same line 603 | sp_getset_brace = force # ignore/add/remove/force 604 | 605 | # CARL TODO 606 | 607 | # Add or remove space between a variable and '{' for C++ uniform initialization 608 | sp_word_brace = ignore 609 | 610 | # Add or remove space between a variable and '{' for a namespace 611 | sp_word_brace_ns = add 612 | 613 | # C++ 614 | # Add or remove space before the '::' operator 615 | sp_before_dc = remove # ignore/add/remove/force 616 | 617 | # C++ 618 | # Add or remove space after the '::' operator 619 | sp_after_dc = remove # ignore/add/remove/force 620 | 621 | # Add or remove around the D named array initializer ':' operator 622 | sp_d_array_colon = ignore # ignore/add/remove/force 623 | 624 | # Add or remove space after the '!' (not) operator. Default=Remove 625 | sp_not = remove # ignore/add/remove/force 626 | 627 | # Add or remove space after the '~' (invert) operator. Default=Remove 628 | sp_inv = remove # ignore/add/remove/force 629 | 630 | # Add or remove space after the '&' (address-of) operator. Default=Remove 631 | # This does not affect the spacing after a '&' that is part of a type. 632 | sp_addr = remove # ignore/add/remove/force 633 | 634 | # Add or remove space around the '.' or '->' operators. Default=Remove 635 | sp_member = remove # ignore/add/remove/force 636 | 637 | # Add or remove space after the '*' (dereference) operator. Default=Remove 638 | # This does not affect the spacing after a '*' that is part of a type. 639 | sp_deref = remove # ignore/add/remove/force 640 | 641 | # Add or remove space after '+' or '-', as in 'x = -5' or 'y = +7'. Default=Remove 642 | sp_sign = remove # ignore/add/remove/force 643 | 644 | # Add or remove space before or after '++' and '--', as in '(--x)' or 'y++;'. Default=Remove 645 | sp_incdec = remove # ignore/add/remove/force 646 | 647 | # Add or remove space before a backslash-newline at the end of a line. Default=Add 648 | sp_before_nl_cont = add # ignore/add/remove/force 649 | 650 | # Obj c 651 | # Add or remove space after the scope '+' or '-', as in '-(void) foo;' or '+(int) bar;' 652 | sp_after_oc_scope = ignore # ignore/add/remove/force 653 | 654 | # Obj c 655 | # Add or remove space after the colon in message specs 656 | # '-(int) f:(int) x;' vs '-(int) f: (int) x;' 657 | sp_after_oc_colon = ignore # ignore/add/remove/force 658 | 659 | # Obj c 660 | # Add or remove space before the colon in message specs 661 | # '-(int) f: (int) x;' vs '-(int) f : (int) x;' 662 | sp_before_oc_colon = ignore # ignore/add/remove/force 663 | 664 | # Obj c 665 | # Add or remove space after the colon in immutable dictionary expression 666 | # 'NSDictionary *test = @{@"foo" :@"bar"};' 667 | sp_after_oc_dict_colon = ignore # ignore/add/remove/force 668 | 669 | # Obj c 670 | # Add or remove space before the colon in immutable dictionary expression 671 | # 'NSDictionary *test = @{@"foo" :@"bar"};' 672 | sp_before_oc_dict_colon = ignore # ignore/add/remove/force 673 | 674 | # Obj c 675 | # Add or remove space after the colon in message specs 676 | # '[object setValue:1];' vs '[object setValue: 1];' 677 | sp_after_send_oc_colon = ignore # ignore/add/remove/force 678 | 679 | # Obj c 680 | # Add or remove space before the colon in message specs 681 | # '[object setValue:1];' vs '[object setValue :1];' 682 | sp_before_send_oc_colon = ignore # ignore/add/remove/force 683 | 684 | # Obj c 685 | # Add or remove space after the (type) in message specs 686 | # '-(int)f: (int) x;' vs '-(int)f: (int)x;' 687 | sp_after_oc_type = ignore # ignore/add/remove/force 688 | 689 | # Obj c 690 | # Add or remove space after the first (type) in message specs 691 | # '-(int) f:(int)x;' vs '-(int)f:(int)x;' 692 | sp_after_oc_return_type = ignore # ignore/add/remove/force 693 | 694 | # Obj c 695 | # Add or remove space between '@selector' and '(' 696 | # '@selector(msgName)' vs '@selector (msgName)' 697 | # Also applies to @protocol() constructs 698 | sp_after_oc_at_sel = ignore # ignore/add/remove/force 699 | 700 | # Obj c 701 | # Add or remove space between '@selector(x)' and the following word 702 | # '@selector(foo) a:' vs '@selector(foo)a:' 703 | sp_after_oc_at_sel_parens = ignore # ignore/add/remove/force 704 | 705 | # Obj c 706 | # Add or remove space inside '@selector' parens 707 | # '@selector(foo)' vs '@selector( foo )' 708 | # Also applies to @protocol() constructs 709 | sp_inside_oc_at_sel_parens = ignore # ignore/add/remove/force 710 | 711 | # Obj c 712 | # Add or remove space before a block pointer caret 713 | # '^int (int arg){...}' vs. ' ^int (int arg){...}' 714 | sp_before_oc_block_caret = ignore # ignore/add/remove/force 715 | 716 | # Obj c 717 | # Add or remove space after a block pointer caret 718 | # '^int (int arg){...}' vs. '^ int (int arg){...}' 719 | sp_after_oc_block_caret = ignore # ignore/add/remove/force 720 | 721 | # Obj c 722 | # Add or remove space between the receiver and selector in a message. 723 | # '[receiver selector ...]' 724 | sp_after_oc_msg_receiver = ignore # ignore/add/remove/force 725 | 726 | # Obj c 727 | # Add or remove space after @property. 728 | sp_after_oc_property = ignore # ignore/add/remove/force 729 | 730 | # Add or remove space around the ':' in 'b ? t : f' 731 | sp_cond_colon = force # ignore/add/remove/force 732 | # TODO 733 | 734 | # Add or remove space before the ':' in 'b ? t : f'. Overrides sp_cond_colon. 735 | sp_cond_colon_before = force 736 | # Add or remove space after the ':' in 'b ? t : f'. Overrides sp_cond_colon. 737 | sp_cond_colon_after = force 738 | # Add or remove space around the '?' in 'b ? t : f' 739 | sp_cond_question = force 740 | 741 | # Add or remove space before the '?' in 'b ? t : f'. Overrides sp_cond_question. 742 | sp_cond_question_before = force 743 | 744 | # Add or remove space after the '?' in 'b ? t : f'. Overrides sp_cond_question. 745 | sp_cond_question_after = force 746 | 747 | # In the abbreviated ternary form (a ?: b), add/remove space between ? and :.'. Overrides all other sp_cond_* options. 748 | sp_cond_ternary_short = force 749 | 750 | # Fix the spacing between 'case' and the label. Only 'ignore' and 'force' make sense here. 751 | sp_case_label = force # ignore/add/remove/force 752 | 753 | # Control the space around the D '..' operator. 754 | sp_range = ignore # ignore/add/remove/force 755 | 756 | # Control the spacing after ':' in 'for (TYPE VAR : EXPR)' (Java) 757 | sp_after_for_colon = ignore # ignore/add/remove/force 758 | 759 | # Control the spacing before ':' in 'for (TYPE VAR : EXPR)' (Java) 760 | sp_before_for_colon = ignore # ignore/add/remove/force 761 | 762 | # Control the spacing in 'extern (C)' (D) 763 | sp_extern_paren = ignore # ignore/add/remove/force 764 | 765 | # Control the space after the opening of a C++ comment '// A' vs '//A' 766 | sp_cmt_cpp_start = force # ignore/add/remove/force 767 | 768 | # Controls the spaces between #else or #endif and a trailing comment 769 | sp_endif_cmt = remove # ignore/add/remove/force 770 | 771 | # Controls the spaces after 'new', 'delete', and 'delete[]' 772 | sp_after_new = force # ignore/add/remove/force 773 | 774 | # Controls the spaces before a trailing or embedded comment 775 | sp_before_tr_emb_cmt = force # ignore/add/remove/force 776 | 777 | # Number of spaces before a trailing or embedded comment 778 | sp_num_before_tr_emb_cmt = 0 # number 779 | 780 | # Control space between a Java annotation and the open paren. 781 | sp_annotation_paren = ignore # ignore/add/remove/force 782 | 783 | # 784 | # Code alignment (not left column spaces/tabs) 785 | # 786 | 787 | # Whether to keep non-indenting tabs 788 | align_keep_tabs = false # false/true 789 | 790 | # Whether to use tabs for aligning 791 | align_with_tabs = false # false/true 792 | 793 | # Whether to bump out to the next tab when aligning 794 | align_on_tabstop = false # false/true 795 | 796 | # Whether to left-align numbers 797 | align_number_left = false # false/true 798 | 799 | # TODO DOC 800 | # Whether to keep whitespace not required for alignment. 801 | align_keep_extra_space = true 802 | 803 | # Align variable definitions in prototypes and functions 804 | align_func_params = false # false/true 805 | 806 | # Align parameters in single-line functions that have the same name. 807 | # The function names must already be aligned with each other. 808 | align_same_func_call_params = false # false/true 809 | 810 | # The span for aligning variable definitions (0=don't align) 811 | align_var_def_span = 0 # number 812 | 813 | # How to align the star in variable definitions. 814 | # 0=Part of the type 'void * foo;' 815 | # 1=Part of the variable 'void *foo;' 816 | # 2=Dangling 'void *foo;' 817 | align_var_def_star_style = 0 # number 818 | 819 | # How to align the '&' in variable definitions. 820 | # 0=Part of the type 821 | # 1=Part of the variable 822 | # 2=Dangling 823 | align_var_def_amp_style = 0 # number 824 | 825 | # The threshold for aligning variable definitions (0=no limit) 826 | align_var_def_thresh = 0 # number 827 | 828 | # The gap for aligning variable definitions 829 | align_var_def_gap = 0 # number 830 | 831 | # Whether to align the colon in struct bit fields 832 | align_var_def_colon = false # false/true 833 | 834 | # Whether to align any attribute after the variable name 835 | align_var_def_attribute = false # false/true 836 | 837 | # Whether to align inline struct/enum/union variable definitions 838 | align_var_def_inline = false # false/true 839 | 840 | # The span for aligning on '=' in assignments (0=don't align) 841 | align_assign_span = 0 # number 842 | 843 | # The threshold for aligning on '=' in assignments (0=no limit) 844 | align_assign_thresh = 0 # number 845 | 846 | # The span for aligning on '=' in enums (0=don't align) 847 | align_enum_equ_span = 0 # number 848 | 849 | # The threshold for aligning on '=' in enums (0=no limit) 850 | align_enum_equ_thresh = 0 # number 851 | 852 | # The span for aligning struct/union (0=don't align) 853 | align_var_struct_span = 0 # number 854 | 855 | # The threshold for aligning struct/union member definitions (0=no limit) 856 | align_var_struct_thresh = 0 # number 857 | 858 | # The gap for aligning struct/union member definitions 859 | align_var_struct_gap = 0 # number 860 | 861 | # The span for aligning struct initializer values (0=don't align) 862 | align_struct_init_span = 0 # number 863 | 864 | # The minimum space between the type and the synonym of a typedef 865 | align_typedef_gap = 0 # number 866 | 867 | # The span for aligning single-line typedefs (0=don't align) 868 | align_typedef_span = 0 # number 869 | 870 | # How to align typedef'd functions with other typedefs 871 | # 0: Don't mix them at all 872 | # 1: align the open paren with the types 873 | # 2: align the function type name with the other type names 874 | align_typedef_func = 0 # number 875 | 876 | # Controls the positioning of the '*' in typedefs. Just try it. 877 | # 0: Align on typedef type, ignore '*' 878 | # 1: The '*' is part of type name: typedef int *pint; 879 | # 2: The '*' is part of the type, but dangling: typedef int *pint; 880 | align_typedef_star_style = 0 # number 881 | 882 | # Controls the positioning of the '&' in typedefs. Just try it. 883 | # 0: Align on typedef type, ignore '&' 884 | # 1: The '&' is part of type name: typedef int &pint; 885 | # 2: The '&' is part of the type, but dangling: typedef int &pint; 886 | align_typedef_amp_style = 0 # number 887 | 888 | # The span for aligning comments that end lines (0=don't align) 889 | align_right_cmt_span = 0 # number 890 | 891 | # If aligning comments, mix with comments after '}' and #endif with less than 3 spaces before the comment 892 | align_right_cmt_mix = false # false/true 893 | 894 | # If a trailing comment is more than this number of columns away from the text it follows, 895 | # it will qualify for being aligned. This has to be > 0 to do anything. 896 | align_right_cmt_gap = 0 # number 897 | 898 | # Align trailing comment at or beyond column N; 'pulls in' comments as a bonus side effect (0=ignore) 899 | align_right_cmt_at_col = 0 # number 900 | 901 | # The span for aligning function prototypes (0=don't align) 902 | align_func_proto_span = 0 # number 903 | 904 | # Minimum gap between the return type and the function name. 905 | align_func_proto_gap = 0 # number 906 | 907 | # Align function protos on the 'operator' keyword instead of what follows 908 | align_on_operator = false # false/true 909 | 910 | # Whether to mix aligning prototype and variable declarations. 911 | # If true, align_var_def_XXX options are used instead of align_func_proto_XXX options. 912 | align_mix_var_proto = false # false/true 913 | 914 | # Align single-line functions with function prototypes, uses align_func_proto_span 915 | align_single_line_func = false # false/true 916 | 917 | # Aligning the open brace of single-line functions. 918 | # Requires align_single_line_func=true, uses align_func_proto_span 919 | align_single_line_brace = false # false/true 920 | 921 | # Gap for align_single_line_brace. 922 | align_single_line_brace_gap = 0 # number 923 | 924 | # The span for aligning ObjC msg spec (0=don't align) 925 | align_oc_msg_spec_span = 0 # number 926 | 927 | # Whether to align macros wrapped with a backslash and a newline. 928 | # This will not work right if the macro contains a multi-line comment. 929 | align_nl_cont = false # false/true 930 | 931 | # # Align macro functions and variables together 932 | align_pp_define_together = false # false/true 933 | 934 | # The minimum space between label and value of a preprocessor define 935 | align_pp_define_gap = 0 # number 936 | 937 | # The span for aligning on '#define' bodies (0=don't align) 938 | align_pp_define_span = 0 # number 939 | 940 | # Align lines that start with '<<' with previous '<<'. Default=true 941 | align_left_shift = true # false/true 942 | 943 | # Span for aligning parameters in an Obj-C message call on the ':' (0=don't align) 944 | align_oc_msg_colon_span = 0 # number 945 | 946 | # If true, always align with the first parameter, even if it is too short. 947 | align_oc_msg_colon_first = false # false/true 948 | 949 | # Aligning parameters in an Obj-C '+' or '-' declaration on the ':' 950 | align_oc_decl_colon = false # false/true 951 | 952 | # 953 | # Newline adding and removing options 954 | # 955 | 956 | # Whether to collapse empty blocks between '{' and '}' 957 | nl_collapse_empty_body = false # false/true 958 | 959 | # Don't split one-line braced assignments - 'foo_t f = { 1, 2 };' 960 | nl_assign_leave_one_liners = true # false/true 961 | 962 | # Don't split one-line braced statements inside a class xx { } body 963 | nl_class_leave_one_liners = false # false/true 964 | 965 | # Don't split one-line enums: 'enum foo { BAR = 15 };' 966 | nl_enum_leave_one_liners = false # false/true 967 | 968 | # Don't split one-line get or set functions 969 | nl_getset_leave_one_liners = false # false/true 970 | 971 | # Don't split one-line function definitions - 'int foo() { return 0; }' 972 | nl_func_leave_one_liners = false # false/true 973 | 974 | # Don't split one-line if/else statements - 'if(a) b++;' 975 | nl_if_leave_one_liners = false # false/true 976 | 977 | # Don't split one-line OC messages 978 | nl_oc_msg_leave_one_liner = false # false/true 979 | 980 | # Add or remove newlines at the start of the file 981 | nl_start_of_file = ignore # ignore/add/remove/force 982 | 983 | # The number of newlines at the start of the file (only used if nl_start_of_file is 'add' or 'force' 984 | nl_start_of_file_min = 0 # number 985 | 986 | # Add or remove newline at the end of the file 987 | nl_end_of_file = ignore # ignore/add/remove/force 988 | 989 | # The number of newlines at the end of the file (only used if nl_end_of_file is 'add' or 'force') 990 | nl_end_of_file_min = 0 # number 991 | 992 | # Add or remove newline between '=' and '{' 993 | nl_assign_brace = ignore # ignore/add/remove/force 994 | 995 | # Add or remove newline between '=' and '[' (D only) 996 | nl_assign_square = ignore # ignore/add/remove/force 997 | 998 | # Add or remove newline after '= [' (D only). Will also affect the newline before the ']' 999 | nl_after_square_assign = ignore # ignore/add/remove/force 1000 | 1001 | # The number of blank lines after a block of variable definitions at the top of a function body 1002 | # 0 = No change (default) 1003 | nl_func_var_def_blk = 0 # number 1004 | 1005 | # The number of newlines before a block of typedefs 1006 | # 0 = No change (default) 1007 | nl_typedef_blk_start = 0 # number 1008 | 1009 | # The number of newlines after a block of typedefs 1010 | # 0 = No change (default) 1011 | nl_typedef_blk_end = 0 # number 1012 | 1013 | # The maximum consecutive newlines within a block of typedefs 1014 | # 0 = No change (default) 1015 | nl_typedef_blk_in = 0 # number 1016 | 1017 | # The number of newlines before a block of variable definitions not at the top of a function body 1018 | # 0 = No change (default) 1019 | nl_var_def_blk_start = 0 # number 1020 | 1021 | # The number of newlines after a block of variable definitions not at the top of a function body 1022 | # 0 = No change (default) 1023 | nl_var_def_blk_end = 0 # number 1024 | 1025 | # The maximum consecutive newlines within a block of variable definitions 1026 | # 0 = No change (default) 1027 | nl_var_def_blk_in = 0 # number 1028 | 1029 | # Add or remove newline between a function call's ')' and '{', as in: 1030 | # list_for_each(item, &list) { } 1031 | nl_fcall_brace = ignore # ignore/add/remove/force 1032 | 1033 | # Add or remove newline between 'enum' and '{' 1034 | nl_enum_brace = remove # ignore/add/remove/force 1035 | 1036 | # Add or remove newline between 'struct and '{' 1037 | nl_struct_brace = remove # ignore/add/remove/force 1038 | 1039 | # Add or remove newline between 'union' and '{' 1040 | nl_union_brace = remove # ignore/add/remove/force 1041 | 1042 | # Add or remove newline between 'if' and '{' 1043 | nl_if_brace = remove # ignore/add/remove/force 1044 | 1045 | # Add or remove newline between '}' and 'else' 1046 | nl_brace_else = remove # ignore/add/remove/force 1047 | 1048 | # Add or remove newline between 'else if' and '{' 1049 | # If set to ignore, nl_if_brace is used instead 1050 | nl_elseif_brace = remove # ignore/add/remove/force 1051 | 1052 | # Add or remove newline between 'else' and '{' 1053 | nl_else_brace = remove # ignore/add/remove/force 1054 | 1055 | # Add or remove newline between 'else' and 'if' 1056 | nl_else_if = remove # ignore/add/remove/force 1057 | 1058 | # Add or remove newline between '}' and 'finally' 1059 | nl_brace_finally = remove # ignore/add/remove/force 1060 | 1061 | # Add or remove newline between 'finally' and '{' 1062 | nl_finally_brace = remove # ignore/add/remove/force 1063 | 1064 | # Add or remove newline between 'try' and '{' 1065 | nl_try_brace = remove # ignore/add/remove/force 1066 | 1067 | # Add or remove newline between get/set and '{' 1068 | nl_getset_brace = remove # ignore/add/remove/force 1069 | 1070 | # Add or remove newline between 'for' and '{' 1071 | nl_for_brace = remove # ignore/add/remove/force 1072 | 1073 | # Add or remove newline between 'catch' and '{' 1074 | nl_catch_brace = remove # ignore/add/remove/force 1075 | 1076 | # Add or remove newline between '}' and 'catch' 1077 | nl_brace_catch = remove # ignore/add/remove/force 1078 | 1079 | # Add or remove newline between '}' and ']' 1080 | nl_brace_square = remove # ignore/add/remove/force 1081 | 1082 | # Add or remove newline between '}' and ')' in a function invocation 1083 | nl_brace_fparen = remove # ignore/add/remove/force 1084 | # Add or remove newline between 'while' and '{' 1085 | nl_while_brace = remove # ignore/add/remove/force 1086 | 1087 | # Add or remove newline between 'scope (x)' and '{' (D) 1088 | nl_scope_brace = ignore # ignore/add/remove/force 1089 | 1090 | # Add or remove newline between 'unittest' and '{' (D) 1091 | nl_unittest_brace = ignore # ignore/add/remove/force 1092 | 1093 | # Add or remove newline between 'version (x)' and '{' (D) 1094 | nl_version_brace = ignore # ignore/add/remove/force 1095 | 1096 | # Add or remove newline between 'using' and '{' 1097 | nl_using_brace = remove # ignore/add/remove/force 1098 | 1099 | # Add or remove newline between two open or close braces. 1100 | # Due to general newline/brace handling, REMOVE may not work. 1101 | nl_brace_brace = ignore # ignore/add/remove/force 1102 | 1103 | # Add or remove newline between 'do' and '{' 1104 | nl_do_brace = remove # ignore/add/remove/force 1105 | 1106 | # Add or remove newline between '}' and 'while' of 'do' statement 1107 | nl_brace_while = remove # ignore/add/remove/force 1108 | 1109 | # Add or remove newline between 'switch' and '{' 1110 | nl_switch_brace = remove # ignore/add/remove/force 1111 | 1112 | # Add a newline between ')' and '{' if the ')' is on a different line than the if/for/etc. 1113 | # Overrides nl_for_brace, nl_if_brace, nl_switch_brace, nl_while_switch, and nl_catch_brace. 1114 | nl_multi_line_cond = false # false/true 1115 | 1116 | # Force a newline in a define after the macro name for multi-line defines. 1117 | nl_multi_line_define = false # false/true 1118 | 1119 | # Whether to put a newline before 'case' statement 1120 | nl_before_case = false # false/true 1121 | 1122 | # Add or remove newline between ')' and 'throw' 1123 | nl_before_throw = remove # ignore/add/remove/force 1124 | 1125 | # Whether to put a newline after 'case' statement 1126 | nl_after_case = false # false/true 1127 | 1128 | # Add or remove a newline between a case ':' and '{'. Overrides nl_after_case. 1129 | nl_case_colon_brace = ignore # ignore/add/remove/force 1130 | 1131 | # Newline between namespace and { 1132 | nl_namespace_brace = remove # ignore/add/remove/force 1133 | 1134 | # Add or remove newline between 'template<>' and whatever follows. 1135 | nl_template_class = ignore # ignore/add/remove/force 1136 | 1137 | # Add or remove newline between 'class' and '{' 1138 | nl_class_brace = remove # ignore/add/remove/force 1139 | 1140 | # Add or remove newline after each ',' in the class base list 1141 | nl_class_init_args = remove # ignore/add/remove/force 1142 | # Add or remove newline after each ',' in the constructor member initialization 1143 | nl_class_init_args = remove # ignore/add/remove/force 1144 | 1145 | # Add or remove newline between return type and function name in a function definition 1146 | nl_func_type_name = remove # ignore/add/remove/force 1147 | 1148 | # Add or remove newline between return type and function name inside a class {} 1149 | # Uses nl_func_type_name or nl_func_proto_type_name if set to ignore. 1150 | nl_func_type_name_class = remove # ignore/add/remove/force 1151 | 1152 | # Add or remove newline between function scope and name in a definition 1153 | # Controls the newline after '::' in 'void A::f() { }' 1154 | nl_func_scope_name = ignore # ignore/add/remove/force 1155 | 1156 | # Add or remove newline between return type and function name in a prototype 1157 | nl_func_proto_type_name = remove # ignore/add/remove/force 1158 | 1159 | # Add or remove newline between a function name and the opening '(' 1160 | nl_func_paren = remove # ignore/add/remove/force 1161 | 1162 | # Add or remove newline between a function name and the opening '(' in the definition 1163 | nl_func_def_paren = remove # ignore/add/remove/force 1164 | 1165 | # Add or remove newline after '(' in a function declaration 1166 | nl_func_decl_start = remove # ignore/add/remove/force 1167 | 1168 | # Add or remove newline after '(' in a function definition 1169 | nl_func_def_start = remove # ignore/add/remove/force 1170 | 1171 | # Overrides nl_func_decl_start when there is only one parameter. 1172 | nl_func_decl_start_single = ignore # ignore/add/remove/force 1173 | 1174 | # Overrides nl_func_def_start when there is only one parameter. 1175 | nl_func_def_start_single = ignore # ignore/add/remove/force 1176 | 1177 | # Add or remove newline after each ',' in a function declaration 1178 | nl_func_decl_args = ignore # ignore/add/remove/force 1179 | 1180 | # Add or remove newline after each ',' in a function definition 1181 | nl_func_def_args = ignore # ignore/add/remove/force 1182 | 1183 | # Add or remove newline before the ')' in a function declaration 1184 | nl_func_decl_end = remove # ignore/add/remove/force 1185 | 1186 | # Add or remove newline before the ')' in a function definition 1187 | nl_func_def_end = remove # ignore/add/remove/force 1188 | 1189 | # Overrides nl_func_decl_end when there is only one parameter. 1190 | nl_func_decl_end_single = ignore # ignore/add/remove/force 1191 | 1192 | # Overrides nl_func_def_end when there is only one parameter. 1193 | nl_func_def_end_single = ignore # ignore/add/remove/force 1194 | 1195 | # Add or remove newline between '()' in a function declaration. 1196 | nl_func_decl_empty = remove # ignore/add/remove/force 1197 | 1198 | # Add or remove newline between '()' in a function definition. 1199 | nl_func_def_empty = remove # ignore/add/remove/force 1200 | 1201 | # Whether to put each OC message parameter on a separate line 1202 | # See nl_oc_msg_leave_one_liner 1203 | nl_oc_msg_args = false # false/true 1204 | 1205 | # Add or remove newline between function signature and '{' 1206 | nl_fdef_brace = remove # ignore/add/remove/force 1207 | 1208 | # Add or remove newline between C++11 lambda signature and '{' 1209 | nl_cpp_ldef_brace = ignore # ignore/add/remove/force 1210 | 1211 | # Add or remove a newline between the return keyword and return expression. 1212 | nl_return_expr = remove # ignore/add/remove/force 1213 | 1214 | # Whether to put a newline after semicolons, except in 'for' statements 1215 | nl_after_semicolon = false # false/true 1216 | 1217 | # CARL ?? 1218 | # Whether to put a newline after brace open. 1219 | # This also adds a newline before the matching brace close. 1220 | nl_after_brace_open = false # false/true 1221 | 1222 | # If nl_after_brace_open and nl_after_brace_open_cmt are true, a newline is 1223 | # placed between the open brace and a trailing single-line comment. 1224 | nl_after_brace_open_cmt = false # false/true 1225 | 1226 | # Whether to put a newline after a virtual brace open with a non-empty body. 1227 | # These occur in un-braced if/while/do/for statement bodies. 1228 | nl_after_vbrace_open = false # false/true 1229 | 1230 | # Whether to put a newline after a virtual brace open with an empty body. 1231 | # These occur in un-braced if/while/do/for statement bodies. 1232 | nl_after_vbrace_open_empty = false # false/true 1233 | 1234 | # Whether to put a newline after a brace close. 1235 | # Does not apply if followed by a necessary ';'. 1236 | nl_after_brace_close = false # false/true 1237 | 1238 | # Whether to put a newline after a virtual brace close. 1239 | # Would add a newline before return in: 'if (foo) a++; return;' 1240 | nl_after_vbrace_close = false # false/true 1241 | 1242 | # Control the newline between the close brace and 'b' in: 'struct { int a; } b;' 1243 | # Affects enums, unions, and structures. If set to ignore, uses nl_after_brace_close 1244 | nl_brace_struct_var = ignore # ignore/add/remove/force 1245 | 1246 | # Whether to alter newlines in '#define' macros 1247 | nl_define_macro = false # false/true 1248 | 1249 | # Whether to not put blanks after '#ifxx', '#elxx', or before '#endif' 1250 | nl_squeeze_ifdef = false # false/true 1251 | 1252 | # Add or remove blank line before 'if' 1253 | nl_before_if = ignore # ignore/add/remove/force 1254 | 1255 | # Add or remove blank line after 'if' statement 1256 | nl_after_if = ignore # ignore/add/remove/force 1257 | 1258 | # Add or remove blank line before 'for' 1259 | nl_before_for = ignore # ignore/add/remove/force 1260 | 1261 | # Add or remove blank line after 'for' statement 1262 | nl_after_for = ignore # ignore/add/remove/force 1263 | 1264 | # Add or remove blank line before 'while' 1265 | nl_before_while = ignore # ignore/add/remove/force 1266 | 1267 | # Add or remove blank line after 'while' statement 1268 | nl_after_while = ignore # ignore/add/remove/force 1269 | 1270 | # Add or remove blank line before 'switch' 1271 | nl_before_switch = ignore # ignore/add/remove/force 1272 | 1273 | # Add or remove blank line after 'switch' statement 1274 | nl_after_switch = ignore # ignore/add/remove/force 1275 | 1276 | # Add or remove blank line before 'do' 1277 | nl_before_do = ignore # ignore/add/remove/force 1278 | 1279 | # Add or remove blank line after 'do/while' statement 1280 | nl_after_do = ignore # ignore/add/remove/force 1281 | 1282 | # Whether to double-space commented-entries in struct/enum 1283 | nl_ds_struct_enum_cmt = false # false/true 1284 | 1285 | # Whether to double-space before the close brace of a struct/union/enum 1286 | # (lower priority than 'eat_blanks_before_close_brace') 1287 | nl_ds_struct_enum_close_brace = false # false/true 1288 | 1289 | # Add or remove a newline around a class colon. 1290 | # Related to pos_class_colon, nl_class_init_args, and pos_comma. 1291 | nl_class_colon = ignore # ignore/add/remove/force 1292 | 1293 | # Add or remove a newline around a class constructor colon. 1294 | # Related to pos_constr_colon, nl_constr_init_args, and pos_constr_comma. 1295 | nl_constr_colon = ignore # ignore/add/remove/force 1296 | 1297 | 1298 | # Change simple unbraced if statements into a one-liner 1299 | # 'if(b)\n i++;' => 'if(b) i++;' 1300 | nl_create_if_one_liner = false # false/true 1301 | 1302 | # Change simple unbraced for statements into a one-liner 1303 | # 'for (i=0;i<5;i++)\n foo(i);' => 'for (i=0;i<5;i++) foo(i);' 1304 | nl_create_for_one_liner = false # false/true 1305 | 1306 | # Change simple unbraced while statements into a one-liner 1307 | # 'while (i<5)\n foo(i++);' => 'while (i<5) foo(i++);' 1308 | nl_create_while_one_liner = false # false/true 1309 | 1310 | # 1311 | # Positioning options 1312 | # 1313 | 1314 | # The position of arithmetic operators in wrapped expressions 1315 | pos_arith = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force 1316 | 1317 | # The position of assignment in wrapped expressions. 1318 | # Do not affect '=' followed by '{' 1319 | pos_assign = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force 1320 | 1321 | # The position of boolean operators in wrapped expressions 1322 | pos_bool = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force 1323 | 1324 | # The position of comparison operators in wrapped expressions 1325 | pos_compare = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force 1326 | 1327 | # The position of conditional (b ? t : f) operators in wrapped expressions 1328 | pos_conditional = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force 1329 | 1330 | # The position of the comma in wrapped expressions 1331 | pos_comma = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force 1332 | 1333 | # The position of the comma in the class base list 1334 | pos_class_comma = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force 1335 | 1336 | # The position of the comma in the constructor initialization list 1337 | pos_constr_comma = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force 1338 | 1339 | # The position of colons between class and base class list 1340 | pos_class_colon = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force 1341 | 1342 | # The position of colons between constructor and member initialization 1343 | pos_constr_colon = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force 1344 | 1345 | # 1346 | # Line Splitting options 1347 | # 1348 | 1349 | # Try to limit code width to N number of columns 1350 | code_width = 0 # number 1351 | 1352 | # Whether to fully split long 'for' statements at semi-colons 1353 | ls_for_split_full = false # false/true 1354 | 1355 | # Whether to fully split long function protos/calls at commas 1356 | ls_func_split_full = false # false/true 1357 | 1358 | # Whether to split lines as close to code_width as possible and ignore some groupings 1359 | ls_code_width = false # false/true 1360 | 1361 | # 1362 | # Blank line options 1363 | # 1364 | 1365 | # The maximum consecutive newlines 1366 | nl_max = 0 # number 1367 | 1368 | # The number of newlines after a function prototype, if followed by another function prototype 1369 | nl_after_func_proto = 0 # number 1370 | 1371 | # The number of newlines after a function prototype, if not followed by another function prototype 1372 | nl_after_func_proto_group = 2 # number 1373 | 1374 | # The number of newlines after '}' of a multi-line function body 1375 | nl_after_func_body = 2 # number 1376 | 1377 | # The number of newlines after '}' of a multi-line function body in a class declaration 1378 | nl_after_func_body_class = 2 # number 1379 | 1380 | # The number of newlines after '}' of a single line function body 1381 | nl_after_func_body_one_liner = 0 # number 1382 | 1383 | # The minimum number of newlines before a multi-line comment. 1384 | # Doesn't apply if after a brace open or another multi-line comment. 1385 | nl_before_block_comment = 0 # number 1386 | 1387 | # The minimum number of newlines before a single-line C comment. 1388 | # Doesn't apply if after a brace open or other single-line C comments. 1389 | nl_before_c_comment = 0 # number 1390 | 1391 | # The minimum number of newlines before a CPP comment. 1392 | # Doesn't apply if after a brace open or other CPP comments. 1393 | nl_before_cpp_comment = 0 # number 1394 | 1395 | # Whether to force a newline after a multi-line comment. 1396 | nl_after_multiline_comment = false # false/true 1397 | 1398 | # The number of newlines after '}' or ';' of a struct/enum/union definition 1399 | nl_after_struct = 0 # number 1400 | 1401 | # The number of newlines after '}' or ';' of a class definition 1402 | nl_after_class = 0 # number 1403 | 1404 | # The number of newlines before a 'private:', 'public:', 'protected:', 'signals:', or 'slots:' label. 1405 | # Will not change the newline count if after a brace open. 1406 | # 0 = No change. 1407 | nl_before_access_spec = 0 # number 1408 | 1409 | # The number of newlines after a 'private:', 'public:', 'protected:', 'signals:', or 'slots:' label. 1410 | # 0 = No change. 1411 | nl_after_access_spec = 0 # number 1412 | 1413 | # The number of newlines between a function def and the function comment. 1414 | # 0 = No change. 1415 | nl_comment_func_def = 0 # number 1416 | 1417 | # The number of newlines after a try-catch-finally block that isn't followed by a brace close. 1418 | # 0 = No change. 1419 | nl_after_try_catch_finally = 0 # number 1420 | 1421 | # The number of newlines before and after a property, indexer or event decl. 1422 | # 0 = No change. 1423 | nl_around_cs_property = 0 # number 1424 | 1425 | # The number of newlines between the get/set/add/remove handlers in C#. 1426 | # 0 = No change. 1427 | nl_between_get_set = 0 # number 1428 | 1429 | # Add or remove newline between C# property and the '{' 1430 | nl_property_brace = ignore # ignore/add/remove/force 1431 | 1432 | # Whether to remove blank lines after '{' 1433 | eat_blanks_after_open_brace = false # false/true 1434 | 1435 | # Whether to remove blank lines before '}' 1436 | eat_blanks_before_close_brace = false # false/true 1437 | 1438 | # How aggressively to remove extra newlines not in preproc. 1439 | # 0: No change 1440 | # 1: Remove most newlines not handled by other config 1441 | # 2: Remove all newlines and reformat completely by config 1442 | nl_remove_extra_newlines = 0 # number 1443 | 1444 | # Whether to put a blank line before 'return' statements, unless after an open brace. 1445 | nl_before_return = false # false/true 1446 | 1447 | # Whether to put a blank line after 'return' statements, unless followed by a close brace. 1448 | nl_after_return = false # false/true 1449 | 1450 | # Whether to put a newline after a Java annotation statement. 1451 | # Only affects annotations that are after a newline. 1452 | nl_after_annotation = ignore # ignore/add/remove/force 1453 | 1454 | # Controls the newline between two annotations. 1455 | nl_between_annotation = ignore # ignore/add/remove/force 1456 | 1457 | # 1458 | # Code modifying options (non-whitespace) 1459 | # 1460 | 1461 | # Add or remove braces on single-line 'do' statement 1462 | mod_full_brace_do = ignore # ignore/add/remove/force 1463 | 1464 | # Add or remove braces on single-line 'for' statement 1465 | mod_full_brace_for = ignore # ignore/add/remove/force 1466 | 1467 | # Add or remove braces on single-line function definitions. (Pawn) 1468 | mod_full_brace_function = ignore # ignore/add/remove/force 1469 | 1470 | # Add or remove braces on single-line 'if' statement. Will not remove the braces if they contain an 'else'. 1471 | mod_full_brace_if = ignore # ignore/add/remove/force 1472 | 1473 | # Make all if/elseif/else statements in a chain be braced or not. Overrides mod_full_brace_if. 1474 | # If any must be braced, they are all braced. If all can be unbraced, then the braces are removed. 1475 | mod_full_brace_if_chain = false # false/true 1476 | 1477 | # Don't remove braces around statements that span N newlines 1478 | mod_full_brace_nl = 0 # number 1479 | 1480 | # Add or remove braces on single-line 'while' statement 1481 | mod_full_brace_while = ignore # ignore/add/remove/force 1482 | 1483 | # Add or remove braces on single-line 'using ()' statement 1484 | mod_full_brace_using = ignore # ignore/add/remove/force 1485 | 1486 | # Add or remove unnecessary paren on 'return' statement 1487 | mod_paren_on_return = ignore # ignore/add/remove/force 1488 | 1489 | # Whether to change optional semicolons to real semicolons 1490 | mod_pawn_semicolon = false # false/true 1491 | 1492 | # Add parens on 'while' and 'if' statement around bools 1493 | mod_full_paren_if_bool = false # false/true 1494 | 1495 | # Whether to remove superfluous semicolons 1496 | mod_remove_extra_semicolon = false # false/true 1497 | 1498 | # If a function body exceeds the specified number of newlines and doesn't have a comment after 1499 | # the close brace, a comment will be added. 1500 | mod_add_long_function_closebrace_comment = 0 # number 1501 | 1502 | # If a namespace body exceeds the specified number of newlines and doesn't have a comment after 1503 | # the close brace, a comment will be added. 1504 | mod_add_long_namespace_closebrace_comment = 0 # number 1505 | # If a switch body exceeds the specified number of newlines and doesn't have a comment after 1506 | # the close brace, a comment will be added. 1507 | mod_add_long_switch_closebrace_comment = 0 # number 1508 | 1509 | # If an #ifdef body exceeds the specified number of newlines and doesn't have a comment after 1510 | # the #endif, a comment will be added. 1511 | mod_add_long_ifdef_endif_comment = 0 # number 1512 | 1513 | # If an #ifdef or #else body exceeds the specified number of newlines and doesn't have a comment after 1514 | # the #else, a comment will be added. 1515 | mod_add_long_ifdef_else_comment = 0 # number 1516 | 1517 | # If TRUE, will sort consecutive single-line 'import' statements [Java, D] 1518 | mod_sort_import = false # false/true 1519 | 1520 | # If TRUE, will sort consecutive single-line 'using' statements [C#] 1521 | mod_sort_using = false # false/true 1522 | 1523 | # If TRUE, will sort consecutive single-line '#include' statements [C/C++] and '#import' statements [Obj-C] 1524 | # This is generally a bad idea, as it may break your code. 1525 | mod_sort_include = false # false/true 1526 | 1527 | # If TRUE, it will move a 'break' that appears after a fully braced 'case' before the close brace. 1528 | mod_move_case_break = false # false/true 1529 | 1530 | # Will add or remove the braces around a fully braced case statement. 1531 | # Will only remove the braces if there are no variable declarations in the block. 1532 | mod_case_brace = ignore # ignore/add/remove/force 1533 | 1534 | # If TRUE, it will remove a void 'return;' that appears as the last statement in a function. 1535 | mod_remove_empty_return = false # false/true 1536 | 1537 | # 1538 | # Comment modifications 1539 | # 1540 | 1541 | # Try to wrap comments at cmt_width columns 1542 | cmt_width = 0 # number 1543 | 1544 | # Set the comment reflow mode (default: 0) 1545 | # 0: no reflowing (apart from the line wrapping due to cmt_width) 1546 | # 1: no touching at all 1547 | # 2: full reflow 1548 | cmt_reflow_mode = 0 # number 1549 | 1550 | # If false, disable all multi-line comment changes, including cmt_width. keyword substitution, and leading chars. 1551 | # Default is true. 1552 | cmt_indent_multi = true # false/true 1553 | 1554 | # Whether to group c-comments that look like they are in a block 1555 | cmt_c_group = false # false/true 1556 | 1557 | # Whether to put an empty '/*' on the first line of the combined c-comment 1558 | cmt_c_nl_start = false # false/true 1559 | 1560 | # Whether to put a newline before the closing '*/' of the combined c-comment 1561 | cmt_c_nl_end = false # false/true 1562 | 1563 | # Whether to group cpp-comments that look like they are in a block 1564 | cmt_cpp_group = false # false/true 1565 | 1566 | # Whether to put an empty '/*' on the first line of the combined cpp-comment 1567 | cmt_cpp_nl_start = false # false/true 1568 | 1569 | # Whether to put a newline before the closing '*/' of the combined cpp-comment 1570 | cmt_cpp_nl_end = false # false/true 1571 | 1572 | # Whether to change cpp-comments into c-comments 1573 | cmt_cpp_to_c = false # false/true 1574 | 1575 | # Whether to put a star on subsequent comment lines 1576 | cmt_star_cont = false # false/true 1577 | 1578 | # The number of spaces to insert at the start of subsequent comment lines 1579 | cmt_sp_before_star_cont = 0 # number 1580 | 1581 | # The number of spaces to insert after the star on subsequent comment lines 1582 | cmt_sp_after_star_cont = 0 # number 1583 | 1584 | # For multi-line comments with a '*' lead, remove leading spaces if the first and last lines of 1585 | # the comment are the same length. Default=True 1586 | cmt_multi_check_last = true # false/true 1587 | 1588 | # The filename that contains text to insert at the head of a file if the file doesn't start with a C/C++ comment. 1589 | # Will substitute $(filename) with the current file's name. 1590 | cmt_insert_file_header = "" # string 1591 | 1592 | # The filename that contains text to insert at the end of a file if the file doesn't end with a C/C++ comment. 1593 | # Will substitute $(filename) with the current file's name. 1594 | cmt_insert_file_footer = "" # string 1595 | 1596 | # The filename that contains text to insert before a function implementation if the function isn't preceded with a C/C++ comment. 1597 | # Will substitute $(function) with the function name and $(javaparam) with the javadoc @param and @return stuff. 1598 | # Will also substitute $(fclass) with the class name: void CFoo::Bar() { ... } 1599 | cmt_insert_func_header = "" # string 1600 | 1601 | # The filename that contains text to insert before a class if the class isn't preceded with a C/C++ comment. 1602 | # Will substitute $(class) with the class name. 1603 | cmt_insert_class_header = "" # string 1604 | 1605 | # The filename that contains text to insert before a Obj-C message specification if the method isn't preceeded with a C/C++ comment. 1606 | # Will substitute $(message) with the function name and $(javaparam) with the javadoc @param and @return stuff. 1607 | cmt_insert_oc_msg_header = "" # string 1608 | 1609 | # If a preprocessor is encountered when stepping backwards from a function name, then 1610 | # this option decides whether the comment should be inserted. 1611 | # Affects cmt_insert_oc_msg_header, cmt_insert_func_header and cmt_insert_class_header. 1612 | cmt_insert_before_preproc = false # false/true 1613 | 1614 | # 1615 | # Preprocessor options 1616 | # 1617 | 1618 | # Control indent of preprocessors inside #if blocks at brace level 0 1619 | pp_indent = ignore # ignore/add/remove/force 1620 | 1621 | # Whether to indent #if/#else/#endif at the brace level (true) or from column 1 (false) 1622 | pp_indent_at_level = false # false/true 1623 | 1624 | # If pp_indent_at_level=false, specifies the number of columns to indent per level. Default=1. 1625 | pp_indent_count = 1 # number 1626 | 1627 | # Add or remove space after # based on pp_level of #if blocks 1628 | pp_space = ignore # ignore/add/remove/force 1629 | 1630 | # Sets the number of spaces added with pp_space 1631 | pp_space_count = 0 # number 1632 | 1633 | # The indent for #region and #endregion in C# and '#pragma region' in C/C++ 1634 | pp_indent_region = 0 # number 1635 | 1636 | # Whether to indent the code between #region and #endregion 1637 | pp_region_indent_code = false # false/true 1638 | 1639 | # If pp_indent_at_level=true, sets the indent for #if, #else, and #endif when not at file-level 1640 | pp_indent_if = 0 # number 1641 | 1642 | # Control whether to indent the code between #if, #else and #endif when not at file-level 1643 | pp_if_indent_code = false # false/true 1644 | 1645 | # Whether to indent '#define' at the brace level (true) or from column 1 (false) 1646 | pp_define_at_level = false # false/true 1647 | 1648 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Günther Wutz 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU General Public License is a free, copyleft license for 11 | software and other kinds of works. 12 | 13 | The licenses for most software and other practical works are designed 14 | to take away your freedom to share and change the works. By contrast, 15 | the GNU General Public License is intended to guarantee your freedom to 16 | share and change all versions of a program--to make sure it remains free 17 | software for all its users. We, the Free Software Foundation, use the 18 | GNU General Public License for most of our software; it applies also to 19 | any other work released this way by its authors. You can apply it to 20 | your programs, too. 21 | 22 | When we speak of free software, we are referring to freedom, not 23 | price. Our General Public Licenses are designed to make sure that you 24 | have the freedom to distribute copies of free software (and charge for 25 | them if you wish), that you receive source code or can get it if you 26 | want it, that you can change the software or use pieces of it in new 27 | free programs, and that you know you can do these things. 28 | 29 | To protect your rights, we need to prevent others from denying you 30 | these rights or asking you to surrender the rights. Therefore, you have 31 | certain responsibilities if you distribute copies of the software, or if 32 | you modify it: responsibilities to respect the freedom of others. 33 | 34 | For example, if you distribute copies of such a program, whether 35 | gratis or for a fee, you must pass on to the recipients the same 36 | freedoms that you received. You must make sure that they, too, receive 37 | or can get the source code. And you must show them these terms so they 38 | know their rights. 39 | 40 | Developers that use the GNU GPL protect your rights with two steps: 41 | (1) assert copyright on the software, and (2) offer you this License 42 | giving you legal permission to copy, distribute and/or modify it. 43 | 44 | For the developers' and authors' protection, the GPL clearly explains 45 | that there is no warranty for this free software. For both users' and 46 | authors' sake, the GPL requires that modified versions be marked as 47 | changed, so that their problems will not be attributed erroneously to 48 | authors of previous versions. 49 | 50 | Some devices are designed to deny users access to install or run 51 | modified versions of the software inside them, although the manufacturer 52 | can do so. This is fundamentally incompatible with the aim of 53 | protecting users' freedom to change the software. The systematic 54 | pattern of such abuse occurs in the area of products for individuals to 55 | use, which is precisely where it is most unacceptable. Therefore, we 56 | have designed this version of the GPL to prohibit the practice for those 57 | products. If such problems arise substantially in other domains, we 58 | stand ready to extend this provision to those domains in future versions 59 | of the GPL, as needed to protect the freedom of users. 60 | 61 | Finally, every program is threatened constantly by software patents. 62 | States should not allow patents to restrict development and use of 63 | software on general-purpose computers, but in those that do, we wish to 64 | avoid the special danger that patents applied to a free program could 65 | make it effectively proprietary. To prevent this, the GPL assures that 66 | patents cannot be used to render the program non-free. 67 | 68 | The precise terms and conditions for copying, distribution and 69 | modification follow. 70 | 71 | TERMS AND CONDITIONS 72 | 73 | 0. Definitions. 74 | 75 | "This License" refers to version 3 of the GNU General Public License. 76 | 77 | "Copyright" also means copyright-like laws that apply to other kinds of 78 | works, such as semiconductor masks. 79 | 80 | "The Program" refers to any copyrightable work licensed under this 81 | License. Each licensee is addressed as "you". "Licensees" and 82 | "recipients" may be individuals or organizations. 83 | 84 | To "modify" a work means to copy from or adapt all or part of the work 85 | in a fashion requiring copyright permission, other than the making of an 86 | exact copy. The resulting work is called a "modified version" of the 87 | earlier work or a work "based on" the earlier work. 88 | 89 | A "covered work" means either the unmodified Program or a work based 90 | on the Program. 91 | 92 | To "propagate" a work means to do anything with it that, without 93 | permission, would make you directly or secondarily liable for 94 | infringement under applicable copyright law, except executing it on a 95 | computer or modifying a private copy. Propagation includes copying, 96 | distribution (with or without modification), making available to the 97 | public, and in some countries other activities as well. 98 | 99 | To "convey" a work means any kind of propagation that enables other 100 | parties to make or receive copies. Mere interaction with a user through 101 | a computer network, with no transfer of a copy, is not conveying. 102 | 103 | An interactive user interface displays "Appropriate Legal Notices" 104 | to the extent that it includes a convenient and prominently visible 105 | feature that (1) displays an appropriate copyright notice, and (2) 106 | tells the user that there is no warranty for the work (except to the 107 | extent that warranties are provided), that licensees may convey the 108 | work under this License, and how to view a copy of this License. If 109 | the interface presents a list of user commands or options, such as a 110 | menu, a prominent item in the list meets this criterion. 111 | 112 | 1. Source Code. 113 | 114 | The "source code" for a work means the preferred form of the work 115 | for making modifications to it. "Object code" means any non-source 116 | form of a work. 117 | 118 | A "Standard Interface" means an interface that either is an official 119 | standard defined by a recognized standards body, or, in the case of 120 | interfaces specified for a particular programming language, one that 121 | is widely used among developers working in that language. 122 | 123 | The "System Libraries" of an executable work include anything, other 124 | than the work as a whole, that (a) is included in the normal form of 125 | packaging a Major Component, but which is not part of that Major 126 | Component, and (b) serves only to enable use of the work with that 127 | Major Component, or to implement a Standard Interface for which an 128 | implementation is available to the public in source code form. A 129 | "Major Component", in this context, means a major essential component 130 | (kernel, window system, and so on) of the specific operating system 131 | (if any) on which the executable work runs, or a compiler used to 132 | produce the work, or an object code interpreter used to run it. 133 | 134 | The "Corresponding Source" for a work in object code form means all 135 | the source code needed to generate, install, and (for an executable 136 | work) run the object code and to modify the work, including scripts to 137 | control those activities. However, it does not include the work's 138 | System Libraries, or general-purpose tools or generally available free 139 | programs which are used unmodified in performing those activities but 140 | which are not part of the work. For example, Corresponding Source 141 | includes interface definition files associated with source files for 142 | the work, and the source code for shared libraries and dynamically 143 | linked subprograms that the work is specifically designed to require, 144 | such as by intimate data communication or control flow between those 145 | subprograms and other parts of the work. 146 | 147 | The Corresponding Source need not include anything that users 148 | can regenerate automatically from other parts of the Corresponding 149 | Source. 150 | 151 | The Corresponding Source for a work in source code form is that 152 | same work. 153 | 154 | 2. Basic Permissions. 155 | 156 | All rights granted under this License are granted for the term of 157 | copyright on the Program, and are irrevocable provided the stated 158 | conditions are met. This License explicitly affirms your unlimited 159 | permission to run the unmodified Program. The output from running a 160 | covered work is covered by this License only if the output, given its 161 | content, constitutes a covered work. This License acknowledges your 162 | rights of fair use or other equivalent, as provided by copyright law. 163 | 164 | You may make, run and propagate covered works that you do not 165 | convey, without conditions so long as your license otherwise remains 166 | in force. You may convey covered works to others for the sole purpose 167 | of having them make modifications exclusively for you, or provide you 168 | with facilities for running those works, provided that you comply with 169 | the terms of this License in conveying all material for which you do 170 | not control copyright. Those thus making or running the covered works 171 | for you must do so exclusively on your behalf, under your direction 172 | and control, on terms that prohibit them from making any copies of 173 | your copyrighted material outside their relationship with you. 174 | 175 | Conveying under any other circumstances is permitted solely under 176 | the conditions stated below. Sublicensing is not allowed; section 10 177 | makes it unnecessary. 178 | 179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 180 | 181 | No covered work shall be deemed part of an effective technological 182 | measure under any applicable law fulfilling obligations under article 183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 184 | similar laws prohibiting or restricting circumvention of such 185 | measures. 186 | 187 | When you convey a covered work, you waive any legal power to forbid 188 | circumvention of technological measures to the extent such circumvention 189 | is effected by exercising rights under this License with respect to 190 | the covered work, and you disclaim any intention to limit operation or 191 | modification of the work as a means of enforcing, against the work's 192 | users, your or third parties' legal rights to forbid circumvention of 193 | technological measures. 194 | 195 | 4. Conveying Verbatim Copies. 196 | 197 | You may convey verbatim copies of the Program's source code as you 198 | receive it, in any medium, provided that you conspicuously and 199 | appropriately publish on each copy an appropriate copyright notice; 200 | keep intact all notices stating that this License and any 201 | non-permissive terms added in accord with section 7 apply to the code; 202 | keep intact all notices of the absence of any warranty; and give all 203 | recipients a copy of this License along with the Program. 204 | 205 | You may charge any price or no price for each copy that you convey, 206 | and you may offer support or warranty protection for a fee. 207 | 208 | 5. Conveying Modified Source Versions. 209 | 210 | You may convey a work based on the Program, or the modifications to 211 | produce it from the Program, in the form of source code under the 212 | terms of section 4, provided that you also meet all of these conditions: 213 | 214 | a) The work must carry prominent notices stating that you modified 215 | it, and giving a relevant date. 216 | 217 | b) The work must carry prominent notices stating that it is 218 | released under this License and any conditions added under section 219 | 7. This requirement modifies the requirement in section 4 to 220 | "keep intact all notices". 221 | 222 | c) You must license the entire work, as a whole, under this 223 | License to anyone who comes into possession of a copy. This 224 | License will therefore apply, along with any applicable section 7 225 | additional terms, to the whole of the work, and all its parts, 226 | regardless of how they are packaged. This License gives no 227 | permission to license the work in any other way, but it does not 228 | invalidate such permission if you have separately received it. 229 | 230 | d) If the work has interactive user interfaces, each must display 231 | Appropriate Legal Notices; however, if the Program has interactive 232 | interfaces that do not display Appropriate Legal Notices, your 233 | work need not make them do so. 234 | 235 | A compilation of a covered work with other separate and independent 236 | works, which are not by their nature extensions of the covered work, 237 | and which are not combined with it such as to form a larger program, 238 | in or on a volume of a storage or distribution medium, is called an 239 | "aggregate" if the compilation and its resulting copyright are not 240 | used to limit the access or legal rights of the compilation's users 241 | beyond what the individual works permit. Inclusion of a covered work 242 | in an aggregate does not cause this License to apply to the other 243 | parts of the aggregate. 244 | 245 | 6. Conveying Non-Source Forms. 246 | 247 | You may convey a covered work in object code form under the terms 248 | of sections 4 and 5, provided that you also convey the 249 | machine-readable Corresponding Source under the terms of this License, 250 | in one of these ways: 251 | 252 | a) Convey the object code in, or embodied in, a physical product 253 | (including a physical distribution medium), accompanied by the 254 | Corresponding Source fixed on a durable physical medium 255 | customarily used for software interchange. 256 | 257 | b) Convey the object code in, or embodied in, a physical product 258 | (including a physical distribution medium), accompanied by a 259 | written offer, valid for at least three years and valid for as 260 | long as you offer spare parts or customer support for that product 261 | model, to give anyone who possesses the object code either (1) a 262 | copy of the Corresponding Source for all the software in the 263 | product that is covered by this License, on a durable physical 264 | medium customarily used for software interchange, for a price no 265 | more than your reasonable cost of physically performing this 266 | conveying of source, or (2) access to copy the 267 | Corresponding Source from a network server at no charge. 268 | 269 | c) Convey individual copies of the object code with a copy of the 270 | written offer to provide the Corresponding Source. This 271 | alternative is allowed only occasionally and noncommercially, and 272 | only if you received the object code with such an offer, in accord 273 | with subsection 6b. 274 | 275 | d) Convey the object code by offering access from a designated 276 | place (gratis or for a charge), and offer equivalent access to the 277 | Corresponding Source in the same way through the same place at no 278 | further charge. You need not require recipients to copy the 279 | Corresponding Source along with the object code. If the place to 280 | copy the object code is a network server, the Corresponding Source 281 | may be on a different server (operated by you or a third party) 282 | that supports equivalent copying facilities, provided you maintain 283 | clear directions next to the object code saying where to find the 284 | Corresponding Source. Regardless of what server hosts the 285 | Corresponding Source, you remain obligated to ensure that it is 286 | available for as long as needed to satisfy these requirements. 287 | 288 | e) Convey the object code using peer-to-peer transmission, provided 289 | you inform other peers where the object code and Corresponding 290 | Source of the work are being offered to the general public at no 291 | charge under subsection 6d. 292 | 293 | A separable portion of the object code, whose source code is excluded 294 | from the Corresponding Source as a System Library, need not be 295 | included in conveying the object code work. 296 | 297 | A "User Product" is either (1) a "consumer product", which means any 298 | tangible personal property which is normally used for personal, family, 299 | or household purposes, or (2) anything designed or sold for incorporation 300 | into a dwelling. In determining whether a product is a consumer product, 301 | doubtful cases shall be resolved in favor of coverage. For a particular 302 | product received by a particular user, "normally used" refers to a 303 | typical or common use of that class of product, regardless of the status 304 | of the particular user or of the way in which the particular user 305 | actually uses, or expects or is expected to use, the product. A product 306 | is a consumer product regardless of whether the product has substantial 307 | commercial, industrial or non-consumer uses, unless such uses represent 308 | the only significant mode of use of the product. 309 | 310 | "Installation Information" for a User Product means any methods, 311 | procedures, authorization keys, or other information required to install 312 | and execute modified versions of a covered work in that User Product from 313 | a modified version of its Corresponding Source. The information must 314 | suffice to ensure that the continued functioning of the modified object 315 | code is in no case prevented or interfered with solely because 316 | modification has been made. 317 | 318 | If you convey an object code work under this section in, or with, or 319 | specifically for use in, a User Product, and the conveying occurs as 320 | part of a transaction in which the right of possession and use of the 321 | User Product is transferred to the recipient in perpetuity or for a 322 | fixed term (regardless of how the transaction is characterized), the 323 | Corresponding Source conveyed under this section must be accompanied 324 | by the Installation Information. But this requirement does not apply 325 | if neither you nor any third party retains the ability to install 326 | modified object code on the User Product (for example, the work has 327 | been installed in ROM). 328 | 329 | The requirement to provide Installation Information does not include a 330 | requirement to continue to provide support service, warranty, or updates 331 | for a work that has been modified or installed by the recipient, or for 332 | the User Product in which it has been modified or installed. Access to a 333 | network may be denied when the modification itself materially and 334 | adversely affects the operation of the network or violates the rules and 335 | protocols for communication across the network. 336 | 337 | Corresponding Source conveyed, and Installation Information provided, 338 | in accord with this section must be in a format that is publicly 339 | documented (and with an implementation available to the public in 340 | source code form), and must require no special password or key for 341 | unpacking, reading or copying. 342 | 343 | 7. Additional Terms. 344 | 345 | "Additional permissions" are terms that supplement the terms of this 346 | License by making exceptions from one or more of its conditions. 347 | Additional permissions that are applicable to the entire Program shall 348 | be treated as though they were included in this License, to the extent 349 | that they are valid under applicable law. If additional permissions 350 | apply only to part of the Program, that part may be used separately 351 | under those permissions, but the entire Program remains governed by 352 | this License without regard to the additional permissions. 353 | 354 | When you convey a copy of a covered work, you may at your option 355 | remove any additional permissions from that copy, or from any part of 356 | it. (Additional permissions may be written to require their own 357 | removal in certain cases when you modify the work.) You may place 358 | additional permissions on material, added by you to a covered work, 359 | for which you have or can give appropriate copyright permission. 360 | 361 | Notwithstanding any other provision of this License, for material you 362 | add to a covered work, you may (if authorized by the copyright holders of 363 | that material) supplement the terms of this License with terms: 364 | 365 | a) Disclaiming warranty or limiting liability differently from the 366 | terms of sections 15 and 16 of this License; or 367 | 368 | b) Requiring preservation of specified reasonable legal notices or 369 | author attributions in that material or in the Appropriate Legal 370 | Notices displayed by works containing it; or 371 | 372 | c) Prohibiting misrepresentation of the origin of that material, or 373 | requiring that modified versions of such material be marked in 374 | reasonable ways as different from the original version; or 375 | 376 | d) Limiting the use for publicity purposes of names of licensors or 377 | authors of the material; or 378 | 379 | e) Declining to grant rights under trademark law for use of some 380 | trade names, trademarks, or service marks; or 381 | 382 | f) Requiring indemnification of licensors and authors of that 383 | material by anyone who conveys the material (or modified versions of 384 | it) with contractual assumptions of liability to the recipient, for 385 | any liability that these contractual assumptions directly impose on 386 | those licensors and authors. 387 | 388 | All other non-permissive additional terms are considered "further 389 | restrictions" within the meaning of section 10. If the Program as you 390 | received it, or any part of it, contains a notice stating that it is 391 | governed by this License along with a term that is a further 392 | restriction, you may remove that term. If a license document contains 393 | a further restriction but permits relicensing or conveying under this 394 | License, you may add to a covered work material governed by the terms 395 | of that license document, provided that the further restriction does 396 | not survive such relicensing or conveying. 397 | 398 | If you add terms to a covered work in accord with this section, you 399 | must place, in the relevant source files, a statement of the 400 | additional terms that apply to those files, or a notice indicating 401 | where to find the applicable terms. 402 | 403 | Additional terms, permissive or non-permissive, may be stated in the 404 | form of a separately written license, or stated as exceptions; 405 | the above requirements apply either way. 406 | 407 | 8. Termination. 408 | 409 | You may not propagate or modify a covered work except as expressly 410 | provided under this License. Any attempt otherwise to propagate or 411 | modify it is void, and will automatically terminate your rights under 412 | this License (including any patent licenses granted under the third 413 | paragraph of section 11). 414 | 415 | However, if you cease all violation of this License, then your 416 | license from a particular copyright holder is reinstated (a) 417 | provisionally, unless and until the copyright holder explicitly and 418 | finally terminates your license, and (b) permanently, if the copyright 419 | holder fails to notify you of the violation by some reasonable means 420 | prior to 60 days after the cessation. 421 | 422 | Moreover, your license from a particular copyright holder is 423 | reinstated permanently if the copyright holder notifies you of the 424 | violation by some reasonable means, this is the first time you have 425 | received notice of violation of this License (for any work) from that 426 | copyright holder, and you cure the violation prior to 30 days after 427 | your receipt of the notice. 428 | 429 | Termination of your rights under this section does not terminate the 430 | licenses of parties who have received copies or rights from you under 431 | this License. If your rights have been terminated and not permanently 432 | reinstated, you do not qualify to receive new licenses for the same 433 | material under section 10. 434 | 435 | 9. Acceptance Not Required for Having Copies. 436 | 437 | You are not required to accept this License in order to receive or 438 | run a copy of the Program. Ancillary propagation of a covered work 439 | occurring solely as a consequence of using peer-to-peer transmission 440 | to receive a copy likewise does not require acceptance. However, 441 | nothing other than this License grants you permission to propagate or 442 | modify any covered work. These actions infringe copyright if you do 443 | not accept this License. Therefore, by modifying or propagating a 444 | covered work, you indicate your acceptance of this License to do so. 445 | 446 | 10. Automatic Licensing of Downstream Recipients. 447 | 448 | Each time you convey a covered work, the recipient automatically 449 | receives a license from the original licensors, to run, modify and 450 | propagate that work, subject to this License. You are not responsible 451 | for enforcing compliance by third parties with this License. 452 | 453 | An "entity transaction" is a transaction transferring control of an 454 | organization, or substantially all assets of one, or subdividing an 455 | organization, or merging organizations. If propagation of a covered 456 | work results from an entity transaction, each party to that 457 | transaction who receives a copy of the work also receives whatever 458 | licenses to the work the party's predecessor in interest had or could 459 | give under the previous paragraph, plus a right to possession of the 460 | Corresponding Source of the work from the predecessor in interest, if 461 | the predecessor has it or can get it with reasonable efforts. 462 | 463 | You may not impose any further restrictions on the exercise of the 464 | rights granted or affirmed under this License. For example, you may 465 | not impose a license fee, royalty, or other charge for exercise of 466 | rights granted under this License, and you may not initiate litigation 467 | (including a cross-claim or counterclaim in a lawsuit) alleging that 468 | any patent claim is infringed by making, using, selling, offering for 469 | sale, or importing the Program or any portion of it. 470 | 471 | 11. Patents. 472 | 473 | A "contributor" is a copyright holder who authorizes use under this 474 | License of the Program or a work on which the Program is based. The 475 | work thus licensed is called the contributor's "contributor version". 476 | 477 | A contributor's "essential patent claims" are all patent claims 478 | owned or controlled by the contributor, whether already acquired or 479 | hereafter acquired, that would be infringed by some manner, permitted 480 | by this License, of making, using, or selling its contributor version, 481 | but do not include claims that would be infringed only as a 482 | consequence of further modification of the contributor version. For 483 | purposes of this definition, "control" includes the right to grant 484 | patent sublicenses in a manner consistent with the requirements of 485 | this License. 486 | 487 | Each contributor grants you a non-exclusive, worldwide, royalty-free 488 | patent license under the contributor's essential patent claims, to 489 | make, use, sell, offer for sale, import and otherwise run, modify and 490 | propagate the contents of its contributor version. 491 | 492 | In the following three paragraphs, a "patent license" is any express 493 | agreement or commitment, however denominated, not to enforce a patent 494 | (such as an express permission to practice a patent or covenant not to 495 | sue for patent infringement). To "grant" such a patent license to a 496 | party means to make such an agreement or commitment not to enforce a 497 | patent against the party. 498 | 499 | If you convey a covered work, knowingly relying on a patent license, 500 | and the Corresponding Source of the work is not available for anyone 501 | to copy, free of charge and under the terms of this License, through a 502 | publicly available network server or other readily accessible means, 503 | then you must either (1) cause the Corresponding Source to be so 504 | available, or (2) arrange to deprive yourself of the benefit of the 505 | patent license for this particular work, or (3) arrange, in a manner 506 | consistent with the requirements of this License, to extend the patent 507 | license to downstream recipients. "Knowingly relying" means you have 508 | actual knowledge that, but for the patent license, your conveying the 509 | covered work in a country, or your recipient's use of the covered work 510 | in a country, would infringe one or more identifiable patents in that 511 | country that you have reason to believe are valid. 512 | 513 | If, pursuant to or in connection with a single transaction or 514 | arrangement, you convey, or propagate by procuring conveyance of, a 515 | covered work, and grant a patent license to some of the parties 516 | receiving the covered work authorizing them to use, propagate, modify 517 | or convey a specific copy of the covered work, then the patent license 518 | you grant is automatically extended to all recipients of the covered 519 | work and works based on it. 520 | 521 | A patent license is "discriminatory" if it does not include within 522 | the scope of its coverage, prohibits the exercise of, or is 523 | conditioned on the non-exercise of one or more of the rights that are 524 | specifically granted under this License. You may not convey a covered 525 | work if you are a party to an arrangement with a third party that is 526 | in the business of distributing software, under which you make payment 527 | to the third party based on the extent of your activity of conveying 528 | the work, and under which the third party grants, to any of the 529 | parties who would receive the covered work from you, a discriminatory 530 | patent license (a) in connection with copies of the covered work 531 | conveyed by you (or copies made from those copies), or (b) primarily 532 | for and in connection with specific products or compilations that 533 | contain the covered work, unless you entered into that arrangement, 534 | or that patent license was granted, prior to 28 March 2007. 535 | 536 | Nothing in this License shall be construed as excluding or limiting 537 | any implied license or other defenses to infringement that may 538 | otherwise be available to you under applicable patent law. 539 | 540 | 12. No Surrender of Others' Freedom. 541 | 542 | If conditions are imposed on you (whether by court order, agreement or 543 | otherwise) that contradict the conditions of this License, they do not 544 | excuse you from the conditions of this License. If you cannot convey a 545 | covered work so as to satisfy simultaneously your obligations under this 546 | License and any other pertinent obligations, then as a consequence you may 547 | not convey it at all. For example, if you agree to terms that obligate you 548 | to collect a royalty for further conveying from those to whom you convey 549 | the Program, the only way you could satisfy both those terms and this 550 | License would be to refrain entirely from conveying the Program. 551 | 552 | 13. Use with the GNU Affero General Public License. 553 | 554 | Notwithstanding any other provision of this License, you have 555 | permission to link or combine any covered work with a work licensed 556 | under version 3 of the GNU Affero General Public License into a single 557 | combined work, and to convey the resulting work. The terms of this 558 | License will continue to apply to the part which is the covered work, 559 | but the special requirements of the GNU Affero General Public License, 560 | section 13, concerning interaction through a network will apply to the 561 | combination as such. 562 | 563 | 14. Revised Versions of this License. 564 | 565 | The Free Software Foundation may publish revised and/or new versions of 566 | the GNU General Public License from time to time. Such new versions will 567 | be similar in spirit to the present version, but may differ in detail to 568 | address new problems or concerns. 569 | 570 | Each version is given a distinguishing version number. If the 571 | Program specifies that a certain numbered version of the GNU General 572 | Public License "or any later version" applies to it, you have the 573 | option of following the terms and conditions either of that numbered 574 | version or of any later version published by the Free Software 575 | Foundation. If the Program does not specify a version number of the 576 | GNU General Public License, you may choose any version ever published 577 | by the Free Software Foundation. 578 | 579 | If the Program specifies that a proxy can decide which future 580 | versions of the GNU General Public License can be used, that proxy's 581 | public statement of acceptance of a version permanently authorizes you 582 | to choose that version for the Program. 583 | 584 | Later license versions may give you additional or different 585 | permissions. However, no additional obligations are imposed on any 586 | author or copyright holder as a result of your choosing to follow a 587 | later version. 588 | 589 | 15. Disclaimer of Warranty. 590 | 591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 599 | 600 | 16. Limitation of Liability. 601 | 602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 610 | SUCH DAMAGES. 611 | 612 | 17. Interpretation of Sections 15 and 16. 613 | 614 | If the disclaimer of warranty and limitation of liability provided 615 | above cannot be given local legal effect according to their terms, 616 | reviewing courts shall apply local law that most closely approximates 617 | an absolute waiver of all civil liability in connection with the 618 | Program, unless a warranty or assumption of liability accompanies a 619 | copy of the Program in return for a fee. 620 | 621 | END OF TERMS AND CONDITIONS 622 | 623 | How to Apply These Terms to Your New Programs 624 | 625 | If you develop a new program, and you want it to be of the greatest 626 | possible use to the public, the best way to achieve this is to make it 627 | free software which everyone can redistribute and change under these terms. 628 | 629 | To do so, attach the following notices to the program. It is safest 630 | to attach them to the start of each source file to most effectively 631 | state the exclusion of warranty; and each file should have at least 632 | the "copyright" line and a pointer to where the full notice is found. 633 | 634 | {one line to give the program's name and a brief idea of what it does.} 635 | Copyright (C) {year} {name of author} 636 | 637 | This program is free software: you can redistribute it and/or modify 638 | it under the terms of the GNU General Public License as published by 639 | the Free Software Foundation, either version 3 of the License, or 640 | (at your option) any later version. 641 | 642 | This program is distributed in the hope that it will be useful, 643 | but WITHOUT ANY WARRANTY; without even the implied warranty of 644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 645 | GNU General Public License for more details. 646 | 647 | You should have received a copy of the GNU General Public License 648 | along with this program. If not, see . 649 | 650 | Also add information on how to contact you by electronic and paper mail. 651 | 652 | If the program does terminal interaction, make it output a short 653 | notice like this when it starts in an interactive mode: 654 | 655 | {project} Copyright (C) {year} {fullname} 656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 657 | This is free software, and you are welcome to redistribute it 658 | under certain conditions; type `show c' for details. 659 | 660 | The hypothetical commands `show w' and `show c' should show the appropriate 661 | parts of the General Public License. Of course, your program's commands 662 | might be different; for a GUI interface, you would use an "about box". 663 | 664 | You should also get your employer (if you work as a programmer) or school, 665 | if any, to sign a "copyright disclaimer" for the program, if necessary. 666 | For more information on this, and how to apply and follow the GNU GPL, see 667 | . 668 | 669 | The GNU General Public License does not permit incorporating your program 670 | into proprietary programs. If your program is a subroutine library, you 671 | may consider it more useful to permit linking proprietary applications with 672 | the library. If this is what you want to do, use the GNU Lesser General 673 | Public License instead of this License. But first, please read 674 | . 675 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | News 2 | ==== 3 | 4 | Gnome News is currently unmaintained. I would love to reactivate it but i dont like python as 5 | programming language for a project like that. So i try here to recreate gnome news in vala 6 | with all special features we recently got: Composite Widgets, Gresource files, DBus Integration, 7 | Tracker RSS Miner etc. 8 | 9 | **NOTE: This project is in no direct connection to the GNOME trademark or desktop. Its an independent 10 | development and will never be part of GNOME. I just lend the free design for this application** 11 | 12 | ![](data/screenshots/start.png) 13 | ![](data/screenshots/list.png) 14 | ![](data/screenshots/news-article.png) 15 | ![](data/screenshots/feed.png) 16 | ![](data/screenshots/search.png) 17 | 18 | Stay tuned! 19 | -------------------------------------------------------------------------------- /data/appmenu.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | 7 | About 8 | app.about 9 | 10 |
11 |
12 | 13 | Quit 14 | app.quit 15 | 16 |
17 |
18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /data/icons/16x16/news.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gwutz/news/3c5b1a4bd87a0c9233543ebb731d1e3b9597d831/data/icons/16x16/news.png -------------------------------------------------------------------------------- /data/icons/22x22/news.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gwutz/news/3c5b1a4bd87a0c9233543ebb731d1e3b9597d831/data/icons/22x22/news.png -------------------------------------------------------------------------------- /data/icons/24x24/news.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gwutz/news/3c5b1a4bd87a0c9233543ebb731d1e3b9597d831/data/icons/24x24/news.png -------------------------------------------------------------------------------- /data/icons/256x256/news.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gwutz/news/3c5b1a4bd87a0c9233543ebb731d1e3b9597d831/data/icons/256x256/news.png -------------------------------------------------------------------------------- /data/icons/32x32/news.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gwutz/news/3c5b1a4bd87a0c9233543ebb731d1e3b9597d831/data/icons/32x32/news.png -------------------------------------------------------------------------------- /data/icons/48x48/news.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gwutz/news/3c5b1a4bd87a0c9233543ebb731d1e3b9597d831/data/icons/48x48/news.png -------------------------------------------------------------------------------- /data/icons/512x512/news.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gwutz/news/3c5b1a4bd87a0c9233543ebb731d1e3b9597d831/data/icons/512x512/news.png -------------------------------------------------------------------------------- /data/icons/hicolor_apps_symbolic_gnome-news-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | image/svg+xml 9 | 10 | Gnome Symbolic Icon Theme 11 | 12 | 13 | 14 | 15 | 16 | 17 | Gnome Symbolic Icon Theme 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /data/icons/meson.build: -------------------------------------------------------------------------------- 1 | sizes = ['16x16', '24x24', '32x32', '512x512', '22x22', '256x256', '48x48'] 2 | themedir = get_option('datadir') + '/icons/hicolor/' 3 | 4 | foreach size: sizes 5 | install_data(size + '/news.png', install_dir: themedir + size + '/apps/') 6 | endforeach 7 | -------------------------------------------------------------------------------- /data/meson.build: -------------------------------------------------------------------------------- 1 | gnome = import ('gnome') 2 | 3 | news_resources = gnome.compile_resources ('news_resource', 'news-resource.xml', source_dir: '.', c_name: 'news') 4 | 5 | install_data('org.gnome.News.desktop', 6 | install_dir : join_paths('share', 'applications')) 7 | 8 | subdir('icons') 9 | -------------------------------------------------------------------------------- /data/news-resource.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ui/window.ui 5 | ui/article.ui 6 | ui/articlerow.ui 7 | appmenu.ui 8 | theme/Adwaita.css 9 | theme/articlebox.html 10 | 11 | 12 | -------------------------------------------------------------------------------- /data/org.gnome.News.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Name=News 3 | Exec=news 4 | Icon=news 5 | Terminal=false 6 | Type=Application 7 | StartupNotify=true 8 | Categories=Network;Feed;News;GNOME;GTK; 9 | Keywords=News;Feed; 10 | -------------------------------------------------------------------------------- /data/screenshots/feed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gwutz/news/3c5b1a4bd87a0c9233543ebb731d1e3b9597d831/data/screenshots/feed.png -------------------------------------------------------------------------------- /data/screenshots/list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gwutz/news/3c5b1a4bd87a0c9233543ebb731d1e3b9597d831/data/screenshots/list.png -------------------------------------------------------------------------------- /data/screenshots/news-article.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gwutz/news/3c5b1a4bd87a0c9233543ebb731d1e3b9597d831/data/screenshots/news-article.png -------------------------------------------------------------------------------- /data/screenshots/news-flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gwutz/news/3c5b1a4bd87a0c9233543ebb731d1e3b9597d831/data/screenshots/news-flow.png -------------------------------------------------------------------------------- /data/screenshots/news-list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gwutz/news/3c5b1a4bd87a0c9233543ebb731d1e3b9597d831/data/screenshots/news-list.png -------------------------------------------------------------------------------- /data/screenshots/newsv2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gwutz/news/3c5b1a4bd87a0c9233543ebb731d1e3b9597d831/data/screenshots/newsv2.png -------------------------------------------------------------------------------- /data/screenshots/search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gwutz/news/3c5b1a4bd87a0c9233543ebb731d1e3b9597d831/data/screenshots/search.png -------------------------------------------------------------------------------- /data/screenshots/start.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gwutz/news/3c5b1a4bd87a0c9233543ebb731d1e3b9597d831/data/screenshots/start.png -------------------------------------------------------------------------------- /data/theme/Adwaita.css: -------------------------------------------------------------------------------- 1 | .feeds-list { 2 | margin-left: 100px; 3 | margin-right: 100px; 4 | color: #2e3436; 5 | border-top: 1px solid #f2f2f2; 6 | } 7 | 8 | .feedbox { 9 | border: 1px solid #a1a1a1; 10 | box-shadow: inset 0 0 0 1px rgba(74, 144, 217, 0), 0 1px white; 11 | background-color: #ffffff; 12 | } 13 | 14 | .sidebar .list { 15 | background-color: @sidebar_bg_color; 16 | } 17 | 18 | .postspinner { 19 | background-color: #ffffff; 20 | } 21 | 22 | .article-title { 23 | font: bold 15pt Cantarell; 24 | } 25 | -------------------------------------------------------------------------------- /data/theme/articlebox.html: -------------------------------------------------------------------------------- 1 | 8 | 9 |
10 |

%s

11 | %s 12 |
%s
13 |
14 | 15 | -------------------------------------------------------------------------------- /data/ui/article.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | True 7 | False 8 | 10 9 | 10 10 | 2 11 | 12 | 13 | True 14 | False 15 | 16 | 17 | -------------------------------------------------------------------------------- /data/ui/articlerow.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 93 | 94 | -------------------------------------------------------------------------------- /data/ui/window.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | False 7 | 8 8 | bottom 9 | 10 | 11 | True 12 | False 13 | vertical 14 | 3 15 | 16 | 17 | True 18 | False 19 | start 20 | True 21 | Enter a feed address to add: 22 | 23 | 24 | False 25 | True 26 | 0 27 | 28 | 29 | 30 | 31 | True 32 | False 33 | 3 34 | 35 | 36 | True 37 | True 38 | 39 | 40 | 41 | False 42 | True 43 | 0 44 | 45 | 46 | 47 | 48 | Add 49 | True 50 | False 51 | True 52 | True 53 | 54 | 57 | 58 | 59 | False 60 | True 61 | 1 62 | 63 | 64 | 65 | 66 | False 67 | True 68 | 1 69 | 70 | 71 | 72 | 73 | main 74 | 1 75 | 76 | 77 | 78 | 233 | 234 | -------------------------------------------------------------------------------- /meson.build: -------------------------------------------------------------------------------- 1 | project ('news', ['vala', 'c']) 2 | 3 | glib = dependency ('glib-2.0') 4 | gobject = dependency ('gobject-2.0') 5 | gio = dependency ('gio-2.0') 6 | gtk = dependency ('gtk+-3.0') 7 | sparql = dependency ('tracker-sparql-1.0') 8 | webkit = dependency ('webkit2gtk-4.0') 9 | 10 | subdir ('data') 11 | subdir ('src') 12 | -------------------------------------------------------------------------------- /package/PKGBUILD: -------------------------------------------------------------------------------- 1 | # Maintainer: Your Name 2 | pkgname=news-feed-reader 3 | pkgver=0.1 4 | pkgrel=1 5 | pkgdesc="A feedreader in the style of gnome news" 6 | arch=(any) 7 | url="http://www.github.com/gwutz/news" 8 | license=('GPLv3') 9 | groups=() 10 | depends=() 11 | makedepends=() 12 | optdepends=() 13 | provides=() 14 | conflicts=() 15 | replaces=() 16 | backup=() 17 | options=() 18 | install= 19 | changelog= 20 | source=("$pkgname"::"git+https://github.com/gwutz/news.git") 21 | noextract=() 22 | md5sums=('SKIP') #autofill using updpkgsums 23 | 24 | build() { 25 | cd "$pkgname" 26 | rm -rf build 27 | 28 | mkdir build && cd build 29 | meson .. 30 | ninja 31 | } 32 | 33 | package() { 34 | cd "$pkgname/build" 35 | 36 | DESTDIR="$pkgdir/" ninja install 37 | } 38 | -------------------------------------------------------------------------------- /src/controller.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * controller.vala 3 | * This file is part of news 4 | * 5 | * Copyright (C) 2017 - Günther Wutz 6 | * 7 | * news is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * news is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with news. If not, see . 19 | */ 20 | 21 | using Tracker; 22 | namespace News { 23 | public class Controller : Object { 24 | 25 | public enum Updated { 26 | MARK_AS_READ 27 | } 28 | 29 | public signal void items_updated (); 30 | 31 | public signal void item_updated (Post post, Updated updated); 32 | 33 | private Sparql.Connection sparql; 34 | 35 | public Controller () { 36 | try { 37 | sparql = Sparql.Connection.get (); 38 | } catch ( Error e ){ 39 | error (e.message); 40 | } 41 | } 42 | 43 | public List post_sorted_by_date (bool unread = false, bool starred = false) { 44 | StringBuilder builder = new StringBuilder (" 45 | SELECT 46 | nie:title(?msg) AS title 47 | nmo:htmlMessageContent(?msg) AS content 48 | nie:url(?msg) AS url 49 | nco:fullname(?creator) AS fullname 50 | nmo:isRead(?msg) AS is_read 51 | ?msg BOUND(?tag) as is_starred 52 | nie:contentCreated(?msg) AS date 53 | nie:url(?website) AS ?author_homepage 54 | nco:emailAddress(?email) AS author_email 55 | WHERE 56 | { 57 | ?msg a mfo:FeedMessage"); 58 | 59 | if (unread) { 60 | builder.append ("; nmo:isRead false"); 61 | } 62 | 63 | if (starred) { 64 | builder.append ("; nao:hasTag nao:predefined-tag-favorite "); 65 | } 66 | 67 | builder.append(" 68 | . OPTIONAL { ?msg nao:hasTag ?tag . 69 | FILTER(?tag = nao:predefined-tag-favorite)} 70 | . OPTIONAL { 71 | ?msg nco:creator ?creator 72 | . OPTIONAL { ?creator nco:websiteUrl ?website } 73 | . OPTIONAL { ?creator nco:hasEmailAddress ?email } 74 | } 75 | 76 | } ORDER BY DESC (nie:contentCreated(?msg))"); 77 | var posts = new List(); 78 | debug ("Query: %s", builder.str); 79 | try { 80 | var result = sparql.query (builder.str); 81 | 82 | while (result.next ()) { 83 | posts.append(new Post(parse_cursor(result))); 84 | } 85 | } catch (Error e) { 86 | error (e.message); 87 | } 88 | 89 | return posts; 90 | } 91 | 92 | public List post_sorted_by_channel (string url) { 93 | string query = """ 94 | SELECT 95 | nie:title(?msg) AS title 96 | nmo:htmlMessageContent(?msg) AS content 97 | nie:url(?msg) AS url 98 | nco:fullname(?creator) AS fullname 99 | nmo:isRead(?msg) AS is_read 100 | ?msg BOUND(?tag) as is_starred 101 | nie:url(?website) AS author_homepage 102 | nco:emailAddress(?email) AS author_email 103 | nie:contentCreated(?msg) AS date 104 | { ?msg a mfo:FeedMessage; 105 | nmo:communicationChannel ?chan . 106 | ?chan nie:url "%s" . 107 | OPTIONAL { ?msg nao:hasTag ?tag . 108 | FILTER(?tag = nao:predefined-tag-favorite) } . 109 | OPTIONAL { ?msg nco:creator ?creator 110 | . OPTIONAL { ?creator nco:websiteUrl ?website } 111 | . OPTIONAL { ?creator nco:hasEmailAddress ?email } 112 | } 113 | 114 | } 115 | ORDER BY DESC (nie:contentCreated(?msg)) 116 | """.printf (url); 117 | var posts = new List(); 118 | try { 119 | var result = sparql.query (query); 120 | 121 | while (result.next ()) { 122 | posts.append(new Post(parse_cursor(result))); 123 | } 124 | } catch (Error e) { 125 | error (e.message); 126 | } 127 | 128 | return posts; 129 | } 130 | 131 | public List post_by_search (string text) { 132 | string query = """ 133 | SELECT 134 | nie:url(?msg) AS url 135 | nie:title(?msg) AS title 136 | nco:fullname(?creator) AS fullname 137 | nie:url(?website) AS author_homepage 138 | nie:contentCreated(?msg) AS date 139 | nmo:htmlMessageContent(?msg) AS content 140 | nmo:isRead(?msg) AS is_read 141 | ?msg BOUND(?tag) as is_starred 142 | { ?msg a mfo:FeedMessage; 143 | fts:match "%s" . 144 | OPTIONAL { ?msg nao:hasTag ?tag . 145 | FILTER(?tag = nao:predefined-tag-favorite) } . 146 | OPTIONAL { ?msg nco:creator ?creator . 147 | OPTIONAL { ?creator nco:hasEmailAddress ?email } . 148 | OPTIONAL { ?creator nco:websiteUrl ?website } 149 | } 150 | } 151 | ORDER BY fts:rank(?msg)""".printf (text); 152 | var posts = new List(); 153 | debug ("%s", query); 154 | try { 155 | var result = sparql.query (query); 156 | while (result.next ()) { 157 | posts.append(new Post(parse_cursor(result))); 158 | } 159 | } catch (Error e) { 160 | error (e.message); 161 | } 162 | return posts; 163 | } 164 | 165 | public void add_channel (string url, int update_interval = 5) { 166 | string query = """ 167 | INSERT { 168 | _:FeedSettings a mfo:FeedSettings ; 169 | mfo:updateInterval %i . 170 | _:Feed a nie:DataObject, mfo:FeedChannel ; 171 | mfo:feedSettings _:FeedSettings ; 172 | nie:url "%s" } 173 | """.printf (update_interval, url); 174 | try { 175 | sparql.update (query); 176 | } catch (DBusError derror) { 177 | error ("There was an error to communicate with the dbus interface %s", derror.message); 178 | } catch (IOError ioerror) { 179 | error ("There was an error to communicate with the io interface %s", ioerror.message); 180 | } catch (Error err) { 181 | error ("A general error occurred %s", err.message); 182 | } 183 | } 184 | 185 | public void mark_post_as_read (Post post) { 186 | debug ("Url read: %s", post.url); 187 | string query = """ 188 | DELETE 189 | { ?msg nmo:isRead ?any } 190 | WHERE 191 | { ?msg nie:url "%s"; 192 | nmo:isRead ?any } 193 | INSERT 194 | { ?msg nmo:isRead true } 195 | WHERE 196 | { ?msg nie:url "%s" } 197 | """.printf(post.url, post.url); 198 | try { 199 | sparql.update (query); 200 | item_updated (post, Updated.MARK_AS_READ); 201 | } catch (Error e) { 202 | error (e.message); 203 | } 204 | } 205 | 206 | public void mark_post_as_starred (Post post, bool starred) { 207 | debug ("Star article %s with url %s", post.title, post.url); 208 | string query; 209 | if (starred) { 210 | query = """ 211 | INSERT 212 | { ?msg nao:hasTag nao:predefined-tag-favorite } 213 | WHERE 214 | { ?msg nie:url "%s" } 215 | """.printf (post.url); 216 | } else { 217 | query = """ 218 | DELETE 219 | { ?msg nao:hasTag nao:predefined-tag-favorite } 220 | WHERE 221 | { ?msg nie:url "%s"; 222 | nao:hasTag nao:predefined-tag-favorite } 223 | """.printf (post.url); 224 | } 225 | try { 226 | sparql.update (query); 227 | } catch (Error e) { 228 | error (e.message); 229 | } 230 | } 231 | 232 | public List get_feed_list () { 233 | string query = """ 234 | SELECT 235 | nie:url(?chan) AS url 236 | nie:title(?chan) AS title 237 | { 238 | ?chan a mfo:FeedChannel 239 | } 240 | ORDER BY nie:title(?chan) 241 | """; 242 | var feeds = new List (); 243 | try { 244 | var result = sparql.query (query); 245 | 246 | while (result.next ()) { 247 | feeds.append (new Feed (parse_cursor (result))); 248 | } 249 | } catch (DBusError derror) { 250 | error ("There was an error to communicate with the dbus interface %s", derror.message); 251 | } catch (IOError ioerror) { 252 | error ("There was an error to communicate with the io interface %s", ioerror.message); 253 | } catch (Error err) { 254 | error ("A general error occurred %s", err.message); 255 | } 256 | return feeds; 257 | } 258 | 259 | public void remove_channel (string url) { 260 | 261 | string messages = """ 262 | DELETE 263 | { ?msg a mfo:FeedMessage } 264 | WHERE 265 | { 266 | ?msg nmo:communicationChannel ?chan . 267 | ?chan nie:url "%s" 268 | } 269 | """.printf (url); 270 | try { 271 | sparql.update (messages); 272 | } catch (Error e) { 273 | error (e.message); 274 | } 275 | 276 | string communicationChannel = """ 277 | DELETE 278 | { ?chan a rdfs:Resource } 279 | WHERE 280 | { ?chan nie:url "%s" } 281 | """.printf (url); 282 | try { 283 | sparql.update (communicationChannel); 284 | } catch (Error e) { 285 | error (e.message); 286 | } 287 | } 288 | 289 | private HashTable parse_cursor (Sparql.Cursor cursor) { 290 | HashTable parsed_data = new HashTable (str_hash, str_equal); 291 | var n_columns = cursor.n_columns; 292 | 293 | for (int i = 0; i < n_columns; i++) { 294 | var vtype = cursor.get_value_type (i); 295 | 296 | switch (vtype) { 297 | case Sparql.ValueType.STRING: 298 | parsed_data.insert (cursor.get_variable_name(i), cursor.get_string (i)); break; 299 | case Sparql.ValueType.BOOLEAN: 300 | parsed_data.insert (cursor.get_variable_name(i), cursor.get_boolean (i)); break; 301 | case Sparql.ValueType.URI: 302 | parsed_data.insert (cursor.get_variable_name(i), cursor.get_string (i)); break; 303 | case Sparql.ValueType.INTEGER: 304 | parsed_data.insert (cursor.get_variable_name(i), cursor.get_integer (i)); break; 305 | case Sparql.ValueType.DOUBLE: 306 | parsed_data.insert (cursor.get_variable_name(i), cursor.get_double (i)); break; 307 | case Sparql.ValueType.DATETIME: 308 | var tv = TimeVal(); 309 | tv.from_iso8601 (cursor.get_string (i)); 310 | parsed_data.insert (cursor.get_variable_name (i), new DateTime.from_timeval_local (tv)); 311 | break; 312 | default: 313 | var column = cursor.get_string (i); 314 | if (column != null) { 315 | parsed_data.insert (cursor.get_variable_name(i), cursor.get_string (i)); 316 | } else { 317 | parsed_data.insert (cursor.get_variable_name(i), ""); 318 | } 319 | break; 320 | } 321 | } 322 | 323 | return parsed_data; 324 | } 325 | 326 | } 327 | } 328 | -------------------------------------------------------------------------------- /src/feed.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * feed.vala 3 | * This file is part of news 4 | * 5 | * Copyright (C) 2017 - Günther Wutz 6 | * 7 | * news is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * news is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with news. If not, see . 19 | */ 20 | 21 | using Tracker; 22 | namespace News { 23 | 24 | public class Feed : Object { 25 | public string title { get; set; } 26 | public string url { get; set; } 27 | 28 | public Feed (HashTable data) { 29 | title = (string) data.get ("title"); 30 | url = (string) data.get ("url"); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * main.vala 3 | * This file is part of news 4 | * 5 | * Copyright (C) 2017 - Günther Wutz 6 | * 7 | * news is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * news is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with news. If not, see . 19 | */ 20 | namespace News { 21 | public static void main(string[] args) { 22 | var app = new News.UI.Application (); 23 | app.run (args); 24 | } 25 | } 26 | 27 | -------------------------------------------------------------------------------- /src/meson.build: -------------------------------------------------------------------------------- 1 | 2 | news_sources = [ 3 | 'main.vala', 4 | 'controller.vala', 5 | 'tracker.vala', 6 | 'post.vala', 7 | 'feed.vala', 8 | 'ui/application.vala', 9 | 'ui/application-window.vala', 10 | 'ui/article-list.vala', 11 | 'ui/article-box.vala', 12 | 'ui/article-view.vala', 13 | 'ui/new-view.vala', 14 | 'ui/feed-view.vala', 15 | 'ui/star-view.vala', 16 | 'ui/search-view.vala', 17 | 'ui/updateable.vala', 18 | 'ui/switchable.vala', 19 | 'worker/company.vala', 20 | 'worker/worker.vala', 21 | 'worker/image-loader.vala', 22 | news_resources 23 | ] 24 | 25 | executable ('news', 26 | news_sources, 27 | dependencies: [glib, gobject, gio, gtk, sparql, webkit], 28 | vala_args:['--target-glib=2.38', '--gresources=' + meson.source_root () + '/data/news-resource.xml'], 29 | install: true 30 | ) 31 | -------------------------------------------------------------------------------- /src/post.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * post.vala 3 | * This file is part of news 4 | * 5 | * Copyright (C) 2017 - Günther Wutz 6 | * 7 | * news is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * news is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with news. If not, see . 19 | */ 20 | 21 | using Tracker; 22 | namespace News { 23 | public class Post : Object { 24 | 25 | public signal void thumb_ready(); 26 | 27 | public string title { get; set; } 28 | public string content { get; set; } 29 | public string url { get; set; } 30 | public string author { get; set; } 31 | public string author_homepage { get; set; } 32 | public string author_email { get; set; } 33 | public DateTime date { get; set; } 34 | public string thumbnail { get; set; } 35 | public bool starred { get; set; } 36 | public bool read { get; set; } 37 | public bool thumb_exists = false; 38 | 39 | public Post (HashTable data) { 40 | this.title = (string) data.get ("title"); 41 | this.content = (string) data.get ("content"); 42 | this.url = (string) data.get ("url"); 43 | this.author = (string) data.get ("fullname"); 44 | this.author_homepage = (string) data.get ("author_homepage"); 45 | this.author_email = (string) data.get ("author_email"); 46 | this.date = (DateTime) data.get ("date"); 47 | this.read = (bool) data.get ("is_read"); 48 | this.starred = (bool) data.get ("is_starred"); 49 | 50 | debug ("Author: %s", this.author); 51 | this.thumbnail = News.UI.Application.CACHE + compute_hash () + ".png"; 52 | if( !FileUtils.test (this.thumbnail, FileTest.EXISTS) ) { 53 | Idle.add (() => { 54 | generate_thumbnail (); 55 | return false; 56 | }); 57 | } else { 58 | thumb_exists = true; 59 | } 60 | } 61 | 62 | private string compute_hash() { 63 | return Checksum.compute_for_string (ChecksumType.MD5, this.url); 64 | } 65 | 66 | // Thumbnail shit 67 | private WebKit.WebView webview; 68 | 69 | public void generate_thumbnail() { 70 | this.webview = new WebKit.WebView (); 71 | this.webview.web_context.get_cookie_manager () 72 | .set_accept_policy (WebKit.CookieAcceptPolicy.NEVER); 73 | this.webview.sensitive = false; 74 | this.webview.load_changed.connect (draw_thumbnail); 75 | var author = this.author != null ? this.author : ""; 76 | var app = GLib.Application.get_default () as News.UI.Application; 77 | try { 78 | string html = app.load_from_resource ("/org/gnome/News/theme/articlebox.html") 79 | .printf (title, author, content); 80 | debug (html); 81 | this.webview.load_html (html, null); 82 | } catch (Error e) { 83 | critical (e.message); 84 | } 85 | } 86 | 87 | private void draw_thumbnail(WebKit.LoadEvent event) { 88 | if( event == WebKit.LoadEvent.FINISHED ){ 89 | debug ("thumb: %s\n", thumbnail); 90 | this.webview.get_snapshot.begin (WebKit.SnapshotRegion.FULL_DOCUMENT, 91 | WebKit.SnapshotOptions.NONE, 92 | null, 93 | (obj, res) => { 94 | try { 95 | var surface = this.webview.get_snapshot.end (res); 96 | var new_surface = new Cairo.ImageSurface (Cairo.Format.ARGB32, 256, 256); 97 | var ctx = new Cairo.Context (new_surface); 98 | ctx.set_source_surface (surface, 0, 0); 99 | ctx.paint (); 100 | new_surface.write_to_png (thumbnail); 101 | thumb_exists = true; 102 | thumb_ready (); 103 | } catch ( Error e ){ 104 | error (e.message); 105 | } 106 | 107 | }); 108 | } 109 | } 110 | 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/tracker.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * tracker.vala 3 | * This file is part of news 4 | * 5 | * Copyright (C) 2017 - Günther Wutz 6 | * 7 | * news is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * news is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with news. If not, see . 19 | */ 20 | 21 | namespace News { 22 | 23 | [DBus (name = "org.freedesktop.Tracker1.Miner")] 24 | public interface TrackerRss : Object { 25 | public abstract void Start() throws IOError; 26 | 27 | } 28 | 29 | [DBus (name = "org.freedesktop.Tracker1.Resources")] 30 | public interface Tracker : Object { 31 | [DBus (name = "GraphUpdated")] 32 | public signal void graph_updated(string classname, ResourcesDeleteStruct[] deletes, ResourcesInsertStruct[] inserts); 33 | 34 | } 35 | 36 | public struct ResourcesDeleteStruct { 37 | public int attr1; 38 | public int attr2; 39 | public int attr3; 40 | public int attr4; 41 | } 42 | 43 | public struct ResourcesInsertStruct { 44 | public int attr1; 45 | public int attr2; 46 | public int attr3; 47 | public int attr4; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/ui/application-window.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * application-window.vala 3 | * This file is part of news 4 | * 5 | * Copyright (C) 2017 - Günther Wutz 6 | * 7 | * news is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * news is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with news. If not, see . 19 | */ 20 | 21 | namespace News.UI { 22 | 23 | [GtkTemplate (ui = "/org/gnome/News/ui/window.ui")] 24 | public class Window : Gtk.ApplicationWindow { 25 | 26 | private bool is_flow = true; 27 | 28 | [GtkChild (name = "Stack")] 29 | private Gtk.Stack stack; 30 | 31 | [GtkChild (name = "ViewMode")] 32 | private Gtk.Button view_mode; 33 | 34 | [GtkChild (name = "BackButton")] 35 | private Gtk.Button back_btn; 36 | 37 | [GtkChild (name = "StarButton")] 38 | private Gtk.Button star_btn; 39 | 40 | [GtkChild (name = "SearchButton")] 41 | private Gtk.ToggleButton search_btn; 42 | 43 | [GtkChild (name = "AddFeed")] 44 | private Gtk.MenuButton add_feed_btn; 45 | 46 | [GtkChild (name = "StackSwitcher")] 47 | private Gtk.StackSwitcher switcher; 48 | 49 | [GtkChild (name = "NewUrl")] 50 | private Gtk.Entry new_url; 51 | 52 | [GtkChild (name = "NewUrlButton")] 53 | private Gtk.Button new_url_btn; 54 | 55 | [GtkChild (name = "SearchBar")] 56 | private Gtk.SearchBar search_bar; 57 | 58 | [GtkChild (name = "SearchEntry")] 59 | private Gtk.SearchEntry search_entry; 60 | 61 | private Gtk.Widget previous_view = null; 62 | 63 | public Window (Application app) { 64 | Object (application: app); 65 | 66 | view_mode.set_image (new Gtk.Image.from_icon_name ("view-list-symbolic", Gtk.IconSize.MENU)); 67 | 68 | this.back_btn.clicked.connect (return_article); 69 | 70 | var new_view = new News.UI.NewView (); 71 | stack.add_titled (new_view, new_view.name, new_view.name); 72 | 73 | var feed_view = new News.UI.FeedView (); 74 | stack.add_titled (feed_view, feed_view.name, feed_view.name); 75 | 76 | var star_view = new News.UI.StarView (); 77 | stack.add_titled (star_view, star_view.name, star_view.name); 78 | 79 | var search_view = new News.UI.SearchView (); 80 | search_entry.bind_property ("text", search_view, "search_query"); 81 | stack.add_named (search_view, search_view.name); 82 | 83 | var article_view = new News.UI.ArticleView (); 84 | stack.add_named (article_view, article_view.name); 85 | 86 | stack.notify["visible-child"].connect (view_changed); 87 | view_changed (); 88 | } 89 | 90 | private void view_changed () { 91 | var to_view = stack.get_visible_child (); 92 | if (to_view is News.UI.Updateable) { 93 | var updateable = to_view as News.UI.Updateable; 94 | updateable.update (); 95 | } 96 | } 97 | 98 | internal void show_article (News.Post post) { 99 | //article = new ArticleView (); 100 | search_bar.set_search_mode (false); 101 | var article = stack.get_child_by_name ("Article") as ArticleView; 102 | article.post = post; 103 | article.show_all (); 104 | this.previous_view = this.stack.get_visible_child (); 105 | //this.stack.add_named (article, "feedview"); 106 | this.stack.set_visible_child (article); 107 | this.stack.show_all (); 108 | set_headerbar_article (post); 109 | var app = get_application () as Application; 110 | app.controller.mark_post_as_read (post); 111 | } 112 | 113 | private void return_article (Gtk.Button btn) { 114 | this.search_entry.text = ""; 115 | this.stack.set_visible_child (this.previous_view); 116 | this.previous_view = null; 117 | set_headerbar_main (); 118 | } 119 | 120 | private void set_headerbar_article (Post post) { 121 | this.add_feed_btn.hide (); 122 | this.switcher.hide (); 123 | this.search_btn.hide (); 124 | this.view_mode.hide (); 125 | this.star_btn.show (); 126 | this.back_btn.show (); 127 | 128 | if (post.starred) { 129 | this.star_btn.set_image (new Gtk.Image.from_icon_name ("starred-symbolic", Gtk.IconSize.MENU)); 130 | } else { 131 | this.star_btn.set_image (new Gtk.Image.from_icon_name ("non-starred-symbolic", Gtk.IconSize.MENU)); 132 | } 133 | } 134 | 135 | private void set_headerbar_search () { 136 | this.add_feed_btn.hide (); 137 | this.switcher.hide (); 138 | this.view_mode.hide (); 139 | this.back_btn.show (); 140 | } 141 | 142 | private void set_headerbar_main () { 143 | this.add_feed_btn.show (); 144 | this.switcher.show (); 145 | this.search_btn.show (); 146 | this.view_mode.show (); 147 | this.back_btn.hide (); 148 | this.star_btn.hide (); 149 | } 150 | 151 | 152 | [GtkCallback] 153 | private void star_article (Gtk.Button btn) { 154 | var app = get_application () as Application; 155 | var article = stack.get_child_by_name ("Article") as ArticleView; 156 | if (article.post.starred) { 157 | this.star_btn.set_image (new Gtk.Image.from_icon_name ("non-starred-symbolic", Gtk.IconSize.MENU)); 158 | } else { 159 | this.star_btn.set_image (new Gtk.Image.from_icon_name ("starred-symbolic", Gtk.IconSize.MENU)); 160 | } 161 | app.controller.mark_post_as_starred (article.post, !article.post.starred); 162 | article.post.starred = !article.post.starred; 163 | } 164 | 165 | [GtkCallback] 166 | private void mode_switched () { 167 | 168 | var active_view = stack.get_visible_child (); 169 | if (active_view is Switchable) { 170 | (active_view as Switchable).switch_mode (); 171 | } 172 | if (is_flow) { 173 | view_mode.set_image (new Gtk.Image.from_icon_name ("view-grid-symbolic", Gtk.IconSize.MENU)); 174 | } else { 175 | view_mode.set_image (new Gtk.Image.from_icon_name ("view-list-symbolic", Gtk.IconSize.MENU)); 176 | } 177 | is_flow = !is_flow; 178 | } 179 | 180 | [GtkCallback] 181 | private void add_new_url (Gtk.Button button) { 182 | var app = get_application () as Application; 183 | app.controller.add_channel (new_url.get_text ()); 184 | } 185 | 186 | [GtkCallback] 187 | private void search_btn_toggled () { 188 | if (search_bar.search_mode_enabled) { 189 | search_bar.set_search_mode (false); 190 | } else { 191 | search_bar.set_search_mode (true); 192 | } 193 | } 194 | 195 | [GtkCallback] 196 | private void on_url_changed (Gtk.Editable entry) { 197 | var url = new_url.get_text (); 198 | if (url.length == 0) { 199 | new_url_btn.set_sensitive (false); 200 | } else { 201 | new_url_btn.set_sensitive (true); 202 | } 203 | } 204 | 205 | [GtkCallback] 206 | private void on_search_changed () { 207 | if (search_entry.text_length > 0) { 208 | if (stack.get_visible_child_name () != "Search") { 209 | previous_view = stack.get_visible_child (); 210 | set_headerbar_search (); 211 | stack.set_visible_child_name ("Search"); 212 | } 213 | } 214 | } 215 | } 216 | } 217 | -------------------------------------------------------------------------------- /src/ui/application.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * application.vala 3 | * This file is part of news 4 | * 5 | * Copyright (C) 2017 - Günther Wutz 6 | * 7 | * news is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * news is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with news. If not, see . 19 | */ 20 | 21 | namespace News.UI { 22 | 23 | public class Application : Gtk.Application { 24 | public static string CACHE = Environment.get_user_cache_dir () + "/News/"; 25 | public Controller controller; 26 | private TrackerRss tracker_rss; 27 | private Tracker tracker; 28 | 29 | public Application () { 30 | Object (application_id: "org.gnome.News"); 31 | 32 | controller = new Controller (); 33 | 34 | if (!FileUtils.test (CACHE, FileTest.EXISTS)) { 35 | try { 36 | File.new_for_path (CACHE).make_directory (); 37 | } catch (Error e) { 38 | warning (e.message); 39 | } 40 | } 41 | var delete_channel_action = new SimpleAction("delete_channel", VariantType.INT32); 42 | add_action(delete_channel_action); 43 | var mark_all_as_read_action = new SimpleAction("mark_all_as_read", VariantType.INT32); 44 | add_action(mark_all_as_read_action); 45 | 46 | try { 47 | tracker_rss = Bus.get_proxy_sync(BusType.SESSION, "org.freedesktop.Tracker1.Miner.RSS", 48 | "/org/freedesktop/Tracker1/Miner/RSS"); 49 | tracker = Bus.get_proxy_sync(BusType.SESSION, "org.freedesktop.Tracker1", 50 | "/org/freedesktop/Tracker1/Resources"); 51 | tracker.graph_updated.connect ((classname, deleted, inserted) => { 52 | // http://www.tracker-project.org/temp/mfo#FeedMessage 53 | 54 | if (classname == "http://www.tracker-project.org/temp/mfo#FeedMessage") { 55 | controller.items_updated (); 56 | } 57 | }); 58 | tracker_rss.Start (); 59 | } catch ( IOError e ){ 60 | error (e.message); 61 | } 62 | } 63 | 64 | public string load_from_resource (string uri) throws IOError, Error { 65 | var stream = resources_open_stream (uri, ResourceLookupFlags.NONE); 66 | var dis = new DataInputStream(stream); 67 | StringBuilder builder = new StringBuilder (); 68 | string line; 69 | while ( (line = dis.read_line (null)) != null ) { 70 | builder.append (line); 71 | } 72 | return builder.str.dup (); 73 | } 74 | 75 | private void setup_css_theming () { 76 | var screen = Gdk.Screen.get_default (); 77 | var cssprovider = new Gtk.CssProvider (); 78 | cssprovider.load_from_resource ("/org/gnome/News/theme/Adwaita.css"); 79 | Gtk.StyleContext.add_provider_for_screen (screen, cssprovider, Gtk.STYLE_PROVIDER_PRIORITY_USER); 80 | } 81 | 82 | protected override void startup () { 83 | base.startup (); 84 | 85 | var builder = new Gtk.Builder.from_resource ("/org/gnome/News/appmenu.ui"); 86 | var menu = (MenuModel) builder.get_object ("appmenu"); 87 | this.set_app_menu (menu); 88 | 89 | var quit_action = new SimpleAction ("app.quit", null); 90 | quit_action.activate.connect (quit_cb); 91 | this.add_action (quit_action); 92 | } 93 | 94 | void quit_cb (SimpleAction action, Variant? param) { 95 | print ("Quit\n"); 96 | } 97 | 98 | protected override void activate () { 99 | setup_css_theming (); 100 | var window = new News.UI.Window (this); 101 | this.add_window (window); 102 | 103 | window.show (); 104 | } 105 | 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /src/ui/article-box.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * article-box.vala 3 | * This file is part of news 4 | * 5 | * Copyright (C) 2017 - Günther Wutz 6 | * 7 | * news is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * news is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with news. If not, see . 19 | */ 20 | 21 | namespace News.UI { 22 | 23 | public class ArticleBox : Gtk.Overlay { 24 | public Post post { get; set; } 25 | public Gtk.Image img; 26 | private Gtk.Spinner spinner; 27 | 28 | public ArticleBox (Post post) { 29 | Object (); 30 | spinner = new Gtk.Spinner (); 31 | spinner.get_style_context ().add_class ("postspinner"); 32 | this.height_request = 256; 33 | this.width_request = 256; 34 | 35 | img = new Gtk.Image (); 36 | img.get_style_context ().add_class ("feedbox"); 37 | this.add (img); 38 | 39 | set_post_data (post); 40 | 41 | this.valign = Gtk.Align.START; 42 | this.halign = Gtk.Align.START; 43 | this.show_all (); 44 | } 45 | 46 | // FIXME: Use properties for setting! 47 | public void set_post_data (Post post) { 48 | this.post = post; 49 | if (!post.thumb_exists) { 50 | spinner.start (); 51 | post.thumb_ready.connect (show_image); 52 | add_overlay (spinner); 53 | } else { 54 | Lumber.Company.get_instance ().enqueue (new News.Background.ImageLoader(this)); 55 | //img.set_from_file (post.thumbnail); 56 | } 57 | 58 | if (post.read) { 59 | img.set_opacity (0.5); 60 | } 61 | } 62 | 63 | public void clear () { 64 | post = null; 65 | img.clear (); 66 | } 67 | 68 | private void show_image () { 69 | spinner.stop (); 70 | remove (spinner); 71 | img.set_from_file (post.thumbnail); 72 | show_all (); 73 | post.thumb_ready.disconnect (show_image); 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/ui/article-list.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * article-list.vala 3 | * This file is part of news 4 | * 5 | * Copyright (C) 2017 - Günther Wutz 6 | * 7 | * news is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * news is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with news. If not, see . 19 | */ 20 | 21 | namespace News.UI { 22 | [GtkTemplate (ui = "/org/gnome/News/ui/articlerow.ui")] 23 | public class ArticleList : Gtk.Box { 24 | public Post post { get; set; } 25 | 26 | [GtkChild (name = "title")] 27 | private Gtk.Label title; 28 | 29 | [GtkChild (name = "author")] 30 | private Gtk.Label author; 31 | 32 | [GtkChild (name = "date")] 33 | private Gtk.Label date; 34 | 35 | [GtkChild (name = "starred")] 36 | private Gtk.Button starred; 37 | 38 | public ArticleList (Post p) { 39 | this.get_style_context ().add_class ("feeds-list"); 40 | set_post_data (p); 41 | 42 | this.show_all (); 43 | } 44 | 45 | public void set_post_data (Post post) { 46 | this.post = post; 47 | 48 | this.title.set_text(post.title); 49 | this.author.set_text(post.author); 50 | var date_str = post.date.format ("%d. %B"); 51 | var now = new DateTime.now_local (); 52 | var diff = now.difference (this.post.date)/TimeSpan.DAY; 53 | 54 | if (diff == 0) date_str = "Today"; 55 | else if (diff == 1) date_str = "Yesterday"; 56 | 57 | this.date.set_text (date_str); 58 | 59 | if (post.starred) { 60 | starred.image = new Gtk.Image.from_icon_name ("starred-symbolic", Gtk.IconSize.MENU); 61 | } 62 | } 63 | 64 | [GtkCallback] 65 | private void star_article (Gtk.Button btn) { 66 | if (post.starred) { 67 | //unstar 68 | starred.image = new Gtk.Image.from_icon_name ("non-starred-symbolic", Gtk.IconSize.MENU); 69 | } else { 70 | //star 71 | starred.image = new Gtk.Image.from_icon_name ("starred-symbolic", Gtk.IconSize.MENU); 72 | } 73 | 74 | var app = GLib.Application.get_default() as Application; 75 | app.controller.mark_post_as_starred (post, !post.starred); 76 | post.starred = !post.starred; 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/ui/article-view.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * feed-view.vala 3 | * This file is part of news 4 | * 5 | * Copyright (C) 2017 - Günther Wutz 6 | * 7 | * news is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * news is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with news. If not, see . 19 | */ 20 | 21 | namespace News.UI { 22 | 23 | public class ArticleView : WebKit.WebView { 24 | private Post _post; 25 | public Post post { 26 | get { 27 | return _post; 28 | } 29 | set { 30 | _post = value; 31 | debug ("Author: %s", _post.author); 32 | var author = _post.author != null? _post.author : ""; 33 | var html = """ 34 | 162 | 163 |
164 |

%s

165 | %s 166 |

%s

167 | 172 |
173 | 174 | """.printf (post.title, author, post.content, post.author_homepage, post.author_homepage, post.author_email, post.title, post.author_email, post.url); 175 | debug ("Author Homepage: %s", post.author_homepage); 176 | load_html(html, null); 177 | } 178 | } 179 | 180 | public ArticleView () { 181 | Object (name: "Article"); 182 | decide_policy.connect (on_policy); 183 | } 184 | 185 | private bool on_policy (WebKit.PolicyDecision decision, WebKit.PolicyDecisionType type) { 186 | if (type == WebKit.PolicyDecisionType.NAVIGATION_ACTION) { 187 | var navidecision = decision as WebKit.NavigationPolicyDecision; 188 | var uri = navidecision.get_navigation_action ().get_request ().get_uri (); 189 | if (uri != "about:blank" && navidecision.get_navigation_action ().get_navigation_type () == WebKit.NavigationType.LINK_CLICKED) { 190 | navidecision.ignore (); 191 | try { 192 | Gtk.show_uri (null, uri, Gdk.CURRENT_TIME); 193 | } catch (Error e) { 194 | warning (e.message); 195 | } 196 | } 197 | return true; 198 | } 199 | return false; 200 | } 201 | 202 | } 203 | 204 | } 205 | -------------------------------------------------------------------------------- /src/ui/feed-view.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * feed-view.vala 3 | * This file is part of news 4 | * 5 | * Copyright (C) 2017 - Günther Wutz 6 | * 7 | * news is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * news is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with news. If not, see . 19 | */ 20 | 21 | namespace News.UI { 22 | public class FeedView : Gtk.Paned, Updateable, Switchable { 23 | private ModeType mode = ModeType.FLOW; 24 | private Gtk.ScrolledWindow posts_scroll; 25 | private Gtk.ListBox feeds_list; 26 | private Gtk.FlowBox posts_box; 27 | private Gtk.ListBox posts_list; 28 | private Gtk.Widget selected_article = null; 29 | private bool should_update = true; 30 | 31 | public FeedView () { 32 | Object (orientation: Gtk.Orientation.HORIZONTAL, name: "Feeds"); 33 | load_view (); 34 | show_all (); 35 | } 36 | 37 | private void load_view () { 38 | var app = GLib.Application.get_default () as Application; 39 | app.controller.items_updated.connect (update); 40 | 41 | // left pane side 42 | var feeds_scroll = new Gtk.ScrolledWindow (null, null); 43 | feeds_scroll.width_request = 200; 44 | feeds_list = new Gtk.ListBox (); 45 | feeds_list.get_style_context ().add_class ("sidebar"); 46 | feeds_list.row_activated.connect (feed_selected); 47 | feeds_list.button_release_event.connect (list_box_button_release); 48 | feeds_scroll.add (feeds_list); 49 | add1 (feeds_scroll); 50 | 51 | // right pane side 52 | posts_scroll = new Gtk.ScrolledWindow (null, null); 53 | posts_box = new Gtk.FlowBox (); 54 | posts_box.set_min_children_per_line (2); 55 | posts_scroll.vexpand = false; 56 | posts_box.valign = Gtk.Align.START; 57 | posts_box.child_activated.connect (show_article_box); 58 | posts_scroll.add (posts_box); 59 | add2 (posts_scroll); 60 | 61 | posts_list = new Gtk.ListBox (); 62 | posts_list.row_activated.connect (show_article_list); 63 | 64 | var delete_action = app.lookup_action("delete_channel") as SimpleAction; 65 | delete_action.activate.connect (delete_channel); 66 | var mark_all_as_read_action = app.lookup_action("mark_all_as_read") as SimpleAction; 67 | mark_all_as_read_action.activate.connect (mark_all_as_read); 68 | } 69 | 70 | public void update () { 71 | // only update the articlebox and leave view untouched 72 | if (!should_update && selected_article != null) { 73 | debug ("update only child"); 74 | should_update = true; 75 | News.Post post; 76 | if (mode == ModeType.FLOW) { 77 | post = (selected_article as ArticleBox).post; 78 | post.read = true; 79 | (selected_article as ArticleBox).set_post_data (post); 80 | posts_box.unselect_child (posts_box.get_selected_children ().first ().data); 81 | } else { 82 | post = (selected_article as ArticleList).post; 83 | post.read = true; 84 | (selected_article as ArticleList).set_post_data (post); 85 | posts_list.unselect_row(posts_list.get_selected_row()); 86 | } 87 | selected_article = null; 88 | return; 89 | } 90 | var old_list = feeds_list.get_children (); 91 | foreach(Gtk.Widget w in old_list) { 92 | w.destroy (); 93 | } 94 | var app = GLib.Application.get_default () as Application; 95 | var feeds = app.controller.get_feed_list (); 96 | debug ("start update"); 97 | foreach (Feed feed in feeds) { 98 | debug ("add Feed %s", feed.title); 99 | var row = new FeedRow (feed); 100 | feeds_list.add (row); 101 | if (feed == feeds.first ().data) { 102 | feeds_list.select_row (row); 103 | } 104 | } 105 | 106 | if (feeds.length () != 0) { 107 | var posts = app.controller.post_sorted_by_channel (feeds.first ().data.url); 108 | populate_posts (posts); 109 | } 110 | show_all (); 111 | } 112 | 113 | public void switch_mode () { 114 | if (mode == ModeType.FLOW) { 115 | mode = ModeType.LIST; 116 | posts_scroll.remove (posts_box); 117 | posts_box.@foreach ((w) => { w.destroy (); }); 118 | posts_scroll.add (posts_list); 119 | } else { 120 | mode = ModeType.FLOW; 121 | posts_scroll.remove (posts_list); 122 | posts_list.@foreach ((w) => { w.destroy (); }); 123 | posts_scroll.add (posts_box); 124 | } 125 | 126 | update (); 127 | } 128 | 129 | private void populate_posts (List posts) { 130 | if (mode == ModeType.FLOW) { 131 | var old_boxes = posts_box.get_children (); 132 | foreach (Gtk.Widget w in old_boxes) { 133 | w.destroy (); 134 | } 135 | 136 | foreach (Post post in posts) { 137 | posts_box.add (new ArticleBox (post)); 138 | } 139 | } else { 140 | var old_rows = posts_list.get_children (); 141 | foreach (Gtk.Widget w in old_rows) { 142 | w.destroy (); 143 | } 144 | 145 | foreach (Post post in posts) { 146 | posts_list.add (new ArticleList (post)); 147 | } 148 | } 149 | } 150 | 151 | private void feed_selected (Gtk.ListBoxRow row) { 152 | var feedrow = row as FeedRow; 153 | var app = GLib.Application.get_default () as Application; 154 | 155 | var posts = app.controller.post_sorted_by_channel (feedrow.feed.url); 156 | populate_posts (posts); 157 | } 158 | 159 | private bool list_box_button_release (Gdk.EventButton event) { 160 | var selected_row = feeds_list.get_row_at_y ((int)event.y); 161 | var button = event.button; 162 | if (button == Gdk.BUTTON_PRIMARY) { 163 | return Gdk.EVENT_PROPAGATE; 164 | } 165 | else if (button == Gdk.BUTTON_SECONDARY) { 166 | int index = selected_row.get_index (); 167 | var menu = new Menu (); 168 | menu.append ("Remove Channel", "app.delete_channel(%d)".printf (index)); 169 | menu.append ("Mark all as read", "app.mark_all_as_read(%d)".printf (index)); 170 | var popover = new Gtk.Popover.from_model (selected_row, menu); 171 | popover.set_position (Gtk.PositionType.BOTTOM); 172 | popover.show (); 173 | } 174 | return Gdk.EVENT_STOP; 175 | } 176 | 177 | private void show_article_list (Gtk.ListBoxRow row) { 178 | selected_article = row.get_child () as ArticleList; 179 | show_article (); 180 | } 181 | 182 | private void show_article_box (Gtk.FlowBoxChild child) { 183 | selected_article = child.get_child () as ArticleBox; 184 | show_article (); 185 | } 186 | 187 | private void show_article () { 188 | should_update = false; 189 | 190 | var toplevel = get_toplevel (); 191 | if (toplevel is Window) { 192 | var window = toplevel as Window; 193 | News.Post post; 194 | if (mode == ModeType.FLOW) 195 | post = (selected_article as ArticleBox).post; 196 | else 197 | post = (selected_article as ArticleList).post; 198 | window.show_article (post); 199 | } 200 | } 201 | 202 | private void delete_channel (Variant? parameter) { 203 | int index = (int)parameter.get_int32 (); 204 | var row = feeds_list.get_children ().nth_data (index) as FeedRow; 205 | if (row != null) { 206 | var app = GLib.Application.get_default () as Application; 207 | app.controller.remove_channel (row.feed.url); 208 | } 209 | } 210 | 211 | private void mark_all_as_read (Variant? parameter) { 212 | var outer = posts_box.get_children (); 213 | var app = GLib.Application.get_default () as Application; 214 | foreach (Gtk.Widget child in outer) { 215 | var flowchild = child as Gtk.FlowBoxChild; 216 | var box = flowchild.get_child () as ArticleBox; 217 | 218 | if (box != null) { 219 | app.controller.mark_post_as_read (box.post); 220 | } 221 | } 222 | } 223 | } 224 | 225 | class FeedRow : Gtk.ListBoxRow { 226 | public Feed feed { get; set; } 227 | 228 | public FeedRow (Feed feed) { 229 | this.feed = feed; 230 | var label = new Gtk.Label (feed.title); 231 | label.margin = 10; 232 | label.xalign = 0.0f; 233 | add (label); 234 | set_activatable (true); 235 | show_all (); 236 | } 237 | } 238 | } 239 | -------------------------------------------------------------------------------- /src/ui/new-view.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * new-view.vala 3 | * This file is part of news 4 | * 5 | * Copyright (C) 2017 - Günther Wutz 6 | * 7 | * news is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * news is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with news. If not, see . 19 | */ 20 | 21 | namespace News.UI { 22 | 23 | public class NewView : Gtk.ScrolledWindow, Updateable, Switchable { 24 | protected ModeType mode = ModeType.FLOW; 25 | private Gtk.Viewport container; 26 | protected Gtk.FlowBox posts_box; 27 | protected Gtk.ListBox posts_list; 28 | 29 | public NewView () { 30 | Object (name: "New"); 31 | load_view (); 32 | var app = GLib.Application.get_default () as Application; 33 | app.controller.items_updated.connect (update); 34 | app.controller.item_updated.connect (item_updated); 35 | show_all (); 36 | } 37 | 38 | protected void load_view () { 39 | container = new Gtk.Viewport (null, null); 40 | add (container); 41 | posts_box = new Gtk.FlowBox (); 42 | posts_box.valign = Gtk.Align.START; 43 | posts_box.margin = 15; 44 | posts_box.column_spacing = 20; 45 | posts_box.row_spacing = 30; 46 | posts_box.homogeneous = true; 47 | posts_box.child_activated.connect (show_article_flow); 48 | container.add (posts_box); 49 | } 50 | 51 | public virtual void update () { 52 | var app = GLib.Application.get_default () as Application; 53 | var posts = app.controller.post_sorted_by_date (true); 54 | if (mode == ModeType.FLOW) { 55 | var old_boxes = posts_box.get_children (); 56 | foreach (Gtk.Widget w in old_boxes) { 57 | w.destroy (); 58 | } 59 | 60 | foreach (Post post in posts) { 61 | posts_box.add (new ArticleBox (post)); 62 | } 63 | } else { 64 | var old_rowes = posts_list.get_children (); 65 | foreach (Gtk.Widget w in old_rowes) { 66 | w.destroy (); 67 | } 68 | 69 | foreach (Post post in posts) { 70 | posts_list.add (new ArticleList (post)); 71 | } 72 | } 73 | show_all (); 74 | } 75 | 76 | public void switch_mode () { 77 | if (mode == ModeType.FLOW) { 78 | mode = ModeType.LIST; 79 | container.remove (posts_box); 80 | posts_box = null; 81 | posts_list = new Gtk.ListBox (); 82 | posts_list.row_activated.connect (show_article_list); 83 | container.add (posts_list); 84 | } else { 85 | mode = ModeType.FLOW; 86 | container.remove (posts_list); 87 | posts_list = null; 88 | posts_box = new Gtk.FlowBox (); 89 | posts_box.valign = Gtk.Align.START; 90 | posts_box.margin = 15; 91 | posts_box.column_spacing = 20; 92 | posts_box.row_spacing = 30; 93 | posts_box.homogeneous = true; 94 | posts_box.child_activated.connect (show_article_flow); 95 | container.add (posts_box); 96 | } 97 | update (); 98 | } 99 | 100 | private void show_article_flow (Gtk.FlowBoxChild child) { 101 | News.Post post = ((ArticleBox)child.get_child()).post; 102 | show_article (post); 103 | } 104 | 105 | private void show_article_list (Gtk.ListBoxRow row) { 106 | News.Post post = ((ArticleList)row.get_child()).post; 107 | show_article (post); 108 | } 109 | 110 | private void show_article (Post post) { 111 | var toplevel = get_toplevel (); 112 | if (toplevel is Window) { 113 | var window = toplevel as Window; 114 | window.show_article (post); 115 | } 116 | } 117 | 118 | 119 | protected void item_updated (Post post, Controller.Updated updated) { 120 | if (updated == Controller.Updated.MARK_AS_READ) { 121 | // Do this a second later, so the transition is seamless and nicer 122 | Timeout.add(1000, () => { 123 | update (); 124 | return false; 125 | }); 126 | } 127 | 128 | } 129 | } 130 | 131 | } 132 | -------------------------------------------------------------------------------- /src/ui/search-view.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * search-view.vala 3 | * This file is part of news 4 | * 5 | * Copyright (C) 2017 - Günther Wutz 6 | * 7 | * news is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * news is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with news. If not, see . 19 | */ 20 | 21 | namespace News.UI { 22 | 23 | public class SearchView : NewView { 24 | private string _search_query; 25 | 26 | public string search_query { 27 | get { 28 | return _search_query; 29 | } 30 | set { 31 | _search_query = value; 32 | update (); 33 | } 34 | } 35 | 36 | public SearchView () { 37 | Object (name: "Search"); 38 | load_view (); 39 | show_all (); 40 | } 41 | 42 | public override void update () { 43 | if (_search_query.length == 0) return; 44 | var app = GLib.Application.get_default () as Application; 45 | var posts = app.controller.post_by_search (_search_query); 46 | foreach (Post p in posts) { 47 | debug ("Title: %s", p.title); 48 | debug ("Is starred: %s", p.starred?"yes":"no"); 49 | } 50 | if (mode == ModeType.FLOW) { 51 | var old_boxes = posts_box.get_children (); 52 | foreach (Gtk.Widget w in old_boxes) { 53 | w.destroy (); 54 | } 55 | 56 | foreach (Post post in posts) { 57 | posts_box.add (new ArticleBox (post)); 58 | } 59 | } else { 60 | var old_rowes = posts_list.get_children (); 61 | foreach (Gtk.Widget w in old_rowes) { 62 | w.destroy (); 63 | } 64 | 65 | foreach (Post post in posts) { 66 | posts_list.add (new ArticleList (post)); 67 | } 68 | } 69 | show_all (); 70 | } 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /src/ui/star-view.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * star-view.vala 3 | * This file is part of news 4 | * 5 | * Copyright (C) 2017 - Günther Wutz 6 | * 7 | * news is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * news is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with news. If not, see . 19 | */ 20 | 21 | namespace News.UI { 22 | 23 | public class StarView : NewView { 24 | 25 | public StarView () { 26 | Object (name: "Starred"); 27 | load_view (); 28 | var app = GLib.Application.get_default () as Application; 29 | app.controller.items_updated.connect (update); 30 | app.controller.item_updated.connect (item_updated); 31 | show_all (); 32 | } 33 | 34 | public override void update () { 35 | var app = GLib.Application.get_default () as Application; 36 | var posts = app.controller.post_sorted_by_date (false, true); 37 | foreach (Post p in posts) { 38 | debug ("Title: %s", p.title); 39 | debug ("Is starred: %s", p.starred?"yes":"no"); 40 | } 41 | if (mode == ModeType.FLOW) { 42 | var old_boxes = posts_box.get_children (); 43 | foreach (Gtk.Widget w in old_boxes) { 44 | w.destroy (); 45 | } 46 | 47 | foreach (Post post in posts) { 48 | posts_box.add (new ArticleBox (post)); 49 | } 50 | } else { 51 | var old_rowes = posts_list.get_children (); 52 | foreach (Gtk.Widget w in old_rowes) { 53 | w.destroy (); 54 | } 55 | 56 | foreach (Post post in posts) { 57 | posts_list.add (new ArticleList (post)); 58 | } 59 | } 60 | show_all (); 61 | } 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /src/ui/switchable.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * switchable.vala 3 | * This file is part of news 4 | * 5 | * Copyright (C) 2017 - Günther Wutz 6 | * 7 | * news is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * news is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with news. If not, see . 19 | */ 20 | 21 | namespace News.UI { 22 | 23 | public enum ModeType { 24 | FLOW, 25 | LIST 26 | } 27 | 28 | public interface Switchable : Object { 29 | public abstract void switch_mode (); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/ui/updateable.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * updateable.vala 3 | * This file is part of news 4 | * 5 | * Copyright (C) 2017 - Günther Wutz 6 | * 7 | * news is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * news is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with news. If not, see . 19 | */ 20 | 21 | namespace News.UI { 22 | 23 | public interface Updateable : Object { 24 | public abstract void update (); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/ui/widget-factory.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * widget-factory.vala 3 | * This file is part of news 4 | * 5 | * Copyright (C) 2017 - Günther Wutz 6 | * 7 | * news is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * news is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with news. If not, see . 19 | */ 20 | 21 | namespace News.UI { 22 | 23 | public class WidgetFactory : Object { 24 | 25 | private Queue flow_childs = new Queue(); 26 | private Queue list_childs = new Queue(); 27 | 28 | public Gtk.FlowBoxChild get_article_box (Post post) { 29 | if (flow_childs.is_empty ()) { 30 | var outer = new Gtk.FlowBoxChild (); 31 | outer.add (new ArticleBox (post)); 32 | outer.show (); 33 | return outer; 34 | } 35 | 36 | var outer = flow_childs.pop_head (); 37 | var box = outer.get_child () as ArticleBox; 38 | assert (box != null); 39 | box.set_post_data (post); 40 | outer.show (); 41 | return outer; 42 | } 43 | 44 | public void remove_article_box (Gtk.FlowBoxChild outer) { 45 | var box = outer.get_child () as ArticleBox; 46 | assert (box != null); 47 | box.clear (); 48 | flow_childs.push_head (outer); 49 | } 50 | 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/worker/company.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * company.vala 3 | * This file is part of news 4 | * 5 | * Copyright (C) 2017 - Günther Wutz 6 | * 7 | * news is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * news is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with news. If not, see . 19 | */ 20 | 21 | namespace Lumber { 22 | 23 | public class Company : Object { 24 | static Company? _instance; 25 | private ThreadPool thread_pool = null; 26 | private AsyncQueue queue = new AsyncQueue(); 27 | 28 | Company () { 29 | try { 30 | thread_pool = new ThreadPool.with_owned_data( 31 | on_work_ready, 2, false 32 | ); 33 | } catch (ThreadError e) { 34 | error(e.message); 35 | } 36 | } 37 | 38 | public static Company get_instance () { 39 | if (_instance == null) 40 | _instance = new Company (); 41 | return _instance; 42 | } 43 | 44 | private void on_work_ready (void *ignored) { 45 | var job = queue.pop (); 46 | job.execute (); 47 | } 48 | 49 | public void enqueue (Worker job) { 50 | queue.push(job); 51 | try { 52 | thread_pool.add(job); 53 | } catch (ThreadError e) { 54 | error(e.message); 55 | } 56 | } 57 | 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /src/worker/image-loader.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * image-loader.vala 3 | * This file is part of news 4 | * 5 | * Copyright (C) 2017 - Günther Wutz 6 | * 7 | * news is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * news is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with news. If not, see . 19 | */ 20 | 21 | namespace News.Background { 22 | public class ImageLoader : Lumber.Worker { 23 | private News.UI.ArticleBox widget; 24 | 25 | public ImageLoader (News.UI.ArticleBox widget) { 26 | this.widget = widget; 27 | } 28 | 29 | public override Gdk.Pixbuf? do_in_background () { 30 | try { 31 | return new Gdk.Pixbuf.from_file (widget.post.thumbnail); 32 | } catch (Error e) { 33 | error (e.message); 34 | return null; 35 | } 36 | } 37 | 38 | public override void on_post_execute (Gdk.Pixbuf? result) { 39 | if (result != null) 40 | widget.img.set_from_pixbuf (result); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/worker/worker.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * worker.vala 3 | * This file is part of news 4 | * 5 | * Copyright (C) 2017 - Günther Wutz 6 | * 7 | * news is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * news is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with news. If not, see . 19 | */ 20 | 21 | /* 22 | * This code is generic and should be stripped out of news for a good library to handle 23 | * long running operations in a similiar way java handles long running operations in android 24 | * code. If we want to let a thread operate on long running operations, we subclass worker 25 | * and implement 26 | */ 27 | namespace Lumber { 28 | 29 | public abstract class Worker : Object { 30 | 31 | public abstract A do_in_background (); 32 | public abstract void on_post_execute (A result); 33 | 34 | internal void execute () { 35 | A result = do_in_background (); 36 | 37 | Idle.add (() => { 38 | on_post_execute (result); 39 | return false; 40 | }); 41 | } 42 | } 43 | 44 | } 45 | --------------------------------------------------------------------------------