1/***************************************************************************** 2 * prefs_widgets.m: Preferences controls 3 ***************************************************************************** 4 * Copyright (C) 2002-2012 VLC authors and VideoLAN 5 * $Id: 3c31ecd5ff72eaadb7b9f5a51427a0dede5d2e3b $ 6 * 7 * Authors: Derk-Jan Hartman <hartman at videolan.org> 8 * Jérôme Decoodt <djc at videolan.org> 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; either version 2 of the License, or 13 * (at your option) any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program; if not, write to the Free Software 22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. 23 *****************************************************************************/ 24 25/***************************************************************************** 26 * Preamble 27 *****************************************************************************/ 28#include <stdlib.h> /* malloc(), free() */ 29#include <string.h> 30 31#ifdef HAVE_CONFIG_H 32# include "config.h" 33#endif 34 35#include <vlc_common.h> 36#include <vlc_modules.h> 37#include <vlc_plugin.h> 38#include <vlc_actions.h> 39 40#include "VLCMain.h" 41#include "prefs_widgets.h" 42 43#define CONFIG_ITEM_STRING_LIST (CONFIG_ITEM_STRING + 10) 44#define CONFIG_ITEM_RANGED_INTEGER (CONFIG_ITEM_INTEGER + 10) 45 46#define LEFTMARGIN 18 47#define RIGHTMARGIN 18 48#define PREFS_WRAP 300 49#define OFFSET_RIGHT 20 50#define OFFSET_BETWEEN 2 51 52#define UPWARDS_WHITE_ARROW "\xE2\x87\xA7" 53#define OPTION_KEY "\xE2\x8C\xA5" 54#define UP_ARROWHEAD "\xE2\x8C\x83" 55#define PLACE_OF_INTEREST_SIGN "\xE2\x8C\x98" 56 57#define POPULATE_A_KEY(o_menu, string, value) \ 58{ \ 59 NSMenuItem *o_mi; \ 60/* Normal */ \ 61 o_mi = [[NSMenuItem alloc] initWithTitle:string \ 62 action:nil keyEquivalent:@""]; \ 63 [o_mi setKeyEquivalentModifierMask: \ 64 0]; \ 65 [o_mi setAlternate: NO]; \ 66 [o_mi setTag: \ 67 (value)]; \ 68 [o_menu addItem: o_mi]; \ 69/* Ctrl */ \ 70 o_mi = [[NSMenuItem alloc] initWithTitle: \ 71 [toNSStr(UP_ARROWHEAD) \ 72 stringByAppendingString: string] \ 73 action:nil keyEquivalent:@""]; \ 74 [o_mi setKeyEquivalentModifierMask: \ 75 NSControlKeyMask]; \ 76 [o_mi setAlternate: YES]; \ 77 [o_mi setTag: \ 78 KEY_MODIFIER_CTRL | (value)]; \ 79 [o_menu addItem: o_mi]; \ 80/* Ctrl+Alt */ \ 81 o_mi = [[NSMenuItem alloc] initWithTitle: \ 82 [toNSStr(UP_ARROWHEAD OPTION_KEY) \ 83 stringByAppendingString: string] \ 84 action:nil keyEquivalent:@""]; \ 85 [o_mi setKeyEquivalentModifierMask: \ 86 NSControlKeyMask | NSAlternateKeyMask]; \ 87 [o_mi setAlternate: YES]; \ 88 [o_mi setTag: \ 89 (KEY_MODIFIER_CTRL | KEY_MODIFIER_ALT) | (value)]; \ 90 [o_menu addItem: o_mi]; \ 91/* Ctrl+Shift */ \ 92 o_mi = [[NSMenuItem alloc] initWithTitle: \ 93 [toNSStr(UP_ARROWHEAD UPWARDS_WHITE_ARROW) \ 94 stringByAppendingString: string] \ 95 action:nil keyEquivalent:@""]; \ 96 [o_mi setKeyEquivalentModifierMask: \ 97 NSControlKeyMask | NSShiftKeyMask]; \ 98 [o_mi setAlternate: YES]; \ 99 [o_mi setTag: \ 100 (KEY_MODIFIER_CTRL | KEY_MODIFIER_SHIFT) | (value)]; \ 101 [o_menu addItem: o_mi]; \ 102/* Ctrl+Apple */ \ 103 o_mi = [[NSMenuItem alloc] initWithTitle: \ 104 [toNSStr(UP_ARROWHEAD PLACE_OF_INTEREST_SIGN) \ 105 stringByAppendingString: string] \ 106 action:nil keyEquivalent:@""]; \ 107 [o_mi setKeyEquivalentModifierMask: \ 108 NSControlKeyMask | NSCommandKeyMask]; \ 109 [o_mi setAlternate: YES]; \ 110 [o_mi setTag: \ 111 (KEY_MODIFIER_CTRL | KEY_MODIFIER_COMMAND) | (value)]; \ 112 [o_menu addItem: o_mi]; \ 113/* Ctrl+Alt+Shift */ \ 114 o_mi = [[NSMenuItem alloc] initWithTitle: \ 115 [toNSStr(UP_ARROWHEAD OPTION_KEY UPWARDS_WHITE_ARROW) \ 116 stringByAppendingString: string] \ 117 action:nil keyEquivalent:@""]; \ 118 [o_mi setKeyEquivalentModifierMask: \ 119 NSControlKeyMask | NSAlternateKeyMask | NSShiftKeyMask]; \ 120 [o_mi setAlternate: YES]; \ 121 [o_mi setTag: \ 122 (KEY_MODIFIER_CTRL | KEY_MODIFIER_ALT | KEY_MODIFIER_SHIFT) | \ 123 (value)]; \ 124 [o_menu addItem: o_mi]; \ 125/* Ctrl+Alt+Apple */ \ 126 o_mi = [[NSMenuItem alloc] initWithTitle: \ 127 [toNSStr(UP_ARROWHEAD OPTION_KEY PLACE_OF_INTEREST_SIGN) \ 128 stringByAppendingString: string] \ 129 action:nil keyEquivalent:@""]; \ 130 [o_mi setKeyEquivalentModifierMask: \ 131 NSControlKeyMask | NSAlternateKeyMask | NSCommandKeyMask]; \ 132 [o_mi setAlternate: YES]; \ 133 [o_mi setTag: \ 134 (KEY_MODIFIER_CTRL | KEY_MODIFIER_ALT | KEY_MODIFIER_COMMAND) | \ 135 (value)]; \ 136 [o_menu addItem: o_mi]; \ 137/* Ctrl+Shift+Apple */ \ 138 o_mi = [[NSMenuItem alloc] initWithTitle: \ 139 [toNSStr(UP_ARROWHEAD UPWARDS_WHITE_ARROW PLACE_OF_INTEREST_SIGN) \ 140 stringByAppendingString: string] \ 141 action:nil keyEquivalent:@""]; \ 142 [o_mi setKeyEquivalentModifierMask: \ 143 NSControlKeyMask | NSShiftKeyMask | NSCommandKeyMask]; \ 144 [o_mi setAlternate: YES]; \ 145 [o_mi setTag: \ 146 (KEY_MODIFIER_CTRL | KEY_MODIFIER_SHIFT | KEY_MODIFIER_COMMAND) | \ 147 (value)]; \ 148 [o_menu addItem: o_mi]; \ 149/* Ctrl+Alt+Shift+Apple */ \ 150 o_mi = [[NSMenuItem alloc] initWithTitle: \ 151 [toNSStr(UP_ARROWHEAD OPTION_KEY UPWARDS_WHITE_ARROW PLACE_OF_INTEREST_SIGN) \ 152 stringByAppendingString: string] \ 153 action:nil keyEquivalent:@""]; \ 154 [o_mi setKeyEquivalentModifierMask: \ 155 NSControlKeyMask | NSAlternateKeyMask | NSShiftKeyMask | \ 156 NSCommandKeyMask]; \ 157 [o_mi setAlternate: YES]; \ 158 [o_mi setTag: \ 159 (KEY_MODIFIER_CTRL | KEY_MODIFIER_ALT | KEY_MODIFIER_SHIFT | \ 160 KEY_MODIFIER_COMMAND) | (value)]; \ 161 [o_menu addItem: o_mi]; \ 162/* Alt */ \ 163 o_mi = [[NSMenuItem alloc] initWithTitle: \ 164 [toNSStr(OPTION_KEY) stringByAppendingString: string] \ 165 action:nil keyEquivalent:@""]; \ 166 [o_mi setKeyEquivalentModifierMask: \ 167 NSAlternateKeyMask]; \ 168 [o_mi setAlternate: YES]; \ 169 [o_mi setTag: \ 170 KEY_MODIFIER_ALT | (value)]; \ 171 [o_menu addItem: o_mi]; \ 172/* Alt+Shift */ \ 173 o_mi = [[NSMenuItem alloc] initWithTitle: \ 174 [toNSStr(OPTION_KEY UPWARDS_WHITE_ARROW) stringByAppendingString: string] \ 175 action:nil keyEquivalent:@""]; \ 176 [o_mi setKeyEquivalentModifierMask: \ 177 NSAlternateKeyMask | NSShiftKeyMask]; \ 178 [o_mi setAlternate: YES]; \ 179 [o_mi setTag: \ 180 (KEY_MODIFIER_ALT | KEY_MODIFIER_SHIFT) | (value)]; \ 181 [o_menu addItem: o_mi]; \ 182/* Alt+Apple */ \ 183 o_mi = [[NSMenuItem alloc] initWithTitle: \ 184 [toNSStr(OPTION_KEY PLACE_OF_INTEREST_SIGN) \ 185 stringByAppendingString: string] action:nil keyEquivalent:@""]; \ 186 [o_mi setKeyEquivalentModifierMask: \ 187 NSAlternateKeyMask | NSCommandKeyMask]; \ 188 [o_mi setAlternate: YES]; \ 189 [o_mi setTag: \ 190 (KEY_MODIFIER_ALT | KEY_MODIFIER_COMMAND) | (value)]; \ 191 [o_menu addItem: o_mi]; \ 192/* Alt+Shift+Apple */ \ 193 o_mi = [[NSMenuItem alloc] initWithTitle: \ 194 [toNSStr(OPTION_KEY UPWARDS_WHITE_ARROW PLACE_OF_INTEREST_SIGN) \ 195 stringByAppendingString: string] \ 196 action:nil keyEquivalent:@""]; \ 197 [o_mi setKeyEquivalentModifierMask: \ 198 NSAlternateKeyMask | NSShiftKeyMask | NSCommandKeyMask]; \ 199 [o_mi setAlternate: YES]; \ 200 [o_mi setTag: \ 201 (KEY_MODIFIER_ALT | KEY_MODIFIER_SHIFT | KEY_MODIFIER_COMMAND) | \ 202 (value)]; \ 203 [o_menu addItem: o_mi]; \ 204/* Shift */ \ 205 o_mi = [[NSMenuItem alloc] initWithTitle: \ 206 [toNSStr(UPWARDS_WHITE_ARROW) \ 207 stringByAppendingString: string] \ 208 action:nil keyEquivalent:@""]; \ 209 [o_mi setKeyEquivalentModifierMask: \ 210 NSShiftKeyMask]; \ 211 [o_mi setAlternate: YES]; \ 212 [o_mi setTag: \ 213 KEY_MODIFIER_SHIFT | (value)]; \ 214 [o_menu addItem: o_mi]; \ 215/* Shift+Apple */ \ 216 o_mi = [[NSMenuItem alloc] initWithTitle: \ 217 [toNSStr(UPWARDS_WHITE_ARROW PLACE_OF_INTEREST_SIGN) \ 218 stringByAppendingString: string] \ 219 action:nil keyEquivalent:@""]; \ 220 [o_mi setKeyEquivalentModifierMask: \ 221 NSShiftKeyMask | NSCommandKeyMask]; \ 222 [o_mi setAlternate: YES]; \ 223 [o_mi setTag: \ 224 (KEY_MODIFIER_SHIFT | KEY_MODIFIER_COMMAND) | (value)]; \ 225 [o_menu addItem: o_mi]; \ 226/* Apple */ \ 227 o_mi = [[NSMenuItem alloc] initWithTitle: \ 228 [toNSStr(PLACE_OF_INTEREST_SIGN) \ 229 stringByAppendingString: string] \ 230 action:nil keyEquivalent:@""]; \ 231 [o_mi setKeyEquivalentModifierMask: \ 232 NSCommandKeyMask]; \ 233 [o_mi setAlternate: YES]; \ 234 [o_mi setTag: \ 235 KEY_MODIFIER_COMMAND | (value)]; \ 236 [o_menu addItem: o_mi]; \ 237} 238 239#define ADD_LABEL(o_label, superFrame, x_offset, my_y_offset, label, \ 240 tooltip) \ 241{ \ 242 NSRect s_rc = superFrame; \ 243 s_rc.size.height = 17; \ 244 s_rc.origin.x = x_offset - 3; \ 245 s_rc.origin.y = superFrame.size.height - 17 + my_y_offset; \ 246 o_label = [[NSTextField alloc] initWithFrame: s_rc]; \ 247 [o_label setDrawsBackground: NO]; \ 248 [o_label setBordered: NO]; \ 249 [o_label setEditable: NO]; \ 250 [o_label setSelectable: NO]; \ 251 [o_label setStringValue: label]; \ 252 [o_label setToolTip: tooltip]; \ 253 [o_label setFont:[NSFont systemFontOfSize:0]]; \ 254 [o_label sizeToFit]; \ 255} 256 257#define ADD_TEXTFIELD(o_textfield, superFrame, x_offset, my_y_offset, \ 258 my_width, tooltip, init_value) \ 259{ \ 260 NSRect s_rc = superFrame; \ 261 s_rc.origin.x = x_offset; \ 262 s_rc.origin.y = my_y_offset; \ 263 s_rc.size.height = 22; \ 264 s_rc.size.width = my_width; \ 265 o_textfield = [[NSTextField alloc] initWithFrame: s_rc]; \ 266 [o_textfield setFont:[NSFont systemFontOfSize:0]]; \ 267 [o_textfield setToolTip: tooltip]; \ 268 [o_textfield setStringValue: init_value]; \ 269} 270 271#define ADD_SECURETEXTFIELD(o_textfield, superFrame, x_offset, my_y_offset, \ 272my_width, tooltip, init_value) \ 273{ \ 274NSRect s_rc = superFrame; \ 275s_rc.origin.x = x_offset; \ 276s_rc.origin.y = my_y_offset; \ 277s_rc.size.height = 22; \ 278s_rc.size.width = my_width; \ 279o_textfield = [[NSSecureTextField alloc] initWithFrame: s_rc]; \ 280[o_textfield setFont:[NSFont systemFontOfSize:0]]; \ 281[o_textfield setToolTip: tooltip]; \ 282[o_textfield setStringValue: init_value]; \ 283} 284 285#define ADD_COMBO(o_combo, superFrame, x_offset, my_y_offset, x2_offset, \ 286 tooltip) \ 287{ \ 288 NSRect s_rc = superFrame; \ 289 s_rc.origin.x = x_offset + 2; \ 290 s_rc.origin.y = my_y_offset; \ 291 s_rc.size.height = 26; \ 292 s_rc.size.width = superFrame.size.width + 2 - s_rc.origin.x - \ 293 (x2_offset); \ 294 o_combo = [[NSComboBox alloc] initWithFrame: s_rc]; \ 295 [o_combo setFont:[NSFont systemFontOfSize:0]]; \ 296 [o_combo setToolTip: tooltip]; \ 297 [o_combo setUsesDataSource:TRUE]; \ 298 [o_combo setDataSource:self]; \ 299 [o_combo setNumberOfVisibleItems:10]; \ 300 [o_combo setCompletes:YES]; \ 301} 302 303#define ADD_RIGHT_BUTTON(o_button, superFrame, x_offset, my_y_offset, \ 304 tooltip, title) \ 305{ \ 306 NSRect s_rc = superFrame; \ 307 o_button = [[NSButton alloc] initWithFrame: s_rc]; \ 308 [o_button setButtonType: NSMomentaryPushInButton]; \ 309 [o_button setBezelStyle: NSRoundedBezelStyle]; \ 310 [o_button setTitle: title]; \ 311 [o_button setFont:[NSFont systemFontOfSize:0]]; \ 312 [o_button sizeToFit]; \ 313 s_rc = [o_button frame]; \ 314 s_rc.origin.x = superFrame.size.width - [o_button frame].size.width - 6;\ 315 s_rc.origin.y = my_y_offset - 6; \ 316 s_rc.size.width += 12; \ 317 [o_button setFrame: s_rc]; \ 318 [o_button setToolTip: tooltip]; \ 319 [o_button setTarget: self]; \ 320 [o_button setAction: @selector(openFileDialog:)]; \ 321} 322 323#define ADD_POPUP(o_popup, superFrame, x_offset, my_y_offset, x2_offset, \ 324 tooltip) \ 325{ \ 326 NSRect s_rc = superFrame; \ 327 s_rc.origin.x = x_offset - 1; \ 328 s_rc.origin.y = my_y_offset; \ 329 s_rc.size.height = 26; \ 330 s_rc.size.width = superFrame.size.width + 2 - s_rc.origin.x - \ 331 (x2_offset); \ 332 o_popup = [[NSPopUpButton alloc] initWithFrame: s_rc]; \ 333 [o_popup setFont:[NSFont systemFontOfSize:0]]; \ 334 [o_popup setToolTip: tooltip]; \ 335} 336 337#define ADD_STEPPER(o_stepper, superFrame, x_offset, my_y_offset, tooltip, \ 338 lower, higher) \ 339{ \ 340 NSRect s_rc = superFrame; \ 341 s_rc.origin.x = x_offset; \ 342 s_rc.origin.y = my_y_offset; \ 343 s_rc.size.height = 23; \ 344 s_rc.size.width = 23; \ 345 o_stepper = [[NSStepper alloc] initWithFrame: s_rc]; \ 346 [o_stepper setFont:[NSFont systemFontOfSize:0]]; \ 347 [o_stepper setToolTip: tooltip]; \ 348 [o_stepper setMaxValue: higher]; \ 349 [o_stepper setMinValue: lower]; \ 350 [o_stepper setTarget: self]; \ 351 [o_stepper setAction: @selector(stepperChanged:)]; \ 352 [o_stepper sendActionOn:NSLeftMouseUpMask | NSLeftMouseDownMask | \ 353 NSLeftMouseDraggedMask]; \ 354} 355 356#define ADD_SLIDER(o_slider, superFrame, x_offset, my_y_offset, my_width, \ 357 tooltip, lower, higher) \ 358{ \ 359 NSRect s_rc = superFrame; \ 360 s_rc.origin.x = x_offset; \ 361 s_rc.origin.y = my_y_offset; \ 362 s_rc.size.height = 21; \ 363 s_rc.size.width = my_width; \ 364 o_slider = [[NSSlider alloc] initWithFrame: s_rc]; \ 365 [o_slider setFont:[NSFont systemFontOfSize:0]]; \ 366 [o_slider setToolTip: tooltip]; \ 367 [o_slider setMaxValue: higher]; \ 368 [o_slider setMinValue: lower]; \ 369} 370 371#define ADD_CHECKBOX(o_checkbox, superFrame, x_offset, my_y_offset, label, \ 372 tooltip, init_value, position) \ 373{ \ 374 NSRect s_rc = superFrame; \ 375 s_rc.size.height = 18; \ 376 s_rc.origin.x = x_offset - 2; \ 377 s_rc.origin.y = superFrame.size.height - 18 + my_y_offset; \ 378 o_checkbox = [[NSButton alloc] initWithFrame: s_rc]; \ 379 [o_checkbox setFont:[NSFont systemFontOfSize:0]]; \ 380 [o_checkbox setButtonType: NSSwitchButton]; \ 381 [o_checkbox setImagePosition: position]; \ 382 [o_checkbox setIntValue: init_value]; \ 383 [o_checkbox setTitle: label]; \ 384 [o_checkbox setToolTip: tooltip]; \ 385 [o_checkbox sizeToFit]; \ 386} 387 388@interface VLCConfigControl() 389{ 390 const char *psz_name; 391} 392@end 393 394@implementation VLCConfigControl 395 396- (id)initWithFrame:(NSRect)frame 397{ 398 return [self initWithFrame: frame 399 item: nil]; 400} 401 402- (id)initWithFrame:(NSRect)frame 403 item:(module_config_t *)p_item 404{ 405 self = [super initWithFrame: frame]; 406 407 if (self != nil) { 408 _p_item = p_item; 409 if (p_item) { 410 psz_name = p_item->psz_name; 411 _type = p_item->i_type; 412 _advanced = p_item->b_advanced; 413 } else { 414 psz_name = NULL; 415 } 416 [self setAutoresizingMask:NSViewWidthSizable | NSViewMinYMargin ]; 417 } 418 return (self); 419} 420 421- (void)setYPos:(int)i_yPos 422{ 423 NSRect frame = [self frame]; 424 frame.origin.y = i_yPos; 425 [self setFrame:frame]; 426} 427 428+ (int)calcVerticalMargin:(int)i_curItem lastItem:(int)i_lastItem 429{ 430 int i_margin; 431 switch(i_curItem) { 432 case CONFIG_ITEM_STRING: 433 case CONFIG_ITEM_PASSWORD: 434 switch(i_lastItem) { 435 case CONFIG_ITEM_STRING: 436 case CONFIG_ITEM_PASSWORD: 437 i_margin = 8; 438 break; 439 case CONFIG_ITEM_STRING_LIST: 440 i_margin = 7; 441 break; 442 case CONFIG_ITEM_LOADFILE: 443 case CONFIG_ITEM_SAVEFILE: 444 i_margin = 8; 445 break; 446 case CONFIG_ITEM_MODULE: 447 i_margin = 4; 448 break; 449 case CONFIG_ITEM_INTEGER: 450 i_margin = 7; 451 break; 452 case CONFIG_ITEM_RANGED_INTEGER: 453 i_margin = 5; 454 break; 455 case CONFIG_ITEM_BOOL: 456 i_margin = 7; 457 break; 458 case CONFIG_ITEM_KEY: 459 i_margin = 6; 460 break; 461 case CONFIG_ITEM_MODULE_LIST: 462 i_margin = 8; 463 break; 464 default: 465 i_margin = 20; 466 break; 467 } 468 break; 469 case CONFIG_ITEM_STRING_LIST: 470 switch(i_lastItem) { 471 case CONFIG_ITEM_STRING: 472 case CONFIG_ITEM_PASSWORD: 473 i_margin = 8; 474 break; 475 case CONFIG_ITEM_STRING_LIST: 476 i_margin = 7; 477 break; 478 case CONFIG_ITEM_LOADFILE: 479 case CONFIG_ITEM_SAVEFILE: 480 i_margin = 6; 481 break; 482 case CONFIG_ITEM_MODULE: 483 i_margin = 4; 484 break; 485 case CONFIG_ITEM_INTEGER: 486 i_margin = 7; 487 break; 488 case CONFIG_ITEM_RANGED_INTEGER: 489 i_margin = 5; 490 break; 491 case CONFIG_ITEM_BOOL: 492 i_margin = 7; 493 break; 494 case CONFIG_ITEM_KEY: 495 i_margin = 6; 496 break; 497 case CONFIG_ITEM_MODULE_LIST: 498 i_margin = 8; 499 break; 500 default: 501 i_margin = 20; 502 break; 503 } 504 break; 505 case CONFIG_ITEM_LOADFILE: 506 case CONFIG_ITEM_SAVEFILE: 507 switch(i_lastItem) { 508 case CONFIG_ITEM_STRING: 509 case CONFIG_ITEM_PASSWORD: 510 i_margin = 13; 511 break; 512 case CONFIG_ITEM_STRING_LIST: 513 i_margin = 10; 514 break; 515 case CONFIG_ITEM_LOADFILE: 516 case CONFIG_ITEM_SAVEFILE: 517 i_margin = 9; 518 break; 519 case CONFIG_ITEM_MODULE: 520 i_margin = 9; 521 break; 522 case CONFIG_ITEM_INTEGER: 523 i_margin = 10; 524 break; 525 case CONFIG_ITEM_RANGED_INTEGER: 526 i_margin = 8; 527 break; 528 case CONFIG_ITEM_BOOL: 529 i_margin = 10; 530 break; 531 case CONFIG_ITEM_KEY: 532 i_margin = 9; 533 break; 534 case CONFIG_ITEM_MODULE_LIST: 535 i_margin = 11; 536 break; 537 default: 538 i_margin = 23; 539 break; 540 } 541 break; 542 case CONFIG_ITEM_MODULE: 543 switch(i_lastItem) { 544 case CONFIG_ITEM_STRING: 545 case CONFIG_ITEM_PASSWORD: 546 i_margin = 8; 547 break; 548 case CONFIG_ITEM_STRING_LIST: 549 i_margin = 7; 550 break; 551 case CONFIG_ITEM_LOADFILE: 552 case CONFIG_ITEM_SAVEFILE: 553 i_margin = 6; 554 break; 555 case CONFIG_ITEM_MODULE: 556 i_margin = 5; 557 break; 558 case CONFIG_ITEM_INTEGER: 559 i_margin = 7; 560 break; 561 case CONFIG_ITEM_RANGED_INTEGER: 562 i_margin = 6; 563 break; 564 case CONFIG_ITEM_BOOL: 565 i_margin = 8; 566 break; 567 case CONFIG_ITEM_KEY: 568 i_margin = 7; 569 break; 570 case CONFIG_ITEM_MODULE_LIST: 571 i_margin = 9; 572 break; 573 default: 574 i_margin = 20; 575 break; 576 } 577 break; 578 case CONFIG_ITEM_INTEGER: 579 switch(i_lastItem) { 580 case CONFIG_ITEM_STRING: 581 case CONFIG_ITEM_PASSWORD: 582 i_margin = 8; 583 break; 584 case CONFIG_ITEM_STRING_LIST: 585 i_margin = 7; 586 break; 587 case CONFIG_ITEM_LOADFILE: 588 case CONFIG_ITEM_SAVEFILE: 589 i_margin = 6; 590 break; 591 case CONFIG_ITEM_MODULE: 592 i_margin = 4; 593 break; 594 case CONFIG_ITEM_INTEGER: 595 i_margin = 7; 596 break; 597 case CONFIG_ITEM_RANGED_INTEGER: 598 i_margin = 5; 599 break; 600 case CONFIG_ITEM_BOOL: 601 i_margin = 7; 602 break; 603 case CONFIG_ITEM_KEY: 604 i_margin = 6; 605 break; 606 case CONFIG_ITEM_MODULE_LIST: 607 i_margin = 8; 608 break; 609 default: 610 i_margin = 20; 611 break; 612 } 613 break; 614 case CONFIG_ITEM_RANGED_INTEGER: 615 switch(i_lastItem) { 616 case CONFIG_ITEM_STRING: 617 case CONFIG_ITEM_PASSWORD: 618 i_margin = 8; 619 break; 620 case CONFIG_ITEM_STRING_LIST: 621 i_margin = 7; 622 break; 623 case CONFIG_ITEM_LOADFILE: 624 case CONFIG_ITEM_SAVEFILE: 625 i_margin = 8; 626 break; 627 case CONFIG_ITEM_MODULE: 628 i_margin = 4; 629 break; 630 case CONFIG_ITEM_INTEGER: 631 i_margin = 7; 632 break; 633 case CONFIG_ITEM_RANGED_INTEGER: 634 i_margin = 5; 635 break; 636 case CONFIG_ITEM_BOOL: 637 i_margin = 7; 638 break; 639 case CONFIG_ITEM_KEY: 640 i_margin = 6; 641 break; 642 case CONFIG_ITEM_MODULE_LIST: 643 i_margin = 8; 644 break; 645 default: 646 i_margin = 20; 647 break; 648 } 649 break; 650 case CONFIG_ITEM_BOOL: 651 switch(i_lastItem) { 652 case CONFIG_ITEM_STRING: 653 case CONFIG_ITEM_PASSWORD: 654 i_margin = 10; 655 break; 656 case CONFIG_ITEM_STRING_LIST: 657 i_margin = 9; 658 break; 659 case CONFIG_ITEM_LOADFILE: 660 case CONFIG_ITEM_SAVEFILE: 661 i_margin = 8; 662 break; 663 case CONFIG_ITEM_MODULE: 664 i_margin = 6; 665 break; 666 case CONFIG_ITEM_INTEGER: 667 i_margin = 9; 668 break; 669 case CONFIG_ITEM_RANGED_INTEGER: 670 i_margin = 7; 671 break; 672 case CONFIG_ITEM_BOOL: 673 i_margin = 7; 674 break; 675 case CONFIG_ITEM_KEY: 676 i_margin = 5; 677 break; 678 case CONFIG_ITEM_MODULE_LIST: 679 i_margin = 10; 680 break; 681 default: 682 i_margin = 20; 683 break; 684 } 685 break; 686 case CONFIG_ITEM_KEY: 687 switch(i_lastItem) { 688 case CONFIG_ITEM_STRING: 689 case CONFIG_ITEM_PASSWORD: 690 i_margin = 8; 691 break; 692 case CONFIG_ITEM_STRING_LIST: 693 i_margin = 7; 694 break; 695 case CONFIG_ITEM_LOADFILE: 696 case CONFIG_ITEM_SAVEFILE: 697 i_margin = 6; 698 break; 699 case CONFIG_ITEM_MODULE: 700 i_margin = 6; 701 break; 702 case CONFIG_ITEM_INTEGER: 703 i_margin = 7; 704 break; 705 case CONFIG_ITEM_RANGED_INTEGER: 706 i_margin = 5; 707 break; 708 case CONFIG_ITEM_BOOL: 709 i_margin = 7; 710 break; 711 case CONFIG_ITEM_KEY: 712 i_margin = 8; 713 break; 714 case CONFIG_ITEM_MODULE_LIST: 715 i_margin = 10; 716 break; 717 default: 718 i_margin = 20; 719 break; 720 } 721 break; 722 case CONFIG_ITEM_MODULE_LIST: 723 switch(i_lastItem) { 724 case CONFIG_ITEM_STRING: 725 case CONFIG_ITEM_PASSWORD: 726 i_margin = 10; 727 break; 728 case CONFIG_ITEM_STRING_LIST: 729 i_margin = 7; 730 break; 731 case CONFIG_ITEM_LOADFILE: 732 case CONFIG_ITEM_SAVEFILE: 733 i_margin = 6; 734 break; 735 case CONFIG_ITEM_MODULE: 736 i_margin = 6; 737 break; 738 case CONFIG_ITEM_INTEGER: 739 i_margin = 9; 740 break; 741 case CONFIG_ITEM_RANGED_INTEGER: 742 i_margin = 5; 743 break; 744 case CONFIG_ITEM_BOOL: 745 i_margin = 7; 746 break; 747 case CONFIG_ITEM_KEY: 748 i_margin = 5; 749 break; 750 case CONFIG_ITEM_MODULE_LIST: 751 i_margin = 8; 752 break; 753 default: 754 i_margin = 20; 755 break; 756 } 757 break; 758 default: 759 i_margin = 20; 760 break; 761 } 762 return i_margin; 763} 764 765+ (VLCConfigControl *)newControl:(module_config_t *)_p_item 766 withView:(NSView *)parentView 767{ 768 VLCConfigControl *control = NULL; 769 770 switch(_p_item->i_type) { 771 case CONFIG_ITEM_STRING: 772 case CONFIG_ITEM_PASSWORD: 773 if (!_p_item->list_count) { 774 control = [[StringConfigControl alloc] 775 initWithItem: _p_item 776 withView: parentView]; 777 } else { 778 control = [[StringListConfigControl alloc] 779 initWithItem: _p_item 780 withView: parentView]; 781 } 782 break; 783 case CONFIG_ITEM_LOADFILE: 784 case CONFIG_ITEM_SAVEFILE: 785 case CONFIG_ITEM_DIRECTORY: 786 control = [[FileConfigControl alloc] 787 initWithItem: _p_item 788 withView: parentView]; 789 break; 790 case CONFIG_ITEM_MODULE: 791 control = [[StringListConfigControl alloc] 792 initWithItem: _p_item 793 withView: parentView]; 794 break; 795 case CONFIG_ITEM_MODULE_CAT: 796 control = [[ModuleConfigControl alloc] 797 initWithItem: _p_item 798 withView: parentView]; 799 break; 800 case CONFIG_ITEM_INTEGER: 801 if (_p_item->list_count) 802 control = [[IntegerListConfigControl alloc] initWithItem: _p_item withView: parentView]; 803 else if (_p_item->min.i > INT32_MIN && _p_item->max.i < INT32_MAX) 804 control = [[RangedIntegerConfigControl alloc] initWithItem: _p_item withView: parentView]; 805 else 806 control = [[IntegerConfigControl alloc] initWithItem: _p_item withView: parentView]; 807 break; 808 case CONFIG_ITEM_BOOL: 809 control = [[BoolConfigControl alloc] initWithItem: _p_item 810 withView: parentView]; 811 break; 812 case CONFIG_ITEM_FLOAT: 813 if (_p_item->min.f > -FLT_MAX && _p_item->max.f < FLT_MAX) 814 control = [[RangedFloatConfigControl alloc] initWithItem: _p_item withView: parentView]; 815 else 816 control = [[FloatConfigControl alloc] initWithItem: _p_item withView: parentView]; 817 break; 818 /* don't display keys in the advanced settings, since the current controls 819 are broken by design. The user is required to change hotkeys in the sprefs 820 and can only change really advanced stuff here.. 821 case CONFIG_ITEM_KEY: 822 control = [[KeyConfigControl alloc] 823 initWithItem: _p_item 824 withView: parentView]; 825 break; */ 826 case CONFIG_ITEM_MODULE_LIST: 827 case CONFIG_ITEM_MODULE_LIST_CAT: 828 control = [[ModuleListConfigControl alloc] initWithItem: _p_item withView: parentView]; 829 break; 830 case CONFIG_SECTION: 831 control = [[SectionControl alloc] initWithItem: _p_item withView: parentView]; 832 break; 833 default: 834 break; 835 } 836 837 return control; 838} 839 840- (NSString *)name 841{ 842 return _NS(psz_name); 843} 844 845- (int)intValue 846{ 847 return 0; 848} 849 850- (float)floatValue 851{ 852 return 0; 853} 854 855- (char *)stringValue 856{ 857 return NULL; 858} 859 860- (void)applyChanges 861{ 862 vlc_value_t val; 863 switch(self.p_item->i_type) { 864 case CONFIG_ITEM_STRING: 865 case CONFIG_ITEM_PASSWORD: 866 case CONFIG_ITEM_LOADFILE: 867 case CONFIG_ITEM_SAVEFILE: 868 case CONFIG_ITEM_DIRECTORY: 869 case CONFIG_ITEM_MODULE: 870 case CONFIG_ITEM_MODULE_LIST: 871 case CONFIG_ITEM_MODULE_LIST_CAT: { 872 char *psz_val = [self stringValue]; 873 config_PutPsz(getIntf(), psz_name, psz_val); 874 free(psz_val); 875 break; 876 } 877 case CONFIG_ITEM_KEY: 878 /* So you don't need to restart to have the changes take effect */ 879 val.i_int = [self intValue]; 880 var_Set(getIntf()->obj.libvlc, psz_name, val); 881 case CONFIG_ITEM_INTEGER: 882 case CONFIG_ITEM_BOOL: 883 config_PutInt(getIntf(), psz_name, [self intValue]); 884 break; 885 case CONFIG_ITEM_FLOAT: 886 config_PutFloat(getIntf(), psz_name, [self floatValue]); 887 break; 888 } 889} 890 891- (void)resetValues 892{ 893} 894 895- (int)labelSize 896{ 897 return self.label.frame.size.width; 898} 899 900- (void) alignWithXPosition:(int)i_xPos; 901{ 902 /* FIXME: not implemented atm, but created to shut up the warning 903 * about "method definition not found" -- FK @ 7/24/05 */ 904} 905@end 906 907@interface StringConfigControl() 908{ 909 NSTextField *o_textfield; 910} 911@end 912 913@implementation StringConfigControl 914- (id)initWithItem:(module_config_t *)p_item 915 withView:(NSView *)parentView 916{ 917 NSRect mainFrame = [parentView frame]; 918 NSString *labelString, *o_textfieldString, *o_textfieldTooltip; 919 mainFrame.size.height = 22; 920 mainFrame.size.width = mainFrame.size.width - LEFTMARGIN - RIGHTMARGIN; 921 mainFrame.origin.x = LEFTMARGIN; 922 mainFrame.origin.y = 0; 923 924 if (self = [super initWithFrame:mainFrame item:p_item]) { 925 if (p_item->i_type == CONFIG_ITEM_PASSWORD) 926 self.viewType = CONFIG_ITEM_PASSWORD; 927 else 928 self.viewType = CONFIG_ITEM_STRING; 929 930 o_textfieldTooltip = [[VLCStringUtility sharedInstance] wrapString: _NS(p_item->psz_longtext) toWidth: PREFS_WRAP]; 931 932 /* add the label */ 933 labelString = _NS(p_item->psz_text); 934 ADD_LABEL(self.label, mainFrame, 0, -3, labelString, o_textfieldTooltip) 935 [self.label setAutoresizingMask:NSViewNotSizable ]; 936 [self addSubview: self.label]; 937 938 /* build the textfield */ 939 o_textfieldString = toNSStr(p_item->value.psz); 940 if (p_item->i_type == CONFIG_ITEM_PASSWORD) { 941 ADD_SECURETEXTFIELD(o_textfield, mainFrame, [self.label frame].size.width + 2, 942 0, mainFrame.size.width - [self.label frame].size.width - 943 2, o_textfieldTooltip, o_textfieldString) 944 } else { 945 ADD_TEXTFIELD(o_textfield, mainFrame, [self.label frame].size.width + 2, 946 0, mainFrame.size.width - [self.label frame].size.width - 947 2, o_textfieldTooltip, o_textfieldString) 948 } 949 [o_textfield setAutoresizingMask:NSViewWidthSizable ]; 950 951 [self addSubview: o_textfield]; 952 } 953 return self; 954} 955 956- (void) alignWithXPosition:(int)i_xPos 957{ 958 NSRect frame; 959 NSRect superFrame = [self frame]; 960 frame = [self.label frame]; 961 frame.origin.x = i_xPos - frame.size.width - 3; 962 [self.label setFrame:frame]; 963 964 frame = [o_textfield frame]; 965 frame.origin.x = i_xPos + 2; 966 frame.size.width = superFrame.size.width - frame.origin.x - 1; 967 [o_textfield setFrame:frame]; 968} 969 970- (char *)stringValue 971{ 972 return strdup([[o_textfield stringValue] UTF8String]); 973} 974 975- (void)resetValues 976{ 977 NSString *o_textfieldString; 978 char *psz_value = config_GetPsz(getIntf(), self.p_item->psz_name); 979 if (psz_value) 980 o_textfieldString = _NS(psz_value); 981 else 982 o_textfieldString = @""; 983 free(psz_value); 984 [super resetValues]; 985} 986@end 987 988@interface StringListConfigControl() 989{ 990 NSPopUpButton *o_popup; 991} 992@end 993 994@implementation StringListConfigControl 995- (id)initWithItem:(module_config_t *)p_item 996 withView:(NSView *)parentView 997{ 998 NSRect mainFrame = [parentView frame]; 999 NSString *labelString, *o_textfieldTooltip; 1000 mainFrame.size.height = 22; 1001 mainFrame.size.width = mainFrame.size.width - LEFTMARGIN - RIGHTMARGIN + 1; 1002 mainFrame.origin.x = LEFTMARGIN; 1003 mainFrame.origin.y = 0; 1004 1005 if (self = [super initWithFrame: mainFrame item:p_item]) { 1006 if (p_item->i_type == CONFIG_ITEM_STRING) 1007 self.viewType = CONFIG_ITEM_STRING_LIST; 1008 else 1009 self.viewType = CONFIG_ITEM_MODULE; 1010 1011 o_textfieldTooltip = [[VLCStringUtility sharedInstance] wrapString: _NS(p_item->psz_longtext) toWidth: PREFS_WRAP]; 1012 1013 /* add the label */ 1014 labelString = _NS(p_item->psz_text); 1015 ADD_LABEL(self.label, mainFrame, 0, -3, labelString, o_textfieldTooltip) 1016 [self.label setAutoresizingMask:NSViewNotSizable ]; 1017 [self addSubview: self.label]; 1018 1019 /* build the textfield */ 1020 ADD_POPUP(o_popup, mainFrame, [self.label frame].size.width, 1021 -2, 0, o_textfieldTooltip) 1022 [o_popup setAutoresizingMask:NSViewWidthSizable]; 1023 1024 /* add items */ 1025 [self resetValues]; 1026 1027 [self addSubview: o_popup]; 1028 } 1029 return self; 1030} 1031 1032- (void) alignWithXPosition:(int)i_xPos 1033{ 1034 NSRect frame; 1035 NSRect superFrame = [self frame]; 1036 frame = [self.label frame]; 1037 frame.origin.x = i_xPos - frame.size.width - 3; 1038 [self.label setFrame:frame]; 1039 1040 frame = [o_popup frame]; 1041 frame.origin.x = i_xPos + 2; 1042 frame.size.width = superFrame.size.width - frame.origin.x + 2; 1043 [o_popup setFrame:frame]; 1044} 1045 1046- (char *)stringValue 1047{ 1048 if ([o_popup indexOfSelectedItem] < 0) 1049 return NULL; 1050 1051 NSString *o_data = [[o_popup selectedItem] representedObject]; 1052 return strdup([o_data UTF8String]); 1053} 1054 1055- (void)resetValues 1056{ 1057 [o_popup removeAllItems]; 1058 1059 char *psz_value = config_GetPsz(getIntf(), self.p_item->psz_name); 1060 1061 char **values, **texts; 1062 ssize_t count = config_GetPszChoices(VLC_OBJECT(getIntf()), self.p_item->psz_name, 1063 &values, &texts); 1064 for (ssize_t i = 0; i < count && texts; i++) { 1065 if (texts[i] == NULL || values[i] == NULL) 1066 continue; 1067 1068 [o_popup addItemWithTitle: toNSStr(texts[i])]; 1069 NSMenuItem *lastItem = [o_popup lastItem]; 1070 [lastItem setRepresentedObject: toNSStr(values[i])]; 1071 1072 if (!strcmp(psz_value ? psz_value : "", values[i])) 1073 [o_popup selectItem: [o_popup lastItem]]; 1074 1075 free(texts[i]); 1076 free(values[i]); 1077 } 1078 free(texts); 1079 free(values); 1080 1081 free(psz_value); 1082 1083 [super resetValues]; 1084} 1085@end 1086 1087@interface FileConfigControl() 1088{ 1089 NSTextField *o_textfield; 1090 NSButton *o_button; 1091 BOOL b_directory; 1092} 1093@end 1094 1095@implementation FileConfigControl 1096- (id)initWithItem:(module_config_t *)p_item 1097 withView:(NSView *)parentView 1098{ 1099 NSRect mainFrame = [parentView frame]; 1100 NSString *labelString, *o_itemTooltip, *o_textfieldString; 1101 mainFrame.size.height = 46; 1102 mainFrame.size.width = mainFrame.size.width - LEFTMARGIN - RIGHTMARGIN; 1103 mainFrame.origin.x = LEFTMARGIN; 1104 mainFrame.origin.y = 0; 1105 1106 if (self = [super initWithFrame:mainFrame item:p_item]) { 1107 self.viewType = CONFIG_ITEM_LOADFILE; 1108 1109 o_itemTooltip = [[VLCStringUtility sharedInstance] wrapString: _NS(p_item->psz_longtext) toWidth: PREFS_WRAP]; 1110 1111 /* is it a directory */ 1112 b_directory = ([self type] == CONFIG_ITEM_DIRECTORY) ? YES : NO; 1113 1114 /* add the label */ 1115 labelString = _NS(p_item->psz_text); 1116 ADD_LABEL(self.label, mainFrame, 0, 3, labelString, o_itemTooltip) 1117 [self.label setAutoresizingMask:NSViewNotSizable ]; 1118 [self addSubview: self.label]; 1119 1120 /* build the button */ 1121 ADD_RIGHT_BUTTON(o_button, mainFrame, 0, 0, o_itemTooltip, 1122 _NS("Browse...")) 1123 [o_button setAutoresizingMask:NSViewMinXMargin ]; 1124 [self addSubview: o_button]; 1125 1126 /* build the textfield */ 1127 o_textfieldString = toNSStr(p_item->value.psz); 1128 ADD_TEXTFIELD(o_textfield, mainFrame, 12, 2, mainFrame.size.width - 1129 8 - [o_button frame].size.width, 1130 o_itemTooltip, o_textfieldString) 1131 [o_textfield setAutoresizingMask:NSViewWidthSizable ]; 1132 [self addSubview: o_textfield]; 1133 } 1134 return self; 1135} 1136 1137- (void) alignWithXPosition:(int)i_xPos 1138{ 1139 ; 1140} 1141 1142- (IBAction)openFileDialog:(id)sender 1143{ 1144 NSOpenPanel *o_open_panel = [NSOpenPanel openPanel]; 1145 1146 [o_open_panel setTitle:(b_directory)? 1147 _NS("Select a directory"):_NS("Select a file")]; 1148 [o_open_panel setPrompt: _NS("Select")]; 1149 [o_open_panel setAllowsMultipleSelection: NO]; 1150 [o_open_panel setCanChooseFiles: !b_directory]; 1151 [o_open_panel setCanChooseDirectories: b_directory]; 1152 [o_open_panel beginSheetModalForWindow:[sender window] completionHandler:^(NSInteger returnCode) { 1153 if (returnCode == NSOKButton) { 1154 NSString *o_path = [[[o_open_panel URLs] firstObject] path]; 1155 [o_textfield setStringValue: o_path]; 1156 } 1157 }]; 1158} 1159 1160- (char *)stringValue 1161{ 1162 if ([[o_textfield stringValue] length] != 0) 1163 return strdup([[o_textfield stringValue] fileSystemRepresentation]); 1164 else 1165 return NULL; 1166} 1167 1168-(void)resetValues 1169{ 1170 NSString *o_textfieldString; 1171 char *psz_value = config_GetPsz(getIntf(), self.p_item->psz_name); 1172 if (psz_value) 1173 o_textfieldString = [NSString stringWithFormat: @"%s", psz_value]; 1174 else 1175 o_textfieldString = @""; 1176 1177 free(psz_value); 1178 [super resetValues]; 1179} 1180@end 1181 1182@interface ModuleConfigControl() 1183{ 1184 NSPopUpButton *o_popup; 1185} 1186@end 1187 1188@implementation ModuleConfigControl 1189- (id)initWithItem:(module_config_t *)p_item 1190 withView:(NSView *)parentView 1191{ 1192 NSRect mainFrame = [parentView frame]; 1193 NSString *labelString, *o_popupTooltip; 1194 mainFrame.size.height = 22; 1195 mainFrame.size.width = mainFrame.size.width - LEFTMARGIN - RIGHTMARGIN + 1; 1196 mainFrame.origin.x = LEFTMARGIN; 1197 mainFrame.origin.y = 0; 1198 1199 if (self = [super initWithFrame:mainFrame item:p_item]) { 1200 self.viewType = CONFIG_ITEM_MODULE; 1201 1202 o_popupTooltip = [[VLCStringUtility sharedInstance] wrapString: _NS(p_item->psz_longtext) toWidth: PREFS_WRAP]; 1203 1204 /* add the label */ 1205 labelString = _NS(p_item->psz_text); 1206 1207 ADD_LABEL(self.label, mainFrame, 0, -1, labelString, o_popupTooltip) 1208 [self.label setAutoresizingMask:NSViewNotSizable ]; 1209 [self addSubview: self.label]; 1210 1211 /* build the popup */ 1212 ADD_POPUP(o_popup, mainFrame, [self.label frame].size.width, 1213 -2, 0, o_popupTooltip) 1214 [o_popup setAutoresizingMask:NSViewWidthSizable ]; 1215 [o_popup addItemWithTitle: _NS("Default")]; 1216 [[o_popup lastItem] setTag: -1]; 1217 [o_popup selectItem: [o_popup lastItem]]; 1218 1219 [self resetValues]; 1220 [self addSubview: o_popup]; 1221 } 1222 return self; 1223} 1224 1225- (void) alignWithXPosition:(int)i_xPos 1226{ 1227 NSRect frame; 1228 NSRect superFrame = [self frame]; 1229 frame = [self.label frame]; 1230 frame.origin.x = i_xPos - frame.size.width - 3; 1231 [self.label setFrame:frame]; 1232 1233 frame = [o_popup frame]; 1234 frame.origin.x = i_xPos - 1; 1235 frame.size.width = superFrame.size.width - frame.origin.x + 2; 1236 [o_popup setFrame:frame]; 1237} 1238 1239- (char *)stringValue 1240{ 1241 NSString *newval = [o_popup titleOfSelectedItem]; 1242 char *returnval = NULL; 1243 size_t i_module_index; 1244 module_t *p_parser, **p_list; 1245 1246 size_t count; 1247 p_list = module_list_get(&count); 1248 for (i_module_index = 0; i_module_index < count; i_module_index++) { 1249 p_parser = p_list[i_module_index]; 1250 1251 if (module_is_main(p_parser)) 1252 continue; 1253 1254 unsigned int confsize; 1255 module_config_t *p_config = module_config_get(p_parser, &confsize); 1256 for (size_t i = 0; i < confsize; i++) { 1257 module_config_t *p_cfg = p_config + i; 1258 /* Hack: required subcategory is stored in i_min */ 1259 if (p_cfg->i_type == CONFIG_SUBCATEGORY && 1260 p_cfg->value.i == self.p_item->min.i) { 1261 NSString *o_description = _NS(module_get_name(p_parser, TRUE)); 1262 if ([newval isEqualToString: o_description]) { 1263 returnval = strdup(module_get_object(p_parser)); 1264 break; 1265 } 1266 } 1267 } 1268 module_config_free(p_config); 1269 } 1270 module_list_free(p_list); 1271 1272 if(returnval == NULL && [newval isEqualToString: _NS("Default")] && self.p_item->orig.psz != NULL) { 1273 returnval = strdup(self.p_item->orig.psz); 1274 } 1275 return returnval; 1276} 1277 1278-(void)resetValues 1279{ 1280 /* build a list of available modules */ 1281 module_t *p_parser, **p_list; 1282 1283 size_t count; 1284 p_list = module_list_get(&count); 1285 for (size_t i_index = 0; i_index < count; i_index++) { 1286 p_parser = p_list[i_index]; 1287 1288 if (module_is_main(p_parser)) 1289 continue; 1290 unsigned int confsize; 1291 1292 module_config_t *p_configlist = module_config_get(p_parser, &confsize); 1293 for (size_t i = 0; i < confsize; i++) { 1294 module_config_t *p_config = &p_configlist[i]; 1295 /* Hack: required subcategory is stored in i_min */ 1296 if (p_config->i_type == CONFIG_SUBCATEGORY && 1297 p_config->value.i == self.p_item->min.i) { 1298 NSString *o_description = _NS(module_get_name(p_parser, TRUE)); 1299 [o_popup addItemWithTitle: o_description]; 1300 1301 if (self.p_item->value.psz && !strcmp(self.p_item->value.psz, 1302 module_get_object(p_parser))) 1303 [o_popup selectItem:[o_popup lastItem]]; 1304 } 1305 } 1306 module_config_free(p_configlist); 1307 } 1308 module_list_free(p_list); 1309 [super resetValues]; 1310} 1311@end 1312 1313@interface IntegerConfigControl() <NSTextFieldDelegate> 1314{ 1315 NSTextField *o_textfield; 1316 NSStepper *o_stepper; 1317} 1318@end 1319 1320@implementation IntegerConfigControl 1321- (id)initWithItem:(module_config_t *)p_item 1322 withView:(NSView *)parentView 1323{ 1324 NSRect mainFrame = [parentView frame]; 1325 NSString *labelString, *toolTip; 1326 mainFrame.size.height = 23; 1327 mainFrame.size.width = mainFrame.size.width - LEFTMARGIN - RIGHTMARGIN + 1; 1328 mainFrame.origin.x = LEFTMARGIN; 1329 mainFrame.origin.y = 0; 1330 1331 if (self = [super initWithFrame:mainFrame item:p_item]) { 1332 self.viewType = CONFIG_ITEM_INTEGER; 1333 1334 toolTip = [[VLCStringUtility sharedInstance] wrapString: _NS(p_item->psz_longtext) toWidth: PREFS_WRAP]; 1335 1336 /* add the label */ 1337 labelString = _NS((char *)p_item->psz_text); 1338 ADD_LABEL(self.label, mainFrame, 0, -3, labelString, toolTip) 1339 [self.label setAutoresizingMask:NSViewNotSizable ]; 1340 [self addSubview: self.label]; 1341 1342 /* build the stepper */ 1343 ADD_STEPPER(o_stepper, mainFrame, mainFrame.size.width - 19, 1344 0, toolTip, -100000, 100000) 1345 [o_stepper setIntValue: p_item->value.i]; 1346 [o_stepper setAutoresizingMask:NSViewMaxXMargin ]; 1347 [self addSubview: o_stepper]; 1348 1349 ADD_TEXTFIELD(o_textfield, mainFrame, mainFrame.size.width - 19 - 52, 1350 1, 49, toolTip, @"") 1351 [o_textfield setIntValue: p_item->value.i]; 1352 [o_textfield setDelegate: self]; 1353 [[NSNotificationCenter defaultCenter] addObserver: self 1354 selector: @selector(textfieldChanged:) 1355 name: NSControlTextDidChangeNotification 1356 object: o_textfield]; 1357 [o_textfield setAutoresizingMask:NSViewMaxXMargin ]; 1358 [self addSubview: o_textfield]; 1359 } 1360 return self; 1361} 1362 1363- (void) alignWithXPosition:(int)i_xPos 1364{ 1365 NSRect frame; 1366 frame = [self.label frame]; 1367 frame.origin.x = i_xPos - frame.size.width - 3; 1368 [self.label setFrame:frame]; 1369 1370 frame = [o_textfield frame]; 1371 frame.origin.x = i_xPos + 2; 1372 [o_textfield setFrame:frame]; 1373 1374 frame = [o_stepper frame]; 1375 frame.origin.x = i_xPos + [o_textfield frame].size.width + 5; 1376 [o_stepper setFrame:frame]; 1377} 1378 1379- (IBAction)stepperChanged:(id)sender 1380{ 1381 [o_textfield setIntValue: [o_stepper intValue]]; 1382} 1383 1384- (void)textfieldChanged:(NSNotification *)o_notification 1385{ 1386 [o_stepper setIntValue: [o_textfield intValue]]; 1387} 1388 1389- (int)intValue 1390{ 1391 return [o_textfield intValue]; 1392} 1393 1394-(void)resetValues 1395{ 1396 [o_textfield setIntValue: config_GetInt(getIntf(), self.p_item->psz_name)]; 1397 [super resetValues]; 1398} 1399 1400@end 1401 1402@interface IntegerListConfigControl() 1403{ 1404 NSPopUpButton *o_popup; 1405} 1406@end 1407 1408@implementation IntegerListConfigControl 1409 1410- (id)initWithItem:(module_config_t *)p_item 1411 withView:(NSView *)parentView 1412{ 1413 NSRect mainFrame = [parentView frame]; 1414 NSString *labelString, *o_textfieldTooltip; 1415 mainFrame.size.height = 22; 1416 mainFrame.size.width = mainFrame.size.width - LEFTMARGIN - RIGHTMARGIN + 1; 1417 mainFrame.origin.x = LEFTMARGIN; 1418 mainFrame.origin.y = 0; 1419 1420 if (self = [super initWithFrame:mainFrame item:p_item]) { 1421 self.viewType = CONFIG_ITEM_STRING_LIST; 1422 1423 o_textfieldTooltip = [[VLCStringUtility sharedInstance] wrapString: _NS(p_item->psz_longtext) toWidth: PREFS_WRAP]; 1424 1425 /* add the label */ 1426 labelString = _NS(p_item->psz_text); 1427 ADD_LABEL(self.label, mainFrame, 0, -3, labelString, o_textfieldTooltip) 1428 [self.label setAutoresizingMask:NSViewNotSizable ]; 1429 [self addSubview: self.label]; 1430 1431 /* build the textfield */ 1432 ADD_POPUP(o_popup, mainFrame, [self.label frame].size.width, 1433 -2, 0, o_textfieldTooltip) 1434 [o_popup setAutoresizingMask:NSViewWidthSizable ]; 1435 1436 /* add items */ 1437 [self resetValues]; 1438 1439 [self addSubview: o_popup]; 1440 } 1441 return self; 1442} 1443 1444- (void) alignWithXPosition:(int)i_xPos 1445{ 1446 NSRect frame; 1447 NSRect superFrame = [self frame]; 1448 frame = [self.label frame]; 1449 frame.origin.x = i_xPos - frame.size.width - 3; 1450 [self.label setFrame:frame]; 1451 1452 frame = [o_popup frame]; 1453 frame.origin.x = i_xPos + 2; 1454 frame.size.width = superFrame.size.width - frame.origin.x + 2; 1455 [o_popup setFrame:frame]; 1456} 1457 1458- (int)intValue 1459{ 1460 NSNumber *p_valueobject = (NSNumber *)[[o_popup selectedItem] representedObject]; 1461 if (p_valueobject) { 1462 assert([p_valueobject isKindOfClass:[NSNumber class]]); 1463 return [p_valueobject intValue]; 1464 } else 1465 return 0; 1466} 1467 1468-(void)resetValues 1469{ 1470 [o_popup removeAllItems]; 1471 1472 int i_current_selection = config_GetInt(getIntf(), self.p_item->psz_name); 1473 int64_t *values; 1474 char **texts; 1475 ssize_t count = config_GetIntChoices(VLC_OBJECT(getIntf()), self.p_item->psz_name, &values, &texts); 1476 for (ssize_t i = 0; i < count; i++) { 1477 NSMenuItem *mi = [[NSMenuItem alloc] initWithTitle: toNSStr(texts[i]) action: NULL keyEquivalent: @""]; 1478 [mi setRepresentedObject:[NSNumber numberWithInt:values[i]]]; 1479 [[o_popup menu] addItem:mi]; 1480 1481 if (i_current_selection == values[i]) 1482 [o_popup selectItem:[o_popup lastItem]]; 1483 1484 free(texts[i]); 1485 } 1486 free(texts); 1487} 1488@end 1489 1490@interface RangedIntegerConfigControl() <NSTextFieldDelegate> 1491{ 1492 NSSlider *o_slider; 1493 NSTextField *o_textfield; 1494 NSTextField *o_textfield_min; 1495 NSTextField *o_textfield_max; 1496} 1497@end 1498 1499@implementation RangedIntegerConfigControl 1500- (id)initWithItem:(module_config_t *)p_item 1501 withView:(NSView *)parentView 1502{ 1503 NSRect mainFrame = [parentView frame]; 1504 NSString *labelString, *toolTip; 1505 mainFrame.size.height = 50; 1506 mainFrame.size.width = mainFrame.size.width - LEFTMARGIN - RIGHTMARGIN; 1507 mainFrame.origin.x = LEFTMARGIN; 1508 mainFrame.origin.y = 0; 1509 1510 if (self = [super initWithFrame: mainFrame item:p_item]) { 1511 self.viewType = CONFIG_ITEM_RANGED_INTEGER; 1512 1513 toolTip = [[VLCStringUtility sharedInstance] wrapString: _NS(p_item->psz_longtext) toWidth: PREFS_WRAP]; 1514 1515 /* add the label */ 1516 labelString = _NS(p_item->psz_text); 1517 ADD_LABEL(self.label, mainFrame, 0, -3, labelString, toolTip) 1518 [self.label setAutoresizingMask:NSViewNotSizable ]; 1519 [self addSubview: self.label]; 1520 1521 /* build the textfield */ 1522 ADD_TEXTFIELD(o_textfield, mainFrame, [self.label frame].size.width + 2, 1523 28, 70, toolTip, @"") 1524 [o_textfield setIntValue: p_item->value.i]; 1525 [o_textfield setAutoresizingMask:NSViewMaxXMargin ]; 1526 [o_textfield setDelegate: self]; 1527 [[NSNotificationCenter defaultCenter] addObserver: self 1528 selector: @selector(textfieldChanged:) 1529 name: NSControlTextDidChangeNotification 1530 object: o_textfield]; 1531 [self addSubview: o_textfield]; 1532 1533 /* build the mintextfield */ 1534 ADD_LABEL(o_textfield_min, mainFrame, 12, -30, @"-88888", @"") 1535 [o_textfield_min setIntValue: p_item->min.i]; 1536 [o_textfield_min setAutoresizingMask:NSViewMaxXMargin ]; 1537 [o_textfield_min setAlignment:NSRightTextAlignment]; 1538 [self addSubview: o_textfield_min]; 1539 1540 /* build the maxtextfield */ 1541 ADD_LABEL(o_textfield_max, mainFrame, 1542 mainFrame.size.width - 50, -30, @"88888", @"") 1543 [o_textfield_max setIntValue: p_item->max.i]; 1544 [o_textfield_max setAutoresizingMask:NSViewMinXMargin ]; 1545 [self addSubview: o_textfield_max]; 1546 1547 [o_textfield_max sizeToFit]; 1548 [o_textfield_min sizeToFit]; 1549 1550 /* build the slider */ 1551 ADD_SLIDER(o_slider, mainFrame, [o_textfield_min frame].origin.x + 1552 [o_textfield_min frame].size.width + 6, -1, 1553 [o_textfield_max frame].origin.x - 1554 ([o_textfield_min frame].origin.x + [o_textfield_min frame].size.width) - 14, toolTip, 1555 p_item->min.i, p_item->max.i) 1556 [o_slider setIntValue: p_item->value.i]; 1557 [o_slider setAutoresizingMask:NSViewWidthSizable ]; 1558 [o_slider setTarget: self]; 1559 [o_slider setAction: @selector(sliderChanged:)]; 1560 [o_slider sendActionOn:NSLeftMouseUpMask | NSLeftMouseDownMask | 1561 NSLeftMouseDraggedMask]; 1562 [self addSubview: o_slider]; 1563 1564 } 1565 return self; 1566} 1567 1568- (void) alignWithXPosition:(int)i_xPos 1569{ 1570 NSRect frame; 1571 frame = [self.label frame]; 1572 frame.origin.x = i_xPos - frame.size.width - 3; 1573 [self.label setFrame:frame]; 1574 1575 frame = [o_textfield frame]; 1576 frame.origin.x = i_xPos + 2; 1577 [o_textfield setFrame:frame]; 1578} 1579 1580- (IBAction)sliderChanged:(id)sender 1581{ 1582 [o_textfield setIntValue: [o_slider intValue]]; 1583} 1584 1585- (void)textfieldChanged:(NSNotification *)o_notification 1586{ 1587 [o_slider setIntValue: [o_textfield intValue]]; 1588} 1589 1590- (int)intValue 1591{ 1592 return [o_slider intValue]; 1593} 1594 1595- (void)resetValues 1596{ 1597 int value = config_GetInt(getIntf(), self.p_item->psz_name); 1598 [o_textfield setIntValue:value]; 1599 [o_slider setIntValue:value]; 1600 [super resetValues]; 1601} 1602@end 1603 1604@interface FloatConfigControl() <NSTextFieldDelegate> 1605{ 1606 NSTextField *o_textfield; 1607 NSStepper *o_stepper; 1608} 1609@end 1610 1611@implementation FloatConfigControl 1612- (id)initWithItem:(module_config_t *)p_item 1613 withView:(NSView *)parentView 1614{ 1615 NSRect mainFrame = [parentView frame]; 1616 NSString *labelString, *toolTip; 1617 mainFrame.size.height = 23; 1618 mainFrame.size.width = mainFrame.size.width - LEFTMARGIN - RIGHTMARGIN + 1; 1619 mainFrame.origin.x = LEFTMARGIN; 1620 mainFrame.origin.y = 0; 1621 1622 if (self = [super initWithFrame:mainFrame item:p_item]) { 1623 self.viewType = CONFIG_ITEM_INTEGER; 1624 1625 toolTip = [[VLCStringUtility sharedInstance] wrapString: _NS(p_item->psz_longtext) toWidth: PREFS_WRAP]; 1626 1627 /* add the label */ 1628 labelString = _NS(p_item->psz_text); 1629 ADD_LABEL(self.label, mainFrame, 0, -2, labelString, toolTip) 1630 [self.label setAutoresizingMask:NSViewNotSizable ]; 1631 [self addSubview: self.label]; 1632 1633 /* build the stepper */ 1634 ADD_STEPPER(o_stepper, mainFrame, mainFrame.size.width - 19, 1635 0, toolTip, -100000, 100000) 1636 [o_stepper setFloatValue: p_item->value.f]; 1637 [o_stepper setAutoresizingMask:NSViewMaxXMargin ]; 1638 [self addSubview: o_stepper]; 1639 1640 /* build the textfield */ 1641 ADD_TEXTFIELD(o_textfield, mainFrame, mainFrame.size.width - 19 - 52, 1642 1, 49, toolTip, @"") 1643 [o_textfield setFloatValue: p_item->value.f]; 1644 [o_textfield setDelegate: self]; 1645 [[NSNotificationCenter defaultCenter] addObserver: self 1646 selector: @selector(textfieldChanged:) 1647 name: NSControlTextDidChangeNotification 1648 object: o_textfield]; 1649 [o_textfield setAutoresizingMask:NSViewMaxXMargin ]; 1650 [self addSubview: o_textfield]; 1651 } 1652 return self; 1653} 1654 1655- (void) alignWithXPosition:(int)i_xPos 1656{ 1657 NSRect frame; 1658 frame = [self.label frame]; 1659 frame.origin.x = i_xPos - frame.size.width - 3; 1660 [self.label setFrame:frame]; 1661 1662 frame = [o_textfield frame]; 1663 frame.origin.x = i_xPos + 2; 1664 [o_textfield setFrame:frame]; 1665 1666 frame = [o_stepper frame]; 1667 frame.origin.x = i_xPos + [o_textfield frame].size.width + 5; 1668 [o_stepper setFrame:frame]; 1669} 1670 1671- (IBAction)stepperChanged:(id)sender 1672{ 1673 [o_textfield setFloatValue: [o_stepper floatValue]]; 1674} 1675 1676- (void)textfieldChanged:(NSNotification *)o_notification 1677{ 1678 [o_stepper setFloatValue: [o_textfield floatValue]]; 1679} 1680 1681- (float)floatValue 1682{ 1683 return [o_stepper floatValue]; 1684} 1685 1686- (void)resetValues 1687{ 1688 [o_textfield setFloatValue: config_GetFloat(getIntf(), self.p_item->psz_name)]; 1689 [super resetValues]; 1690} 1691@end 1692 1693@interface RangedFloatConfigControl() <NSTextFieldDelegate> 1694{ 1695 NSSlider *o_slider; 1696 NSTextField *o_textfield; 1697 NSTextField *o_textfield_min; 1698 NSTextField *o_textfield_max; 1699} 1700@end 1701 1702@implementation RangedFloatConfigControl 1703- (id)initWithItem:(module_config_t *)p_item 1704 withView:(NSView *)parentView 1705{ 1706 NSRect mainFrame = [parentView frame]; 1707 NSString *labelString, *toolTip; 1708 mainFrame.size.height = 50; 1709 mainFrame.size.width = mainFrame.size.width - LEFTMARGIN - RIGHTMARGIN; 1710 mainFrame.origin.x = LEFTMARGIN; 1711 mainFrame.origin.y = 0; 1712 1713 if (self = [super initWithFrame:mainFrame item:p_item]) { 1714 self.viewType = CONFIG_ITEM_RANGED_INTEGER; 1715 1716 toolTip = [[VLCStringUtility sharedInstance] wrapString: _NS(p_item->psz_longtext) toWidth: PREFS_WRAP]; 1717 1718 /* add the label */ 1719 labelString = _NS(p_item->psz_text); 1720 ADD_LABEL(self.label, mainFrame, 0, -3, labelString, toolTip) 1721 [self.label setAutoresizingMask:NSViewNotSizable ]; 1722 [self addSubview: self.label]; 1723 1724 /* build the textfield */ 1725 ADD_TEXTFIELD(o_textfield, mainFrame, [self.label frame].size.width + 2, 1726 28, 49, toolTip, @"") 1727 [o_textfield setFloatValue: p_item->value.f]; 1728 [o_textfield setAutoresizingMask:NSViewMaxXMargin ]; 1729 [o_textfield setDelegate: self]; 1730 [[NSNotificationCenter defaultCenter] addObserver: self 1731 selector: @selector(textfieldChanged:) 1732 name: NSControlTextDidChangeNotification 1733 object: o_textfield]; 1734 [self addSubview: o_textfield]; 1735 1736 /* build the mintextfield */ 1737 ADD_LABEL(o_textfield_min, mainFrame, 12, -30, @"-8888", @"") 1738 [o_textfield_min setFloatValue: p_item->min.f]; 1739 [o_textfield_min setAutoresizingMask:NSViewMaxXMargin ]; 1740 [o_textfield_min setAlignment:NSRightTextAlignment]; 1741 [self addSubview: o_textfield_min]; 1742 1743 /* build the maxtextfield */ 1744 ADD_LABEL(o_textfield_max, mainFrame, mainFrame.size.width - 31, 1745 -30, @"8888", @"") 1746 [o_textfield_max setFloatValue: p_item->max.f]; 1747 [o_textfield_max setAutoresizingMask:NSViewMinXMargin ]; 1748 [self addSubview: o_textfield_max]; 1749 1750 /* build the slider */ 1751 ADD_SLIDER(o_slider, mainFrame, [o_textfield_min frame].origin.x + 1752 [o_textfield_min frame].size.width + 6, -1, mainFrame.size.width - 1753 [o_textfield_max frame].size.width - 1754 [o_textfield_max frame].size.width - 14 - 1755 [o_textfield_min frame].origin.x, toolTip, p_item->min.f, 1756 p_item->max.f) 1757 [o_slider setFloatValue: p_item->value.f]; 1758 [o_slider setAutoresizingMask:NSViewWidthSizable ]; 1759 [o_slider setTarget: self]; 1760 [o_slider setAction: @selector(sliderChanged:)]; 1761 [o_slider sendActionOn:NSLeftMouseUpMask | NSLeftMouseDownMask | 1762 NSLeftMouseDraggedMask]; 1763 [self addSubview: o_slider]; 1764 1765 } 1766 return self; 1767} 1768 1769- (void) alignWithXPosition:(int)i_xPos 1770{ 1771 NSRect frame; 1772 frame = [self.label frame]; 1773 frame.origin.x = i_xPos - frame.size.width - 3; 1774 [self.label setFrame:frame]; 1775 1776 frame = [o_textfield frame]; 1777 frame.origin.x = i_xPos + 2; 1778 [o_textfield setFrame:frame]; 1779} 1780 1781- (IBAction)sliderChanged:(id)sender 1782{ 1783 [o_textfield setFloatValue: [o_slider floatValue]]; 1784} 1785 1786- (void)textfieldChanged:(NSNotification *)o_notification 1787{ 1788 [o_slider setFloatValue: [o_textfield floatValue]]; 1789} 1790 1791- (float)floatValue 1792{ 1793 return [o_slider floatValue]; 1794} 1795 1796- (void)resetValues 1797{ 1798 [o_textfield setFloatValue: config_GetFloat(getIntf(), self.p_item->psz_name)]; 1799 [o_slider setFloatValue: config_GetFloat(getIntf(), self.p_item->psz_name)]; 1800 [super resetValues]; 1801} 1802@end 1803 1804@interface BoolConfigControl() 1805{ 1806 NSButton *o_checkbox; 1807} 1808@end 1809 1810@implementation BoolConfigControl 1811 1812- (id)initWithItem:(module_config_t *)p_item 1813 withView:(NSView *)parentView 1814{ 1815 NSRect mainFrame = [parentView frame]; 1816 NSString *labelString, *toolTip; 1817 mainFrame.size.height = 17; 1818 mainFrame.size.width = mainFrame.size.width - LEFTMARGIN - RIGHTMARGIN; 1819 mainFrame.origin.x = LEFTMARGIN; 1820 mainFrame.origin.y = 0; 1821 1822 self = [super initWithFrame:mainFrame item:p_item]; 1823 1824 if (self != nil) { 1825 self.viewType = CONFIG_ITEM_BOOL; 1826 1827 labelString = _NS(p_item->psz_text); 1828 1829 toolTip = [[VLCStringUtility sharedInstance] wrapString: _NS(p_item->psz_longtext) toWidth: PREFS_WRAP]; 1830 1831 /* add the checkbox */ 1832 ADD_CHECKBOX(o_checkbox, mainFrame, 0, 1833 0, labelString, toolTip, p_item->value.i, NSImageLeft) 1834 [o_checkbox setAutoresizingMask:NSViewNotSizable]; 1835 [self addSubview: o_checkbox]; 1836 } 1837 return self; 1838} 1839 1840- (int)intValue 1841{ 1842 return [o_checkbox intValue]; 1843} 1844 1845- (void)resetValues 1846{ 1847 [o_checkbox setState: config_GetInt(getIntf(), self.p_item->psz_name)]; 1848 [super resetValues]; 1849} 1850@end 1851 1852@interface KeyConfigControl() 1853{ 1854 NSPopUpButton *o_popup; 1855} 1856@end 1857 1858@implementation KeyConfigControl 1859- (id)initWithItem:(module_config_t *)p_item 1860 withView:(NSView *)parentView 1861{ 1862 NSRect mainFrame = [parentView frame]; 1863 NSString *labelString, *toolTip; 1864 mainFrame.size.height = 22; 1865 mainFrame.size.width = mainFrame.size.width - LEFTMARGIN - RIGHTMARGIN + 1; 1866 mainFrame.origin.x = LEFTMARGIN; 1867 mainFrame.origin.y = 0; 1868 1869 if (self = [super initWithFrame:mainFrame item:p_item]) { 1870 self.viewType = CONFIG_ITEM_KEY; 1871 1872 toolTip = [[VLCStringUtility sharedInstance] wrapString: _NS(p_item->psz_longtext) toWidth: PREFS_WRAP]; 1873 1874 /* add the label */ 1875 labelString = _NS(p_item->psz_text); 1876 ADD_LABEL(self.label, mainFrame, 0, -1, labelString, toolTip) 1877 [self.label setAutoresizingMask:NSViewNotSizable ]; 1878 [self addSubview: self.label]; 1879 1880 /* build the popup */ 1881 ADD_POPUP(o_popup, mainFrame, [self.label frame].origin.x + 1882 [self.label frame].size.width + 3, 1883 -2, 0, toolTip) 1884 [o_popup setAutoresizingMask:NSViewWidthSizable ]; 1885 1886 if (o_keys_menu == nil) { 1887 unsigned int i; 1888 o_keys_menu = [[NSMenu alloc] initWithTitle: @"Keys Menu"]; 1889#warning This does not work anymore. FIXME. 1890#if 0 1891 for (i = 0; i < sizeof(vlc_key) / sizeof(key_descriptor_t); i++) 1892 if (vlc_key[i].psz_key_string) 1893 POPULATE_A_KEY(o_keys_menu,toNSStr(vlc_key[i].psz_key_string), 1894 vlc_key[i].i_key_code) 1895#endif 1896 } 1897 [o_popup setMenu:[o_keys_menu copyWithZone:nil]]; 1898 [o_popup selectItem:[[o_popup menu] itemWithTag:p_item->value.i]]; 1899 [self addSubview: o_popup]; 1900 1901 } 1902 return self; 1903} 1904 1905- (void) alignWithXPosition:(int)i_xPos 1906{ 1907 NSRect frame; 1908 NSRect superFrame = [self frame]; 1909 frame = [self.label frame]; 1910 frame.origin.x = i_xPos - frame.size.width - 3; 1911 [self.label setFrame:frame]; 1912 1913 frame = [o_popup frame]; 1914 frame.origin.x = i_xPos - 1; 1915 frame.size.width = superFrame.size.width - frame.origin.x + 2; 1916 [o_popup setFrame:frame]; 1917} 1918 1919- (int)intValue 1920{ 1921 return [o_popup selectedTag]; 1922} 1923 1924- (void)resetValues 1925{ 1926 [o_popup selectItem:[[o_popup menu] itemWithTag:config_GetInt(getIntf(), self.p_item->psz_name)]]; 1927 [super resetValues]; 1928} 1929@end 1930 1931@interface ModuleListConfigControl() <NSTextFieldDelegate, NSTableViewDataSource> 1932{ 1933 NSTextField *o_textfield; 1934 NSTableView *o_tableview; 1935 NSMutableArray *o_modulearray; 1936} 1937@end 1938 1939@implementation ModuleListConfigControl 1940- (id)initWithItem:(module_config_t *)p_item 1941 withView:(NSView *)parentView 1942{ 1943 self = [super initWithFrame:CGRectZero item:p_item]; 1944 if (!self) { 1945 return self; 1946 } 1947 self.viewType = CONFIG_ITEM_MODULE_LIST; 1948 1949 BOOL b_by_cat = p_item->i_type == CONFIG_ITEM_MODULE_LIST_CAT; 1950 1951 //Fill our array to know how may items we have... 1952 module_t *p_parser, **p_list; 1953 size_t i_module_index; 1954 NSRect mainFrame = [parentView frame]; 1955 NSString *labelString, *o_textfieldString, *toolTip; 1956 1957 o_modulearray = [[NSMutableArray alloc] initWithCapacity:10]; 1958 /* build a list of available modules */ 1959 size_t count; 1960 p_list = module_list_get(&count); 1961 for (i_module_index = 0; i_module_index < count; i_module_index++) { 1962 int i; 1963 p_parser = p_list[i_module_index]; 1964 1965 if (module_is_main(p_parser)) 1966 continue; 1967 1968 if (b_by_cat) { 1969 unsigned int confsize; 1970 module_config_t *p_configlist = module_config_get(p_parser, &confsize); 1971 1972 for (i = 0; i < confsize; i++) { 1973 unsigned int unused; 1974 module_config_t *p_config = &p_configlist[i]; 1975 NSString *o_modulelongname, *o_modulename; 1976 NSNumber *o_moduleenabled = nil; 1977 1978 /* Hack: required subcategory is stored in i_min */ 1979 if (p_config->i_type == CONFIG_SUBCATEGORY && 1980 p_config->value.i == p_item->min.i) { 1981 1982 o_modulelongname = toNSStr(module_get_name(p_parser, TRUE)); 1983 o_modulename = toNSStr(module_get_object(p_parser)); 1984 1985 if (p_item->value.psz && 1986 strstr(p_item->value.psz, module_get_object(p_parser))) 1987 o_moduleenabled = [NSNumber numberWithBool:YES]; 1988 else 1989 o_moduleenabled = [NSNumber numberWithBool:NO]; 1990 1991 [o_modulearray addObject:[NSMutableArray 1992 arrayWithObjects: o_modulename, o_modulelongname, 1993 o_moduleenabled, nil]]; 1994 } 1995 1996 /* Parental Advisory HACK: 1997 * Selecting HTTP, RC and Telnet interfaces is difficult now 1998 * since they are just the lua interface module */ 1999 if (p_config->i_type == CONFIG_SUBCATEGORY && 2000 !strcmp(module_get_object(p_parser), "lua") && 2001 !strcmp(p_item->psz_name, "extraintf") && 2002 p_config->value.i == p_item->min.i) { 2003 2004#define addLuaIntf(shortname, longname) \ 2005if (p_item->value.psz && strstr(p_item->value.psz, shortname))\ 2006o_moduleenabled = [NSNumber numberWithBool:YES];\ 2007else \ 2008o_moduleenabled = [NSNumber numberWithBool:NO];\ 2009[o_modulearray addObject:[NSMutableArray arrayWithObjects: @shortname, _NS(longname), o_moduleenabled, nil]] 2010 2011 addLuaIntf("http", "Web"); 2012 addLuaIntf("telnet", "Telnet"); 2013 addLuaIntf("cli", "Console"); 2014#undef addLuaIntf 2015 } 2016 2017 } 2018 module_config_free(p_configlist); 2019 2020 } else if (module_provides(p_parser, p_item->psz_type)) { 2021 2022 NSString *o_modulelongname = toNSStr(module_get_name(p_parser, TRUE)); 2023 NSString *o_modulename = toNSStr(module_get_object(p_parser)); 2024 2025 NSNumber *o_moduleenabled = nil; 2026 if (p_item->value.psz && 2027 strstr(p_item->value.psz, module_get_object(p_parser))) 2028 o_moduleenabled = [NSNumber numberWithBool:YES]; 2029 else 2030 o_moduleenabled = [NSNumber numberWithBool:NO]; 2031 2032 [o_modulearray addObject:[NSMutableArray 2033 arrayWithObjects: o_modulename, o_modulelongname, 2034 o_moduleenabled, nil]]; 2035 } 2036 2037 } /* FOR i_module_index */ 2038 module_list_free(p_list); 2039 2040 // First, initialize and draw the table view to get its height 2041 // width is increased a little to fix horizontal auto-sizing 2042 NSRect s_rc = NSMakeRect(12, 10, mainFrame.size.width - LEFTMARGIN - RIGHTMARGIN + 18, 50); 2043 // height is automatically increased as needed 2044 o_tableview = [[NSTableView alloc] initWithFrame : s_rc]; 2045 [o_tableview setUsesAlternatingRowBackgroundColors:YES]; 2046 [o_tableview setHeaderView:nil]; 2047 /* FIXME: support for multiple selection... */ 2048 // [o_tableview setAllowsMultipleSelection:YES]; 2049 2050 NSTableHeaderCell *o_headerCell = [[NSTableHeaderCell alloc] initTextCell:@"Enabled"]; 2051 NSCell *o_dataCell = [[NSButtonCell alloc] init]; 2052 [(NSButtonCell*)o_dataCell setButtonType:NSSwitchButton]; 2053 [o_dataCell setTitle:@""]; 2054 [o_dataCell setFont:[NSFont systemFontOfSize:0]]; 2055 NSTableColumn *o_tableColumn = [[NSTableColumn alloc] 2056 initWithIdentifier:@"Enabled"]; 2057 [o_tableColumn setHeaderCell: o_headerCell]; 2058 [o_tableColumn setDataCell: o_dataCell]; 2059 [o_tableColumn setWidth:17]; 2060 [o_tableview addTableColumn: o_tableColumn]; 2061 2062 o_headerCell = [[NSTableHeaderCell alloc] initTextCell:@"Module Name"]; 2063 o_dataCell = [[NSTextFieldCell alloc] init]; 2064 [o_dataCell setFont:[NSFont systemFontOfSize:12]]; 2065 o_tableColumn = [[NSTableColumn alloc] 2066 initWithIdentifier:@"Module"]; 2067 [o_tableColumn setHeaderCell: o_headerCell]; 2068 [o_tableColumn setDataCell: o_dataCell]; 2069 [o_tableColumn setWidth:s_rc.size.width - 34]; 2070 [o_tableview addTableColumn: o_tableColumn]; 2071 [o_tableview registerForDraggedTypes:[NSArray arrayWithObject:@"VLC media player module"]]; 2072 2073 [o_tableview setDataSource:self]; 2074 [o_tableview setTarget: self]; 2075 [o_tableview setAction: @selector(tableChanged:)]; 2076 [o_tableview sendActionOn:NSLeftMouseUpMask | NSLeftMouseDownMask | 2077 NSLeftMouseDraggedMask]; 2078 2079 [o_tableview reloadData]; 2080 [o_tableview setAutoresizingMask: NSViewWidthSizable]; 2081 2082 CGFloat tableview_height = [o_tableview frame].size.height; 2083 2084 mainFrame.size.height = 40 + tableview_height; 2085 mainFrame.size.width = mainFrame.size.width - LEFTMARGIN - RIGHTMARGIN; 2086 mainFrame.origin.x = LEFTMARGIN; 2087 mainFrame.origin.y = 0; 2088 self.frame = mainFrame; 2089 2090 toolTip = [[VLCStringUtility sharedInstance] wrapString: _NS(p_item->psz_longtext) toWidth: PREFS_WRAP]; 2091 2092 /* add the label */ 2093 labelString = _NS((char *)p_item->psz_text); 2094 ADD_LABEL(self.label, mainFrame, 0, -3, labelString, toolTip) 2095 [self.label setAutoresizingMask:NSViewNotSizable ]; 2096 [self addSubview: self.label]; 2097 2098 /* build the textfield */ 2099 o_textfieldString = _NS(p_item->value.psz); 2100 ADD_TEXTFIELD(o_textfield, mainFrame, [self.label frame].size.width + 2, 2101 mainFrame.size.height - 22, mainFrame.size.width - 2102 [self.label frame].size.width - 2, toolTip, o_textfieldString) 2103 [o_textfield setAutoresizingMask:NSViewWidthSizable ]; 2104 [self addSubview: o_textfield]; 2105 2106 [self addSubview: o_tableview]; 2107 2108 return self; 2109} 2110 2111- (void) alignWithXPosition:(int)i_xPos 2112{ 2113 ; 2114} 2115 2116- (IBAction)tableChanged:(id)sender 2117{ 2118 NSString *o_newstring = @""; 2119 NSUInteger count = [o_modulearray count]; 2120 for (NSUInteger i = 0 ; i < count ; i++) 2121 if ([[[o_modulearray objectAtIndex:i] objectAtIndex:2] 2122 boolValue] != NO) { 2123 o_newstring = [o_newstring stringByAppendingString: 2124 [[o_modulearray objectAtIndex:i] firstObject]]; 2125 o_newstring = [o_newstring stringByAppendingString:@":"]; 2126 } 2127 2128 [o_textfield setStringValue: [o_newstring 2129 substringToIndex:([o_newstring length])?[o_newstring length] - 1:0]]; 2130} 2131 2132- (char *)stringValue 2133{ 2134 return strdup([[o_textfield stringValue] UTF8String]); 2135} 2136 2137/* FIXME: 2138 * This is supposed to load the module list state from preferences 2139 * and set the table items state (selected or unselected) accordingly, 2140 * as far as I could figure out by reading the commit in which this was 2141 * introduced. (d66f3c874786e9dd4692f9775bdd54b386c583dd) 2142 */ 2143-(void)resetValues 2144{ 2145#warning Reset prefs of the module selector is broken atm. 2146 msg_Err(getIntf(), "don't forget about modulelistconfig"); 2147 [super resetValues]; 2148} 2149 2150@end 2151 2152@implementation ModuleListConfigControl (NSTableDataSource) 2153 2154- (BOOL)tableView:(NSTableView*)table writeRows:(NSArray*)rows 2155 toPasteboard:(NSPasteboard*)pb 2156{ 2157 // We only want to allow dragging of selected rows. 2158 NSEnumerator *iter = [rows objectEnumerator]; 2159 NSNumber *row; 2160 while ((row = [iter nextObject]) != nil) { 2161 if (![table isRowSelected:[row intValue]]) 2162 return NO; 2163 } 2164 2165 [pb declareTypes:[NSArray arrayWithObject:@"VLC media player module"] owner:nil]; 2166 [pb setPropertyList:rows forType:@"VLC media player module"]; 2167 return YES; 2168} 2169 2170- (NSDragOperation)tableView:(NSTableView*)table 2171 validateDrop:(id <NSDraggingInfo>)info proposedRow:(NSInteger)row 2172 proposedDropOperation:(NSTableViewDropOperation)op 2173{ 2174 // Make drops at the end of the table go to the end. 2175 if (row == -1) { 2176 row = [table numberOfRows]; 2177 op = NSTableViewDropAbove; 2178 [table setDropRow:row dropOperation:op]; 2179 } 2180 2181 // We don't ever want to drop onto a row, only between rows. 2182 if (op == NSTableViewDropOn) 2183 [table setDropRow:(row+1) dropOperation:NSTableViewDropAbove]; 2184 return NSDragOperationGeneric; 2185} 2186 2187- (BOOL)tableView:(NSTableView*)table acceptDrop:(id <NSDraggingInfo>)info 2188 row:(NSInteger)dropRow dropOperation:(NSTableViewDropOperation)op; 2189{ 2190 NSPasteboard *pb = [info draggingPasteboard]; 2191 BOOL accepted = NO; 2192 2193 NS_DURING 2194 2195 NSArray *array; 2196 2197 // Intra-table drag - data is the array of rows. 2198 if (!accepted && (array = 2199 [pb propertyListForType:@"VLC media player module"]) != NULL) { 2200 NSEnumerator *iter = nil; 2201 id val; 2202 // Move the modules 2203 iter = [array objectEnumerator]; 2204 while ((val = [iter nextObject]) != NULL) { 2205 NSArray *o_tmp = [[o_modulearray objectAtIndex: 2206 [val intValue]] mutableCopyWithZone:nil]; 2207 [o_modulearray removeObject:o_tmp]; 2208 [o_modulearray insertObject:o_tmp 2209 atIndex:(dropRow>[val intValue]) ? dropRow - 1 : dropRow]; 2210 dropRow++; 2211 } 2212 2213 // Select the newly-dragged items. 2214 iter = [array objectEnumerator]; 2215 //TODO... 2216 [table deselectAll:self]; 2217 2218 [self tableChanged:self]; 2219 [table setNeedsDisplay:YES]; 2220 // Indicate that we finished the drag. 2221 accepted = YES; 2222 } 2223 [table reloadData]; 2224 [table setNeedsDisplay:YES]; 2225 2226 NS_HANDLER 2227 2228 // An exception occurred. Uh-oh. Update the track table so that 2229 // it stays consistent, and re-raise the exception. 2230 [table reloadData]; 2231 [localException raise]; 2232 [table setNeedsDisplay:YES]; 2233 NS_ENDHANDLER 2234 2235 return accepted; 2236} 2237 2238- (NSInteger)numberOfRowsInTableView:(NSTableView *)aTableView 2239{ 2240 return [o_modulearray count]; 2241} 2242 2243- (id)tableView:(NSTableView *)aTableView 2244objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex 2245{ 2246 if ([[aTableColumn identifier] isEqualToString: @"Enabled"]) 2247 return [[o_modulearray objectAtIndex:rowIndex] objectAtIndex:2]; 2248 if ([[aTableColumn identifier] isEqualToString: @"Module"]) 2249 return [[o_modulearray objectAtIndex:rowIndex] objectAtIndex:1]; 2250 2251 return nil; 2252} 2253 2254- (void)tableView:(NSTableView *)aTableView setObjectValue:(id)anObject 2255 forTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex 2256{ 2257 [[o_modulearray objectAtIndex:rowIndex] replaceObjectAtIndex:2 2258 withObject: anObject]; 2259} 2260@end 2261 2262@implementation SectionControl 2263 2264- (id)initWithItem:(module_config_t *)p_item 2265 withView:(NSView *)parentView 2266{ 2267 NSRect mainFrame = [parentView frame]; 2268 NSString *labelString, *toolTip; 2269 mainFrame.size.height = 17; 2270 mainFrame.size.width = mainFrame.size.width - LEFTMARGIN - RIGHTMARGIN; 2271 mainFrame.origin.x = LEFTMARGIN; 2272 mainFrame.origin.y = 0; 2273 2274 if (self = [super initWithFrame:mainFrame item:p_item]) { 2275 /* add the label */ 2276 labelString = _NS(p_item->psz_text); 2277 2278 NSDictionary *boldAttributes = [NSDictionary dictionaryWithObjectsAndKeys: 2279 [NSFont boldSystemFontOfSize:[NSFont systemFontSize]], 2280 NSFontAttributeName, 2281 nil]; 2282 NSAttributedString *o_bold_string = [[NSAttributedString alloc] initWithString: labelString attributes: boldAttributes]; 2283 2284 ADD_LABEL(self.label, mainFrame, 1, 0, @"", @"") 2285 [self.label setAttributedStringValue: o_bold_string]; 2286 [self.label sizeToFit]; 2287 2288 [self.label setAutoresizingMask:NSViewNotSizable]; 2289 [self addSubview: self.label]; 2290 } 2291 return self; 2292} 2293 2294@end 2295