16c333678SFredrik Modeen /* 23672a07eSStephan Aßmus * Copyright 1999-2010 Haiku Inc. All rights reserved. 36c333678SFredrik Modeen * Distributed under the terms of the MIT License. 46c333678SFredrik Modeen * 56c333678SFredrik Modeen * Authors: 66c333678SFredrik Modeen * Jeremy Friesner 76c333678SFredrik Modeen */ 86c333678SFredrik Modeen 96c333678SFredrik Modeen 106c333678SFredrik Modeen #include "ShortcutsSpec.h" 116c333678SFredrik Modeen 126c333678SFredrik Modeen #include <ctype.h> 136c333678SFredrik Modeen #include <stdio.h> 146c333678SFredrik Modeen 15fa1ee6d4SJonas Sundström #include <Beep.h> 163672a07eSStephan Aßmus #include <Catalog.h> 17fa1ee6d4SJonas Sundström #include <Directory.h> 183672a07eSStephan Aßmus #include <Locale.h> 19fa1ee6d4SJonas Sundström #include <NodeInfo.h> 20fa1ee6d4SJonas Sundström #include <Path.h> 216c333678SFredrik Modeen #include <Region.h> 226c333678SFredrik Modeen #include <Window.h> 236c333678SFredrik Modeen 246c333678SFredrik Modeen #include "ColumnListView.h" 256c333678SFredrik Modeen 266c333678SFredrik Modeen #include "BitFieldTesters.h" 27fa1ee6d4SJonas Sundström #include "Colors.h" 286c333678SFredrik Modeen #include "CommandActuators.h" 29fa1ee6d4SJonas Sundström #include "MetaKeyStateMap.h" 306c333678SFredrik Modeen #include "ParseCommandLine.h" 316c333678SFredrik Modeen 32fa1ee6d4SJonas Sundström 336c333678SFredrik Modeen #define CLASS "ShortcutsSpec : " 346c333678SFredrik Modeen 35546208a5SOliver Tappe #undef B_TRANSLATION_CONTEXT 36546208a5SOliver Tappe #define B_TRANSLATION_CONTEXT "ShortcutsSpec" 37fa1ee6d4SJonas Sundström 386c333678SFredrik Modeen const float _height = 20.0f; 396c333678SFredrik Modeen 403672a07eSStephan Aßmus static MetaKeyStateMap sMetaMaps[ShortcutsSpec::NUM_META_COLUMNS]; 416c333678SFredrik Modeen 423672a07eSStephan Aßmus static bool sFontCached = false; 433672a07eSStephan Aßmus static BFont sViewFont; 443672a07eSStephan Aßmus static float sFontHeight; 453672a07eSStephan Aßmus static BBitmap* sActuatorBitmaps[2]; 466c333678SFredrik Modeen 473672a07eSStephan Aßmus const char* ShortcutsSpec::sShiftName; 483672a07eSStephan Aßmus const char* ShortcutsSpec::sControlName; 493672a07eSStephan Aßmus const char* ShortcutsSpec::sOptionName; 503672a07eSStephan Aßmus const char* ShortcutsSpec::sCommandName; 51fa1ee6d4SJonas Sundström 526c333678SFredrik Modeen 536c333678SFredrik Modeen #define ICON_BITMAP_RECT BRect(0.0f, 0.0f, 15.0f, 15.0f) 545788aadfSJérôme Duval #define ICON_BITMAP_SPACE B_RGBA32 556c333678SFredrik Modeen 56fa1ee6d4SJonas Sundström 576c333678SFredrik Modeen // Returns the (pos)'th char in the string, or '\0' if (pos) if off the end of 586c333678SFredrik Modeen // the string 596c333678SFredrik Modeen static char 606c333678SFredrik Modeen GetLetterAt(const char* str, int pos) 616c333678SFredrik Modeen { 623672a07eSStephan Aßmus for (int i = 0; i < pos; i++) { 636c333678SFredrik Modeen if (str[i] == '\0') 646c333678SFredrik Modeen return '\0'; 653672a07eSStephan Aßmus } 666c333678SFredrik Modeen return str[pos]; 676c333678SFredrik Modeen } 686c333678SFredrik Modeen 696c333678SFredrik Modeen 706c333678SFredrik Modeen // Setup the states in a standard manner for a pair of meta-keys. 716c333678SFredrik Modeen static void 726c333678SFredrik Modeen SetupStandardMap(MetaKeyStateMap& map, const char* name, uint32 both, 736c333678SFredrik Modeen uint32 left, uint32 right) 746c333678SFredrik Modeen { 756c333678SFredrik Modeen map.SetInfo(name); 766c333678SFredrik Modeen 776c333678SFredrik Modeen // In this state, neither key may be pressed. 786c333678SFredrik Modeen map.AddState("(None)", new HasBitsFieldTester(0, both)); 796c333678SFredrik Modeen 806c333678SFredrik Modeen // Here, either may be pressed. (Remember both is NOT a 2-bit chord, it's 816c333678SFredrik Modeen // another bit entirely) 826c333678SFredrik Modeen map.AddState("Either", new HasBitsFieldTester(both)); 836c333678SFredrik Modeen 846c333678SFredrik Modeen // Here, only the left may be pressed 856c333678SFredrik Modeen map.AddState("Left", new HasBitsFieldTester(left, right)); 866c333678SFredrik Modeen 876c333678SFredrik Modeen // Here, only the right may be pressed 886c333678SFredrik Modeen map.AddState("Right", new HasBitsFieldTester(right, left)); 896c333678SFredrik Modeen 906c333678SFredrik Modeen // Here, both must be pressed. 916c333678SFredrik Modeen map.AddState("Both", new HasBitsFieldTester(left | right)); 926c333678SFredrik Modeen } 936c333678SFredrik Modeen 946c333678SFredrik Modeen 953672a07eSStephan Aßmus MetaKeyStateMap& 963672a07eSStephan Aßmus GetNthKeyMap(int which) 976c333678SFredrik Modeen { 983672a07eSStephan Aßmus return sMetaMaps[which]; 996c333678SFredrik Modeen } 1006c333678SFredrik Modeen 1016c333678SFredrik Modeen 1026c333678SFredrik Modeen static BBitmap* 1036c333678SFredrik Modeen MakeActuatorBitmap(bool lit) 1046c333678SFredrik Modeen { 1056c333678SFredrik Modeen BBitmap* map = new BBitmap(ICON_BITMAP_RECT, ICON_BITMAP_SPACE, true); 1066c333678SFredrik Modeen const rgb_color yellow = {255, 255, 0}; 1076c333678SFredrik Modeen const rgb_color red = {200, 200, 200}; 1086c333678SFredrik Modeen const rgb_color black = {0, 0, 0}; 1096c333678SFredrik Modeen const BPoint points[10] = { 1106c333678SFredrik Modeen BPoint(8, 0), BPoint(9.8, 5.8), BPoint(16, 5.8), 1116c333678SFredrik Modeen BPoint(11, 9.0), BPoint(13, 16), BPoint(8, 11), 1126c333678SFredrik Modeen BPoint(3, 16), BPoint(5, 9.0), BPoint(0, 5.8), 1136c333678SFredrik Modeen BPoint(6.2, 5.8) }; 1146c333678SFredrik Modeen 1156c333678SFredrik Modeen BView* view = new BView(BRect(0, 0, 16, 16), NULL, B_FOLLOW_ALL_SIDES, 0L); 1166c333678SFredrik Modeen map->AddChild(view); 1176c333678SFredrik Modeen map->Lock(); 1186c333678SFredrik Modeen view->SetHighColor(B_TRANSPARENT_32_BIT); 1196c333678SFredrik Modeen view->FillRect(ICON_BITMAP_RECT); 1206c333678SFredrik Modeen view->SetHighColor(lit ? yellow : red); 1216c333678SFredrik Modeen view->FillPolygon(points, 10); 1226c333678SFredrik Modeen view->SetHighColor(black); 1236c333678SFredrik Modeen view->StrokePolygon(points, 10); 1246c333678SFredrik Modeen map->Unlock(); 1256c333678SFredrik Modeen map->RemoveChild(view); 1266c333678SFredrik Modeen delete view; 1276c333678SFredrik Modeen return map; 1286c333678SFredrik Modeen } 1296c333678SFredrik Modeen 1306c333678SFredrik Modeen 1313672a07eSStephan Aßmus /*static*/ void 1323672a07eSStephan Aßmus ShortcutsSpec::InitializeMetaMaps() 1336c333678SFredrik Modeen { 1343672a07eSStephan Aßmus static bool metaMapsInitialized = false; 1353672a07eSStephan Aßmus if (metaMapsInitialized) 1363672a07eSStephan Aßmus return; 1373672a07eSStephan Aßmus metaMapsInitialized = true; 1383672a07eSStephan Aßmus 1393672a07eSStephan Aßmus _InitModifierNames(); 1403672a07eSStephan Aßmus 1413672a07eSStephan Aßmus SetupStandardMap(sMetaMaps[ShortcutsSpec::SHIFT_COLUMN_INDEX], sShiftName, 1426c333678SFredrik Modeen B_SHIFT_KEY, B_LEFT_SHIFT_KEY, B_RIGHT_SHIFT_KEY); 1436c333678SFredrik Modeen 1443672a07eSStephan Aßmus SetupStandardMap(sMetaMaps[ShortcutsSpec::CONTROL_COLUMN_INDEX], 1453672a07eSStephan Aßmus sControlName, B_CONTROL_KEY, B_LEFT_CONTROL_KEY, B_RIGHT_CONTROL_KEY); 1466c333678SFredrik Modeen 1473672a07eSStephan Aßmus SetupStandardMap(sMetaMaps[ShortcutsSpec::COMMAND_COLUMN_INDEX], 1483672a07eSStephan Aßmus sCommandName, B_COMMAND_KEY, B_LEFT_COMMAND_KEY, B_RIGHT_COMMAND_KEY); 1496c333678SFredrik Modeen 1503672a07eSStephan Aßmus SetupStandardMap(sMetaMaps[ShortcutsSpec::OPTION_COLUMN_INDEX], sOptionName 1516c333678SFredrik Modeen , B_OPTION_KEY, B_LEFT_OPTION_KEY, B_RIGHT_OPTION_KEY); 1526c333678SFredrik Modeen 1533672a07eSStephan Aßmus sActuatorBitmaps[0] = MakeActuatorBitmap(false); 1543672a07eSStephan Aßmus sActuatorBitmaps[1] = MakeActuatorBitmap(true); 1556c333678SFredrik Modeen } 1566c333678SFredrik Modeen 1576c333678SFredrik Modeen 1586c333678SFredrik Modeen ShortcutsSpec::ShortcutsSpec(const char* cmd) 1596c333678SFredrik Modeen : 1606c333678SFredrik Modeen CLVListItem(0, false, false, _height), 1616c333678SFredrik Modeen fCommand(NULL), 1626c333678SFredrik Modeen fTextOffset(0), 1636c333678SFredrik Modeen fBitmap(ICON_BITMAP_RECT, ICON_BITMAP_SPACE), 1646c333678SFredrik Modeen fLastBitmapName(NULL), 1656c333678SFredrik Modeen fBitmapValid(false), 1666c333678SFredrik Modeen fKey(0), 1676c333678SFredrik Modeen fCursorPtsValid(false) 1686c333678SFredrik Modeen { 1696c333678SFredrik Modeen for (int i = 0; i < NUM_META_COLUMNS; i++) 1706c333678SFredrik Modeen fMetaCellStateIndex[i] = 0; 1716c333678SFredrik Modeen SetCommand(cmd); 1726c333678SFredrik Modeen } 1736c333678SFredrik Modeen 1746c333678SFredrik Modeen 1756c333678SFredrik Modeen ShortcutsSpec::ShortcutsSpec(const ShortcutsSpec& from) 1766c333678SFredrik Modeen : 1776c333678SFredrik Modeen CLVListItem(0, false, false, _height), 1786c333678SFredrik Modeen fCommand(NULL), 1796c333678SFredrik Modeen fTextOffset(from.fTextOffset), 1806c333678SFredrik Modeen fBitmap(ICON_BITMAP_RECT, ICON_BITMAP_SPACE), 1816c333678SFredrik Modeen fLastBitmapName(NULL), 1826c333678SFredrik Modeen fBitmapValid(false), 1836c333678SFredrik Modeen fKey(from.fKey), 1846c333678SFredrik Modeen fCursorPtsValid(false) 1856c333678SFredrik Modeen { 1866c333678SFredrik Modeen for (int i = 0; i < NUM_META_COLUMNS; i++) 1876c333678SFredrik Modeen fMetaCellStateIndex[i] = from.fMetaCellStateIndex[i]; 1886c333678SFredrik Modeen 1896c333678SFredrik Modeen SetCommand(from.fCommand); 1906c333678SFredrik Modeen SetSelectedColumn(from.GetSelectedColumn()); 1916c333678SFredrik Modeen } 1926c333678SFredrik Modeen 1936c333678SFredrik Modeen 1946c333678SFredrik Modeen ShortcutsSpec::ShortcutsSpec(BMessage* from) 1956c333678SFredrik Modeen : 1966c333678SFredrik Modeen CLVListItem(0, false, false, _height), 1976c333678SFredrik Modeen fCommand(NULL), 1986c333678SFredrik Modeen fTextOffset(0), 1996c333678SFredrik Modeen fBitmap(ICON_BITMAP_RECT, ICON_BITMAP_SPACE), 2006c333678SFredrik Modeen fLastBitmapName(NULL), 2016c333678SFredrik Modeen fBitmapValid(false), 2026c333678SFredrik Modeen fCursorPtsValid(false) 2036c333678SFredrik Modeen { 2046c333678SFredrik Modeen const char* temp; 2056c333678SFredrik Modeen if (from->FindString("command", &temp) != B_NO_ERROR) { 2063672a07eSStephan Aßmus printf(CLASS); 2073672a07eSStephan Aßmus printf(" Error, no command string in archive BMessage!\n"); 2086c333678SFredrik Modeen temp = ""; 2096c333678SFredrik Modeen } 2106c333678SFredrik Modeen 2116c333678SFredrik Modeen SetCommand(temp); 2126c333678SFredrik Modeen 2133672a07eSStephan Aßmus if (from->FindInt32("key", (int32*) &fKey) != B_NO_ERROR) { 2143672a07eSStephan Aßmus printf(CLASS); 2153672a07eSStephan Aßmus printf(" Error, no key int32 in archive BMessage!\n"); 2163672a07eSStephan Aßmus } 2176c333678SFredrik Modeen 2186c333678SFredrik Modeen for (int i = 0; i < NUM_META_COLUMNS; i++) 2196c333678SFredrik Modeen if (from->FindInt32("mcidx", i, (int32*)&fMetaCellStateIndex[i]) 2203672a07eSStephan Aßmus != B_NO_ERROR) { 2213672a07eSStephan Aßmus printf(CLASS); 2223672a07eSStephan Aßmus printf(" Error, no modifiers int32 in archive BMessage!\n"); 2233672a07eSStephan Aßmus } 2246c333678SFredrik Modeen } 2256c333678SFredrik Modeen 2266c333678SFredrik Modeen 2276c333678SFredrik Modeen void 2286c333678SFredrik Modeen ShortcutsSpec::SetCommand(const char* command) 2296c333678SFredrik Modeen { 2306c333678SFredrik Modeen delete[] fCommand; // out with the old (if any)... 2316c333678SFredrik Modeen fCommandLen = strlen(command) + 1; 2326c333678SFredrik Modeen fCommandNul = fCommandLen - 1; 2336c333678SFredrik Modeen fCommand = new char[fCommandLen]; 2346c333678SFredrik Modeen strcpy(fCommand, command); 2356c333678SFredrik Modeen _UpdateIconBitmap(); 2366c333678SFredrik Modeen } 2376c333678SFredrik Modeen 2386c333678SFredrik Modeen 2396c333678SFredrik Modeen const char* 2406c333678SFredrik Modeen ShortcutsSpec::GetColumnName(int i) 2416c333678SFredrik Modeen { 2423672a07eSStephan Aßmus return sMetaMaps[i].GetName(); 2436c333678SFredrik Modeen } 2446c333678SFredrik Modeen 2456c333678SFredrik Modeen 2466c333678SFredrik Modeen status_t 2476c333678SFredrik Modeen ShortcutsSpec::Archive(BMessage* into, bool deep) const 2486c333678SFredrik Modeen { 2496c333678SFredrik Modeen status_t ret = BArchivable::Archive(into, deep); 2506c333678SFredrik Modeen if (ret != B_NO_ERROR) 2516c333678SFredrik Modeen return ret; 2526c333678SFredrik Modeen 2536c333678SFredrik Modeen into->AddString("class", "ShortcutsSpec"); 2546c333678SFredrik Modeen 2556c333678SFredrik Modeen // These fields are for our prefs panel's benefit only 2566c333678SFredrik Modeen into->AddString("command", fCommand); 2576c333678SFredrik Modeen into->AddInt32("key", fKey); 2586c333678SFredrik Modeen 2596c333678SFredrik Modeen // Assemble a BitFieldTester for the input_server add-on to use... 2606c333678SFredrik Modeen MinMatchFieldTester test(NUM_META_COLUMNS, false); 2616c333678SFredrik Modeen for (int i = 0; i < NUM_META_COLUMNS; i++) { 2626c333678SFredrik Modeen // for easy parsing by prefs applet on load-in 2636c333678SFredrik Modeen into->AddInt32("mcidx", fMetaCellStateIndex[i]); 2643672a07eSStephan Aßmus test.AddSlave(sMetaMaps[i].GetNthStateTester(fMetaCellStateIndex[i])); 2656c333678SFredrik Modeen } 2666c333678SFredrik Modeen 2676c333678SFredrik Modeen BMessage testerMsg; 2686c333678SFredrik Modeen ret = test.Archive(&testerMsg); 2696c333678SFredrik Modeen if (ret != B_NO_ERROR) 2706c333678SFredrik Modeen return ret; 2716c333678SFredrik Modeen 2726c333678SFredrik Modeen into->AddMessage("modtester", &testerMsg); 2736c333678SFredrik Modeen 2746c333678SFredrik Modeen // And also create a CommandActuator for the input_server add-on to execute 2756c333678SFredrik Modeen CommandActuator* act = CreateCommandActuator(fCommand); 2766c333678SFredrik Modeen BMessage actMsg; 2776c333678SFredrik Modeen ret = act->Archive(&actMsg); 2786c333678SFredrik Modeen if (ret != B_NO_ERROR) 2796c333678SFredrik Modeen return ret; 2806c333678SFredrik Modeen delete act; 2816c333678SFredrik Modeen 2826c333678SFredrik Modeen into->AddMessage("act", &actMsg); 2836c333678SFredrik Modeen return ret; 2846c333678SFredrik Modeen } 2856c333678SFredrik Modeen 2866c333678SFredrik Modeen 2876c333678SFredrik Modeen static bool IsValidActuatorName(const char* c); 2886c333678SFredrik Modeen static bool 2896c333678SFredrik Modeen IsValidActuatorName(const char* c) 2906c333678SFredrik Modeen { 2913672a07eSStephan Aßmus return (strcmp(c, B_TRANSLATE("InsertString")) == 0 2923672a07eSStephan Aßmus || strcmp(c, B_TRANSLATE("MoveMouse")) == 0 2933672a07eSStephan Aßmus || strcmp(c, B_TRANSLATE("MoveMouseTo")) == 0 2943672a07eSStephan Aßmus || strcmp(c, B_TRANSLATE("MouseButton")) == 0 2953672a07eSStephan Aßmus || strcmp(c, B_TRANSLATE("LaunchHandler")) == 0 2963672a07eSStephan Aßmus || strcmp(c, B_TRANSLATE("Multi")) == 0 2973672a07eSStephan Aßmus || strcmp(c, B_TRANSLATE("MouseDown")) == 0 2983672a07eSStephan Aßmus || strcmp(c, B_TRANSLATE("MouseUp")) == 0 2993672a07eSStephan Aßmus || strcmp(c, B_TRANSLATE("SendMessage")) == 0 3003672a07eSStephan Aßmus || strcmp(c, B_TRANSLATE("Beep")) == 0); 3016c333678SFredrik Modeen } 3026c333678SFredrik Modeen 3036c333678SFredrik Modeen 3046c333678SFredrik Modeen BArchivable* 3056c333678SFredrik Modeen ShortcutsSpec::Instantiate(BMessage* from) 3066c333678SFredrik Modeen { 3076c333678SFredrik Modeen bool validateOK = false; 3086c333678SFredrik Modeen if (validate_instantiation(from, "ShortcutsSpec")) 3096c333678SFredrik Modeen validateOK = true; 3106c333678SFredrik Modeen else // test the old one. 3116c333678SFredrik Modeen if (validate_instantiation(from, "SpicyKeysSpec")) 3126c333678SFredrik Modeen validateOK = true; 3136c333678SFredrik Modeen 3146c333678SFredrik Modeen if (!validateOK) 3156c333678SFredrik Modeen return NULL; 3166c333678SFredrik Modeen 3176c333678SFredrik Modeen return new ShortcutsSpec(from); 3186c333678SFredrik Modeen } 3196c333678SFredrik Modeen 3206c333678SFredrik Modeen 3216c333678SFredrik Modeen ShortcutsSpec::~ShortcutsSpec() 3226c333678SFredrik Modeen { 3236c333678SFredrik Modeen delete[] fCommand; 3246c333678SFredrik Modeen delete[] fLastBitmapName; 3256c333678SFredrik Modeen } 3266c333678SFredrik Modeen 3276c333678SFredrik Modeen 3286c333678SFredrik Modeen void 3296c333678SFredrik Modeen ShortcutsSpec::_CacheViewFont(BView* owner) 3306c333678SFredrik Modeen { 3313672a07eSStephan Aßmus if (sFontCached == false) { 3323672a07eSStephan Aßmus sFontCached = true; 3333672a07eSStephan Aßmus owner->GetFont(&sViewFont); 3346c333678SFredrik Modeen font_height fh; 3353672a07eSStephan Aßmus sViewFont.GetHeight(&fh); 3363672a07eSStephan Aßmus sFontHeight = fh.ascent - fh.descent; 3376c333678SFredrik Modeen } 3386c333678SFredrik Modeen } 3396c333678SFredrik Modeen 3406c333678SFredrik Modeen 3416c333678SFredrik Modeen void 3426c333678SFredrik Modeen ShortcutsSpec::DrawItemColumn(BView* owner, BRect item_column_rect, 3436c333678SFredrik Modeen int32 column_index, bool columnSelected, bool complete) 3446c333678SFredrik Modeen { 3456c333678SFredrik Modeen const float STRING_COLUMN_LEFT_MARGIN = 25.0f; // 16 for the icon,+9 empty 3466c333678SFredrik Modeen 3476c333678SFredrik Modeen rgb_color color; 3486c333678SFredrik Modeen bool selected = IsSelected(); 3496c333678SFredrik Modeen if (selected) 3506c333678SFredrik Modeen color = columnSelected ? BeBackgroundGrey : BeListSelectGrey; 3516c333678SFredrik Modeen else 3526c333678SFredrik Modeen color = BeInactiveControlGrey; 3536c333678SFredrik Modeen owner->SetLowColor(color); 3546c333678SFredrik Modeen owner->SetDrawingMode(B_OP_COPY); 3556c333678SFredrik Modeen owner->SetHighColor(color); 3566c333678SFredrik Modeen owner->FillRect(item_column_rect); 3576c333678SFredrik Modeen 3586c333678SFredrik Modeen const char* text = GetCellText(column_index); 3596c333678SFredrik Modeen 3606c333678SFredrik Modeen if (text == NULL) 3616c333678SFredrik Modeen return; 3626c333678SFredrik Modeen 363ce59b51cSRene Gollent _CacheViewFont(owner); 364ce59b51cSRene Gollent // Ensure that sViewFont is configured before using it to calculate 365ce59b51cSRene Gollent // widths. The lack of this call was causing the initial display of 366ce59b51cSRene Gollent // columns to be incorrect, with a "jump" as all the columns correct 367ce59b51cSRene Gollent // themselves upon the first column resize. 368ce59b51cSRene Gollent 3693672a07eSStephan Aßmus float textWidth = sViewFont.StringWidth(text); 3706c333678SFredrik Modeen BPoint point; 3716c333678SFredrik Modeen rgb_color lowColor = color; 3726c333678SFredrik Modeen 3736c333678SFredrik Modeen if (column_index == STRING_COLUMN_INDEX) { 3746c333678SFredrik Modeen // left justified 3756c333678SFredrik Modeen point.Set(item_column_rect.left + STRING_COLUMN_LEFT_MARGIN, 3766c333678SFredrik Modeen item_column_rect.top + fTextOffset); 3776c333678SFredrik Modeen 378fa1ee6d4SJonas Sundström item_column_rect.left = point.x; 379fa1ee6d4SJonas Sundström // keep text from drawing into icon area 3806c333678SFredrik Modeen 3816c333678SFredrik Modeen // scroll if too wide 3826c333678SFredrik Modeen float rectWidth = item_column_rect.Width() - STRING_COLUMN_LEFT_MARGIN; 3836c333678SFredrik Modeen float extra = textWidth - rectWidth; 3846c333678SFredrik Modeen if (extra > 0.0f) 3856c333678SFredrik Modeen point.x -= extra; 3866c333678SFredrik Modeen } else { 3876c333678SFredrik Modeen if ((column_index < NUM_META_COLUMNS) && (text[0] == '(')) 3886c333678SFredrik Modeen return; // don't draw for this ... 3896c333678SFredrik Modeen 3906c333678SFredrik Modeen if ((column_index <= NUM_META_COLUMNS) && (text[0] == '\0')) 3916c333678SFredrik Modeen return; // don't draw for this ... 3926c333678SFredrik Modeen 3936c333678SFredrik Modeen // centered 3946c333678SFredrik Modeen point.Set((item_column_rect.left + item_column_rect.right) / 2.0, 3956c333678SFredrik Modeen item_column_rect.top + fTextOffset); 3966c333678SFredrik Modeen _CacheViewFont(owner); 3976c333678SFredrik Modeen point.x -= textWidth / 2.0f; 3986c333678SFredrik Modeen } 3996c333678SFredrik Modeen 4006c333678SFredrik Modeen BRegion Region; 4016c333678SFredrik Modeen Region.Include(item_column_rect); 4026c333678SFredrik Modeen owner->ConstrainClippingRegion(&Region); 4036c333678SFredrik Modeen if (column_index != STRING_COLUMN_INDEX) { 4046c333678SFredrik Modeen const float KEY_MARGIN = 3.0f; 4056c333678SFredrik Modeen const float CORNER_RADIUS = 3.0f; 4066c333678SFredrik Modeen _CacheViewFont(owner); 4076c333678SFredrik Modeen 4086c333678SFredrik Modeen // How about I draw a nice "key" background for this one? 4093672a07eSStephan Aßmus BRect textRect(point.x - KEY_MARGIN, (point.y-sFontHeight) - KEY_MARGIN 4106c333678SFredrik Modeen , point.x + textWidth + KEY_MARGIN - 2.0f, point.y + KEY_MARGIN); 4116c333678SFredrik Modeen 4126c333678SFredrik Modeen if (column_index == KEY_COLUMN_INDEX) 4136c333678SFredrik Modeen lowColor = ReallyLightPurple; 4146c333678SFredrik Modeen else 4156c333678SFredrik Modeen lowColor = LightYellow; 4166c333678SFredrik Modeen 4176c333678SFredrik Modeen owner->SetHighColor(lowColor); 4186c333678SFredrik Modeen owner->FillRoundRect(textRect, CORNER_RADIUS, CORNER_RADIUS); 4196c333678SFredrik Modeen owner->SetHighColor(Black); 4206c333678SFredrik Modeen owner->StrokeRoundRect(textRect, CORNER_RADIUS, CORNER_RADIUS); 4216c333678SFredrik Modeen } 4226c333678SFredrik Modeen 4236c333678SFredrik Modeen owner->SetHighColor(Black); 4246c333678SFredrik Modeen owner->SetLowColor(lowColor); 4256c333678SFredrik Modeen owner->DrawString(text, point); 4266c333678SFredrik Modeen // with a cursor at the end if highlighted 4276c333678SFredrik Modeen if (column_index == STRING_COLUMN_INDEX) { 4286c333678SFredrik Modeen // Draw cursor 4296c333678SFredrik Modeen if ((columnSelected) && (selected)) { 4306c333678SFredrik Modeen point.x += textWidth; 4316c333678SFredrik Modeen point.y += (fTextOffset / 4.0f); 4326c333678SFredrik Modeen 4336c333678SFredrik Modeen BPoint pt2 = point; 4346c333678SFredrik Modeen pt2.y -= fTextOffset; 4356c333678SFredrik Modeen owner->StrokeLine(point, pt2); 4366c333678SFredrik Modeen 4376c333678SFredrik Modeen fCursorPt1 = point; 4386c333678SFredrik Modeen fCursorPt2 = pt2; 4396c333678SFredrik Modeen fCursorPtsValid = true; 4406c333678SFredrik Modeen } 4416c333678SFredrik Modeen 4426c333678SFredrik Modeen BRegion bitmapRegion; 4436c333678SFredrik Modeen item_column_rect.left -= (STRING_COLUMN_LEFT_MARGIN - 4.0f); 4446c333678SFredrik Modeen item_column_rect.right = item_column_rect.left + 16.0f; 4456c333678SFredrik Modeen item_column_rect.top += 3.0f; 4466c333678SFredrik Modeen item_column_rect.bottom = item_column_rect.top + 16.0f; 4476c333678SFredrik Modeen 4486c333678SFredrik Modeen bitmapRegion.Include(item_column_rect); 4496c333678SFredrik Modeen owner->ConstrainClippingRegion(&bitmapRegion); 4505788aadfSJérôme Duval owner->SetDrawingMode(B_OP_ALPHA); 4516c333678SFredrik Modeen 4526c333678SFredrik Modeen if ((fCommand != NULL) && (fCommand[0] == '*')) 4533672a07eSStephan Aßmus owner->DrawBitmap(sActuatorBitmaps[fBitmapValid ? 1 : 0], 4546c333678SFredrik Modeen ICON_BITMAP_RECT, item_column_rect); 4556c333678SFredrik Modeen else 4566c333678SFredrik Modeen // Draw icon, if any 4576c333678SFredrik Modeen if (fBitmapValid) 4586c333678SFredrik Modeen owner->DrawBitmap(&fBitmap, ICON_BITMAP_RECT, 4596c333678SFredrik Modeen item_column_rect); 4606c333678SFredrik Modeen } 4616c333678SFredrik Modeen 4626c333678SFredrik Modeen owner->SetDrawingMode(B_OP_COPY); 4636c333678SFredrik Modeen owner->ConstrainClippingRegion(NULL); 4646c333678SFredrik Modeen } 4656c333678SFredrik Modeen 4666c333678SFredrik Modeen 4676c333678SFredrik Modeen void 4686c333678SFredrik Modeen ShortcutsSpec::Update(BView* owner, const BFont* font) 4696c333678SFredrik Modeen { 4706c333678SFredrik Modeen CLVListItem::Update(owner, font); 4716c333678SFredrik Modeen font_height FontAttributes; 4726c333678SFredrik Modeen be_plain_font->GetHeight(&FontAttributes); 4736c333678SFredrik Modeen float fontHeight = ceil(FontAttributes.ascent) + 4746c333678SFredrik Modeen ceil(FontAttributes.descent); 4756c333678SFredrik Modeen fTextOffset = ceil(FontAttributes.ascent) + (Height() - fontHeight) / 2.0; 4766c333678SFredrik Modeen } 4776c333678SFredrik Modeen 4786c333678SFredrik Modeen 4796c333678SFredrik Modeen const char* 4806c333678SFredrik Modeen ShortcutsSpec::GetCellText(int whichColumn) const 4816c333678SFredrik Modeen { 4826c333678SFredrik Modeen const char* temp = ""; // default 4833672a07eSStephan Aßmus switch(whichColumn) { 4846c333678SFredrik Modeen case KEY_COLUMN_INDEX: 4856c333678SFredrik Modeen { 4866c333678SFredrik Modeen if ((fKey > 0) && (fKey <= 0xFF)) { 4876c333678SFredrik Modeen temp = GetKeyName(fKey); 4886c333678SFredrik Modeen if (temp == NULL) 4896c333678SFredrik Modeen temp = ""; 4906c333678SFredrik Modeen } else if (fKey > 0xFF) { 491*0bbc331fSJérôme Duval sprintf(fScratch, "#%" B_PRIx32, fKey); 4926c333678SFredrik Modeen return fScratch; 4936c333678SFredrik Modeen } 4946c333678SFredrik Modeen break; 4953672a07eSStephan Aßmus } 4966c333678SFredrik Modeen 4976c333678SFredrik Modeen case STRING_COLUMN_INDEX: 4986c333678SFredrik Modeen temp = fCommand; 4996c333678SFredrik Modeen break; 5006c333678SFredrik Modeen 5016c333678SFredrik Modeen default: 5026c333678SFredrik Modeen if ((whichColumn >= 0) && (whichColumn < NUM_META_COLUMNS)) 5033672a07eSStephan Aßmus temp = sMetaMaps[whichColumn].GetNthStateDesc( 5046c333678SFredrik Modeen fMetaCellStateIndex[whichColumn]); 5056c333678SFredrik Modeen break; 5066c333678SFredrik Modeen } 5076c333678SFredrik Modeen return temp; 5086c333678SFredrik Modeen } 5096c333678SFredrik Modeen 5106c333678SFredrik Modeen 5116c333678SFredrik Modeen bool 5126c333678SFredrik Modeen ShortcutsSpec::ProcessColumnMouseClick(int whichColumn) 5136c333678SFredrik Modeen { 5146c333678SFredrik Modeen if ((whichColumn >= 0) && (whichColumn < NUM_META_COLUMNS)) { 5156c333678SFredrik Modeen // same as hitting space for these columns: cycle entry 5166c333678SFredrik Modeen const char temp = B_SPACE; 5176c333678SFredrik Modeen 5186c333678SFredrik Modeen // 3rd arg isn't correct but it isn't read for this case anyway 5196c333678SFredrik Modeen return ProcessColumnKeyStroke(whichColumn, &temp, 0); 5206c333678SFredrik Modeen } 5216c333678SFredrik Modeen return false; 5226c333678SFredrik Modeen } 5236c333678SFredrik Modeen 5246c333678SFredrik Modeen 5256c333678SFredrik Modeen bool 5266c333678SFredrik Modeen ShortcutsSpec::ProcessColumnTextString(int whichColumn, const char* string) 5276c333678SFredrik Modeen { 5286c333678SFredrik Modeen switch(whichColumn) { 5296c333678SFredrik Modeen case STRING_COLUMN_INDEX: 5306c333678SFredrik Modeen SetCommand(string); 5316c333678SFredrik Modeen return true; 5326c333678SFredrik Modeen break; 5336c333678SFredrik Modeen 5346c333678SFredrik Modeen case KEY_COLUMN_INDEX: 5356c333678SFredrik Modeen { 5366c333678SFredrik Modeen fKey = FindKeyCode(string); 5376c333678SFredrik Modeen return true; 5386c333678SFredrik Modeen break; 5396c333678SFredrik Modeen } 5406c333678SFredrik Modeen 5416c333678SFredrik Modeen default: 5426c333678SFredrik Modeen return ProcessColumnKeyStroke(whichColumn, string, 0); 5436c333678SFredrik Modeen } 5446c333678SFredrik Modeen } 5456c333678SFredrik Modeen 5466c333678SFredrik Modeen 5476c333678SFredrik Modeen bool 5486c333678SFredrik Modeen ShortcutsSpec::_AttemptTabCompletion() 5496c333678SFredrik Modeen { 5506c333678SFredrik Modeen bool ret = false; 5516c333678SFredrik Modeen 5526c333678SFredrik Modeen int32 argc; 5536c333678SFredrik Modeen char** argv = ParseArgvFromString(fCommand, argc); 5546c333678SFredrik Modeen if (argc > 0) { 5556c333678SFredrik Modeen // Try to complete the path partially expressed in the last argument! 5566c333678SFredrik Modeen char* arg = argv[argc - 1]; 5576c333678SFredrik Modeen char* fileFragment = strrchr(arg, '/'); 5586c333678SFredrik Modeen if (fileFragment) { 5596c333678SFredrik Modeen const char* directoryName = (fileFragment == arg) ? "/" : arg; 5606c333678SFredrik Modeen *fileFragment = '\0'; 5616c333678SFredrik Modeen fileFragment++; 5626c333678SFredrik Modeen int fragLen = strlen(fileFragment); 5636c333678SFredrik Modeen 5646c333678SFredrik Modeen BDirectory dir(directoryName); 5656c333678SFredrik Modeen if (dir.InitCheck() == B_NO_ERROR) { 5666c333678SFredrik Modeen BEntry nextEnt; 5676c333678SFredrik Modeen BPath nextPath; 5686c333678SFredrik Modeen BList matchList; 5696c333678SFredrik Modeen int maxEntryLen = 0; 5706c333678SFredrik Modeen 5716c333678SFredrik Modeen // Read in all the files in the directory whose names start 5726c333678SFredrik Modeen // with our fragment. 5736c333678SFredrik Modeen while (dir.GetNextEntry(&nextEnt) == B_NO_ERROR) { 5746c333678SFredrik Modeen if (nextEnt.GetPath(&nextPath) == B_NO_ERROR) { 5756c333678SFredrik Modeen char* filePath = strrchr(nextPath.Path(), '/') + 1; 5766c333678SFredrik Modeen if (strncmp(filePath, fileFragment, fragLen) == 0) { 5776c333678SFredrik Modeen int len = strlen(filePath); 5786c333678SFredrik Modeen if (len > maxEntryLen) 5796c333678SFredrik Modeen maxEntryLen = len; 5806c333678SFredrik Modeen char* newStr = new char[len + 1]; 5816c333678SFredrik Modeen strcpy(newStr, filePath); 5826c333678SFredrik Modeen matchList.AddItem(newStr); 5836c333678SFredrik Modeen } 5846c333678SFredrik Modeen } 5856c333678SFredrik Modeen } 5866c333678SFredrik Modeen 5876c333678SFredrik Modeen // Now slowly extend our keyword to its full length, counting 5886c333678SFredrik Modeen // numbers of matches at each step. If the match list length 5896c333678SFredrik Modeen // is 1, we can use that whole entry. If it's greater than one 5906c333678SFredrik Modeen // , we can use just the match length. 5916c333678SFredrik Modeen int matchLen = matchList.CountItems(); 5926c333678SFredrik Modeen if (matchLen > 0) { 5936c333678SFredrik Modeen int i; 5946c333678SFredrik Modeen BString result(fileFragment); 5956c333678SFredrik Modeen for (i = fragLen; i < maxEntryLen; i++) { 5966c333678SFredrik Modeen // See if all the matching entries have the same letter 5976c333678SFredrik Modeen // in the next position... if so, we can go farther. 5986c333678SFredrik Modeen char commonLetter = '\0'; 5996c333678SFredrik Modeen for (int j = 0; j < matchLen; j++) { 6006c333678SFredrik Modeen char nextLetter = GetLetterAt( 6016c333678SFredrik Modeen (char*)matchList.ItemAt(j), i); 6026c333678SFredrik Modeen if (commonLetter == '\0') 6036c333678SFredrik Modeen commonLetter = nextLetter; 6046c333678SFredrik Modeen 6056c333678SFredrik Modeen if ((commonLetter != '\0') 6066c333678SFredrik Modeen && (commonLetter != nextLetter)) { 6076c333678SFredrik Modeen commonLetter = '\0';// failed; 6086c333678SFredrik Modeen beep(); 6096c333678SFredrik Modeen break; 6106c333678SFredrik Modeen } 6116c333678SFredrik Modeen } 6126c333678SFredrik Modeen if (commonLetter == '\0') 6136c333678SFredrik Modeen break; 6146c333678SFredrik Modeen else 6156c333678SFredrik Modeen result.Append(commonLetter, 1); 6166c333678SFredrik Modeen } 6176c333678SFredrik Modeen 6186c333678SFredrik Modeen // Free all the strings we allocated 6196c333678SFredrik Modeen for (int k = 0; k < matchLen; k++) 6206c333678SFredrik Modeen delete [] ((char*)matchList.ItemAt(k)); 6216c333678SFredrik Modeen 6226c333678SFredrik Modeen DoStandardEscapes(result); 6236c333678SFredrik Modeen 6246c333678SFredrik Modeen BString wholeLine; 6256c333678SFredrik Modeen for (int l = 0; l < argc - 1; l++) { 6266c333678SFredrik Modeen wholeLine += argv[l]; 6276c333678SFredrik Modeen wholeLine += " "; 6286c333678SFredrik Modeen } 6296c333678SFredrik Modeen 6306c333678SFredrik Modeen BString file(directoryName); 6316c333678SFredrik Modeen DoStandardEscapes(file); 6326c333678SFredrik Modeen 6336c333678SFredrik Modeen if (directoryName[strlen(directoryName) - 1] != '/') 6346c333678SFredrik Modeen file += "/"; 6356c333678SFredrik Modeen 6366c333678SFredrik Modeen file += result; 6376c333678SFredrik Modeen 6386c333678SFredrik Modeen // Remove any trailing slash... 6396c333678SFredrik Modeen const char* fileStr = file.String(); 6406c333678SFredrik Modeen if (fileStr[strlen(fileStr)-1] == '/') 6416c333678SFredrik Modeen file.RemoveLast("/"); 6426c333678SFredrik Modeen 6436c333678SFredrik Modeen // And re-append it iff the file is a dir. 6446c333678SFredrik Modeen BDirectory testFileAsDir(file.String()); 6456c333678SFredrik Modeen if ((strcmp(file.String(), "/") != 0) 6466c333678SFredrik Modeen && (testFileAsDir.InitCheck() == B_NO_ERROR)) 6476c333678SFredrik Modeen file.Append("/"); 6486c333678SFredrik Modeen 6496c333678SFredrik Modeen wholeLine += file; 6506c333678SFredrik Modeen 6516c333678SFredrik Modeen SetCommand(wholeLine.String()); 6526c333678SFredrik Modeen ret = true; 6536c333678SFredrik Modeen } 6546c333678SFredrik Modeen } 6556c333678SFredrik Modeen *(fileFragment - 1) = '/'; 6566c333678SFredrik Modeen } 6576c333678SFredrik Modeen } 6586c333678SFredrik Modeen FreeArgv(argv); 6596c333678SFredrik Modeen return ret; 6606c333678SFredrik Modeen } 6616c333678SFredrik Modeen 6626c333678SFredrik Modeen 6636c333678SFredrik Modeen bool 6646c333678SFredrik Modeen ShortcutsSpec::ProcessColumnKeyStroke(int whichColumn, const char* bytes, 6656c333678SFredrik Modeen int32 key) 6666c333678SFredrik Modeen { 6676c333678SFredrik Modeen bool ret = false; 6686c333678SFredrik Modeen switch(whichColumn) { 6696c333678SFredrik Modeen case KEY_COLUMN_INDEX: 6703672a07eSStephan Aßmus if (key > -1) { 6713672a07eSStephan Aßmus if ((int32)fKey != key) { 6726c333678SFredrik Modeen fKey = key; 6736c333678SFredrik Modeen ret = true; 6746c333678SFredrik Modeen } 6756c333678SFredrik Modeen } 6766c333678SFredrik Modeen break; 6776c333678SFredrik Modeen 6786c333678SFredrik Modeen case STRING_COLUMN_INDEX: 6796c333678SFredrik Modeen { 6806c333678SFredrik Modeen switch(bytes[0]) { 6816c333678SFredrik Modeen case B_BACKSPACE: 6826c333678SFredrik Modeen case B_DELETE: 6836c333678SFredrik Modeen if (fCommandNul > 0) { 6846c333678SFredrik Modeen // trim a char off the string 6856c333678SFredrik Modeen fCommand[fCommandNul - 1] = '\0'; 6866c333678SFredrik Modeen fCommandNul--; // note new nul position 6876c333678SFredrik Modeen ret = true; 6886c333678SFredrik Modeen _UpdateIconBitmap(); 6896c333678SFredrik Modeen } 6906c333678SFredrik Modeen break; 6916c333678SFredrik Modeen 6926c333678SFredrik Modeen case B_TAB: 6936c333678SFredrik Modeen if (_AttemptTabCompletion()) { 6946c333678SFredrik Modeen _UpdateIconBitmap(); 6956c333678SFredrik Modeen ret = true; 6966c333678SFredrik Modeen } else 6976c333678SFredrik Modeen beep(); 6986c333678SFredrik Modeen break; 6996c333678SFredrik Modeen 7006c333678SFredrik Modeen default: 7016c333678SFredrik Modeen { 702529fd9afSOliver Tappe uint32 newCharLen = strlen(bytes); 7036c333678SFredrik Modeen if ((newCharLen > 0) && (bytes[0] >= ' ')) { 7046c333678SFredrik Modeen bool reAllocString = false; 7056c333678SFredrik Modeen // Make sure we have enough room in our command string 7066c333678SFredrik Modeen // to add these chars... 707529fd9afSOliver Tappe while (fCommandLen - fCommandNul <= newCharLen) { 7086c333678SFredrik Modeen reAllocString = true; 7096c333678SFredrik Modeen // enough for a while... 7106c333678SFredrik Modeen fCommandLen = (fCommandLen + 10) * 2; 7116c333678SFredrik Modeen } 7126c333678SFredrik Modeen 7136c333678SFredrik Modeen if (reAllocString) { 7146c333678SFredrik Modeen char* temp = new char[fCommandLen]; 7156c333678SFredrik Modeen strcpy(temp, fCommand); 7166c333678SFredrik Modeen delete [] fCommand; 7176c333678SFredrik Modeen fCommand = temp; 7186c333678SFredrik Modeen // fCommandNul is still valid since it's an offset 7196c333678SFredrik Modeen // and the string length is the same for now 7206c333678SFredrik Modeen } 7216c333678SFredrik Modeen 7226c333678SFredrik Modeen // Here we should be guaranteed enough room. 7236c333678SFredrik Modeen strncat(fCommand, bytes, fCommandLen); 7246c333678SFredrik Modeen fCommandNul += newCharLen; 7256c333678SFredrik Modeen ret = true; 7266c333678SFredrik Modeen _UpdateIconBitmap(); 7276c333678SFredrik Modeen } 7286c333678SFredrik Modeen } 7296c333678SFredrik Modeen } 7306c333678SFredrik Modeen break; 7313672a07eSStephan Aßmus } 7326c333678SFredrik Modeen 7336c333678SFredrik Modeen default: 7346c333678SFredrik Modeen if ((whichColumn >= 0) && (whichColumn < NUM_META_COLUMNS)) { 7353672a07eSStephan Aßmus MetaKeyStateMap * map = &sMetaMaps[whichColumn]; 7366c333678SFredrik Modeen int curState = fMetaCellStateIndex[whichColumn]; 7376c333678SFredrik Modeen int origState = curState; 7386c333678SFredrik Modeen int numStates = map->GetNumStates(); 7396c333678SFredrik Modeen 7406c333678SFredrik Modeen switch(bytes[0]) 7416c333678SFredrik Modeen { 7426c333678SFredrik Modeen case B_RETURN: 7436c333678SFredrik Modeen // cycle to the previous state 7446c333678SFredrik Modeen curState = (curState + numStates - 1) % numStates; 7456c333678SFredrik Modeen break; 7466c333678SFredrik Modeen 7476c333678SFredrik Modeen case B_SPACE: 7486c333678SFredrik Modeen // cycle to the next state 7496c333678SFredrik Modeen curState = (curState + 1) % numStates; 7506c333678SFredrik Modeen break; 7516c333678SFredrik Modeen 7526c333678SFredrik Modeen default: 7536c333678SFredrik Modeen { 7546c333678SFredrik Modeen // Go to the state starting with the given letter, if 7556c333678SFredrik Modeen // any 7566c333678SFredrik Modeen char letter = bytes[0]; 7576c333678SFredrik Modeen if (islower(letter)) 7586c333678SFredrik Modeen letter = toupper(letter); // convert to upper case 7596c333678SFredrik Modeen 7606c333678SFredrik Modeen if ((letter == B_BACKSPACE) || (letter == B_DELETE)) 761fa1ee6d4SJonas Sundström letter = '('; 762fa1ee6d4SJonas Sundström // so space bar will blank out an entry 7636c333678SFredrik Modeen 7646c333678SFredrik Modeen for (int i = 0; i < numStates; i++) { 7656c333678SFredrik Modeen const char* desc = map->GetNthStateDesc(i); 7666c333678SFredrik Modeen 7676c333678SFredrik Modeen if (desc) { 7686c333678SFredrik Modeen if (desc[0] == letter) { 7696c333678SFredrik Modeen curState = i; 7706c333678SFredrik Modeen break; 7716c333678SFredrik Modeen } 7726c333678SFredrik Modeen } else 7733672a07eSStephan Aßmus printf(B_TRANSLATE("Error, NULL state description?\n")); 7746c333678SFredrik Modeen } 7756c333678SFredrik Modeen break; 7766c333678SFredrik Modeen } 7773672a07eSStephan Aßmus } 7786c333678SFredrik Modeen fMetaCellStateIndex[whichColumn] = curState; 7796c333678SFredrik Modeen 7806c333678SFredrik Modeen if (curState != origState) 7816c333678SFredrik Modeen ret = true; 7826c333678SFredrik Modeen } 7836c333678SFredrik Modeen break; 7846c333678SFredrik Modeen } 7856c333678SFredrik Modeen 7866c333678SFredrik Modeen return ret; 7876c333678SFredrik Modeen } 7886c333678SFredrik Modeen 7896c333678SFredrik Modeen 7906c333678SFredrik Modeen int 791fa1ee6d4SJonas Sundström ShortcutsSpec::MyCompare(const CLVListItem* a_Item1, const CLVListItem* a_Item2, 792fa1ee6d4SJonas Sundström int32 KeyColumn) 7936c333678SFredrik Modeen { 7946c333678SFredrik Modeen ShortcutsSpec* left = (ShortcutsSpec*) a_Item1; 7956c333678SFredrik Modeen ShortcutsSpec* right = (ShortcutsSpec*) a_Item2; 7966c333678SFredrik Modeen 7976c333678SFredrik Modeen int ret = strcmp(left->GetCellText(KeyColumn), 7986c333678SFredrik Modeen right->GetCellText(KeyColumn)); 7996c333678SFredrik Modeen return (ret > 0) ? 1 : ((ret == 0) ? 0 : -1); 8006c333678SFredrik Modeen } 8016c333678SFredrik Modeen 8026c333678SFredrik Modeen 8036c333678SFredrik Modeen void 8046c333678SFredrik Modeen ShortcutsSpec::Pulse(BView* owner) 8056c333678SFredrik Modeen { 8066c333678SFredrik Modeen if ((fCursorPtsValid)&&(owner->Window()->IsActive())) { 8076c333678SFredrik Modeen rgb_color prevColor = owner->HighColor(); 8086c333678SFredrik Modeen rgb_color backgroundColor = (GetSelectedColumn() == 8096c333678SFredrik Modeen STRING_COLUMN_INDEX) ? BeBackgroundGrey : BeListSelectGrey; 8106c333678SFredrik Modeen rgb_color barColor = ((GetSelectedColumn() == STRING_COLUMN_INDEX) 8116c333678SFredrik Modeen && ((system_time() % 1000000) > 500000)) ? Black : backgroundColor; 8126c333678SFredrik Modeen owner->SetHighColor(barColor); 8136c333678SFredrik Modeen owner->StrokeLine(fCursorPt1, fCursorPt2); 8146c333678SFredrik Modeen owner->SetHighColor(prevColor); 8156c333678SFredrik Modeen } 8166c333678SFredrik Modeen } 8176c333678SFredrik Modeen 8186c333678SFredrik Modeen 8196c333678SFredrik Modeen void 8206c333678SFredrik Modeen ShortcutsSpec::_UpdateIconBitmap() 8216c333678SFredrik Modeen { 8226c333678SFredrik Modeen BString firstWord = ParseArgvZeroFromString(fCommand); 8236c333678SFredrik Modeen 8246c333678SFredrik Modeen // Only need to change if the first word has changed... 8253672a07eSStephan Aßmus if (fLastBitmapName == NULL || firstWord.Length() == 0 8263672a07eSStephan Aßmus || firstWord.Compare(fLastBitmapName)) { 8276c333678SFredrik Modeen if (firstWord.ByteAt(0) == '*') 8286c333678SFredrik Modeen fBitmapValid = IsValidActuatorName(&firstWord.String()[1]); 8296c333678SFredrik Modeen else { 8306c333678SFredrik Modeen fBitmapValid = false; // default till we prove otherwise! 8316c333678SFredrik Modeen 8326c333678SFredrik Modeen if (firstWord.Length() > 0) { 8336c333678SFredrik Modeen delete [] fLastBitmapName; 8346c333678SFredrik Modeen fLastBitmapName = new char[firstWord.Length() + 1]; 8356c333678SFredrik Modeen strcpy(fLastBitmapName, firstWord.String()); 8366c333678SFredrik Modeen 8376c333678SFredrik Modeen BEntry progEntry(fLastBitmapName, true); 8386c333678SFredrik Modeen if ((progEntry.InitCheck() == B_NO_ERROR) 8396c333678SFredrik Modeen && (progEntry.Exists())) { 8406c333678SFredrik Modeen BNode progNode(&progEntry); 8416c333678SFredrik Modeen if (progNode.InitCheck() == B_NO_ERROR) { 8426c333678SFredrik Modeen BNodeInfo progNodeInfo(&progNode); 8436c333678SFredrik Modeen if ((progNodeInfo.InitCheck() == B_NO_ERROR) 8446c333678SFredrik Modeen && (progNodeInfo.GetTrackerIcon(&fBitmap, B_MINI_ICON) 8453672a07eSStephan Aßmus == B_NO_ERROR)) { 8466c333678SFredrik Modeen fBitmapValid = fBitmap.IsValid(); 8476c333678SFredrik Modeen } 8486c333678SFredrik Modeen } 8496c333678SFredrik Modeen } 8506c333678SFredrik Modeen } 8516c333678SFredrik Modeen } 8526c333678SFredrik Modeen } 8533672a07eSStephan Aßmus } 8543672a07eSStephan Aßmus 8553672a07eSStephan Aßmus 8563672a07eSStephan Aßmus /*static*/ void 8573672a07eSStephan Aßmus ShortcutsSpec::_InitModifierNames() 8583672a07eSStephan Aßmus { 8593672a07eSStephan Aßmus sShiftName = B_TRANSLATE_COMMENT("Shift", 8603672a07eSStephan Aßmus "Name for modifier on keyboard"); 8613672a07eSStephan Aßmus sControlName = B_TRANSLATE_COMMENT("Control", 8623672a07eSStephan Aßmus "Name for modifier on keyboard"); 8633672a07eSStephan Aßmus // TODO: Wrapping in __INTEL__ define probably won't work to extract catkeys? 8643672a07eSStephan Aßmus #if __INTEL__ 86576f3378cSHumdinger sOptionName = B_TRANSLATE_COMMENT("Option", 8663672a07eSStephan Aßmus "Name for modifier on keyboard"); 8673672a07eSStephan Aßmus sCommandName = B_TRANSLATE_COMMENT("Alt", 8683672a07eSStephan Aßmus "Name for modifier on keyboard"); 8693672a07eSStephan Aßmus #else 8703672a07eSStephan Aßmus sOptionName = B_TRANSLATE_COMMENT("Option", 8713672a07eSStephan Aßmus "Name for modifier on keyboard"); 8723672a07eSStephan Aßmus sCommandName = B_TRANSLATE_COMMENT("Command", 8733672a07eSStephan Aßmus "Name for modifier on keyboard"); 8743672a07eSStephan Aßmus #endif 8753672a07eSStephan Aßmus } 876fa1ee6d4SJonas Sundström 877