1/* functions.m 2 * Common Cenon functions 3 * 4 * Copyright (C) 1996-2012 by vhf interservice GmbH 5 * Author: Georg Fleischmann 6 * 7 * created: 1996-01-25 8 * modified: 2012-01-05 (NSMenuItem) 9 * 10 * This program is free software; you can redistribute it and/or 11 * modify it under the terms of the vhf Public License as 12 * published by vhf interservice GmbH. Among other things, the 13 * License requires that the copyright notices and this notice 14 * be preserved on all copies. 15 * 16 * This program is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 19 * See the vhf Public License for more details. 20 * 21 * You should have received a copy of the vhf Public License along 22 * with this program; see the file LICENSE. If not, write to vhf. 23 * 24 * vhf interservice GmbH, Im Marxle 3, 72119 Altingen, Germany 25 * eMail: info@vhf.de 26 * http://www.vhf.de 27 */ 28 29#include <AppKit/AppKit.h> 30#include <VHFShared/types.h> 31#include <VHFShared/vhfCommonFunctions.h> 32#include <VHFShared/VHFDictionaryAdditions.h> 33#include "functions.h" 34#include "locations.h" 35 36/* return library paths 37 * modified: 2008-02-28 38 */ 39NSString *localLibrary(void) 40{ 41# if defined(GNUSTEP_BASE_VERSION) || defined(__APPLE__) 42 NSFileManager *fileManager = [NSFileManager defaultManager]; 43 NSString *lPath, *sPath; 44 45 /* we return the local path or the system path, whichever exists - local has priority */ 46 /* "/Library/Application Support/Cenon" */ 47 lPath = vhfPathWithPathComponents( 48 [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSLocalDomainMask, YES) objectAtIndex:0], 49 @"Application Support", APPNAME, nil); 50 if ( lPath && [fileManager fileExistsAtPath:lPath] ) 51 return lPath; 52 /* "/Library/Cenon" (Default) */ 53 lPath = [[NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSLocalDomainMask, YES) objectAtIndex:0] 54 stringByAppendingPathComponent:APPNAME]; 55 if ( lPath && [fileManager fileExistsAtPath:lPath] ) 56 return lPath; 57 /* "/System/Library/Cenon" */ 58 sPath = [[NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSSystemDomainMask, YES) objectAtIndex:0] 59 stringByAppendingPathComponent:APPNAME]; 60 if ( sPath && [fileManager fileExistsAtPath:sPath] ) 61 return sPath; 62 return lPath; 63# else 64 return LOCALLIBRARY; 65# endif 66} 67NSString *userLibrary(void) 68{ 69# if defined(GNUSTEP_BASE_VERSION) || defined(__APPLE__) 70 NSFileManager *fileManager = [NSFileManager defaultManager]; 71 NSString *lPath; 72 73 /* "Library/Application Support/Cenon" */ 74 lPath = vhfPathWithPathComponents( 75 [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) objectAtIndex:0], 76 @"Application Support", APPNAME, nil); 77 if ( lPath && [fileManager fileExistsAtPath:lPath] ) 78 return lPath; 79 /* "Library/Cenon" (Default) */ 80 return [[NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) objectAtIndex:0] 81 stringByAppendingPathComponent:APPNAME]; 82# else 83 return vhfPathWithPathComponents(NSHomeDirectory(), HOMELIBRARY, nil); 84# endif 85} 86 87NSString *localBundlePath(void) 88{ 89# if defined(GNUSTEP_BASE_VERSION) || defined(__APPLE__) 90 return [[NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSLocalDomainMask, YES) objectAtIndex:0] 91 stringByAppendingPathComponent:BUNDLEFOLDER]; 92# else 93 return vhfPathWithPathComponents(@"/LocalLibrary", BUNDLEFOLDER, nil); 94# endif 95} 96NSString *systemBundlePath(void) 97{ 98# if defined(__APPLE__) 99 return nil; // we don't have any business here 100# elif defined(GNUSTEP_BASE_VERSION) 101 return [[NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSSystemDomainMask, YES) objectAtIndex:0] 102 stringByAppendingPathComponent:BUNDLEFOLDER]; 103# else // OpenStep 104 return vhfPathWithPathComponents(@"/NextLibrary", BUNDLEFOLDER, nil); 105# endif 106} 107NSString *userBundlePath(void) 108{ 109# if defined(GNUSTEP_BASE_VERSION) || defined(__APPLE__) 110 return [[NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) objectAtIndex:0] 111 stringByAppendingPathComponent:BUNDLEFOLDER]; 112# else 113 return vhfPathWithPathComponents(NSHomeDirectory(), @"Library", BUNDLEFOLDER, nil); 114# endif 115} 116 117/* 118 * fill the device popup 'devicePopup' with menu cells 119 * containing all devices ".dev" inside the appropriate folder ("Devices/xyz"). 120 * Search the folder 'path' in all library directories. 121 * 122 * begin: 1993-01-17 123 * modified: 2012-03-09 (sub-folders, clean-up, don't add directories with extension) 124 * 2005-11-16 (appendPathComponent) 125 * 126 * popup the popup button 127 * folder the folder 128 * ext the extension of the files 129 * removeIx the index of the first item of the popuplist to be removed 130 */ 131void fillPopup(NSPopUpButton *popup, NSString *folder, NSString *ext, int removeIx, BOOL searchSubFolders) 132{ NSString *path; 133 int i, j, selectedIx = [popup indexOfSelectedItem]; 134 NSFileManager *fileManager = [NSFileManager defaultManager]; 135 136 if (!folder) 137 { [popup setEnabled:NO]; 138 return; 139 } 140 141 /* remove entries from popup list, but keep items before removeIx */ 142 if (removeIx == 0) 143 [popup removeAllItems]; 144 else 145 while ( [popup numberOfItems] > removeIx ) 146 [popup removeItemAtIndex:[popup numberOfItems]-1]; 147 148 /* search the files in several directories 149 * add devices in these folders to popup list 150 */ 151 for (i=0; i < 3 ;i++) 152 { NSArray *array; 153 154 switch ( i ) 155 { 156 case 0: // 1. application bundle 157 path = [[NSBundle mainBundle] resourcePath]; break; 158 case 1: // 2. local library 159 path = localLibrary(); break; 160 case 2: // 3. user local library 161 path = userLibrary(); break; 162 default: 163 path = nil; 164 } 165 if ( ! path ) 166 break; 167 path = [path stringByAppendingPathComponent:folder]; 168 169 array = [fileManager directoryContentsAtPath:path]; 170 for ( j = [array count]-1; j >= 0; j-- ) 171 { NSString *name = [array objectAtIndex:j]; 172 NSString *filePath = [path stringByAppendingPathComponent:name]; 173 BOOL isDir; 174 175 /* A. files directly in folder */ 176 if ( [fileManager fileExistsAtPath:filePath isDirectory:&isDir] && !isDir ) 177 { 178 if ( [name hasSuffix:ext] ) 179 { NSString *title; 180 181 title = [name substringToIndex:[name rangeOfString:ext].location]; 182 if ([popup indexOfItemWithTitle:title] < 0) 183 [popup addItemWithTitle:title]; 184 } 185 } 186 /* B. files in sub-folders */ 187 else if ( searchSubFolders ) // sub-folder 188 { NSString *subpath = vhfPathWithPathComponents(path, name, nil); 189 NSArray *subArray = [fileManager directoryContentsAtPath:subpath]; 190 int s; 191 192 for ( s = [subArray count]-1; s >= 0; s-- ) 193 { NSString *subName = [subArray objectAtIndex:s]; 194 NSString *filePath = [subpath stringByAppendingPathComponent:subName]; 195 196 if ( [subName hasSuffix:ext] && 197 [fileManager fileExistsAtPath:filePath isDirectory:&isDir] && !isDir ) 198 { NSString *title; 199 200 title = [subName substringToIndex:[subName rangeOfString:ext].location]; 201 if ([popup indexOfItemWithTitle:title] < 0) 202 [popup addItemWithTitle:title]; 203 } 204 } 205 } 206 } 207 } 208 sortPopup( popup, removeIx ); 209 210 /* enable popup list when having any entries */ 211 [popup setEnabled:([popup numberOfItems]) ? YES : NO]; 212 if ( [popup numberOfItems] > selectedIx ) 213 [popup selectItemAtIndex:selectedIx]; 214} 215 216BOOL vhfUpdateMenuItem(NSMenuItem *menuItem, NSString *zeroItem, NSString *oneItem, BOOL state) 217{ 218 if (state) 219 { 220 if ([menuItem tag] != 0) 221 { 222 [menuItem setTitleWithMnemonic:zeroItem]; 223 [menuItem setTag:0]; 224 [menuItem setEnabled:NO]; // causes it to get redrawn 225 } 226 } 227 else if ([menuItem tag] != 1) 228 { 229 [menuItem setTitleWithMnemonic:oneItem]; 230 [menuItem setTag:1]; 231 [menuItem setEnabled:NO]; // causes it to get redrawn 232 } 233 return YES; 234} 235 236NSDictionary *dictionaryFromFolder(NSString *folder, NSString *name) 237{ NSDictionary *dict; 238 int i; 239 240 for (i=0; ;i++) 241 { NSString *path; 242 243 if (!i) // application resource directory 244 path = [[NSBundle mainBundle] resourcePath]; 245 else if (i==1) // local library 246 path = localLibrary(); 247 else if (i==2) // user local library 248 path = userLibrary(); 249 else 250 break; 251 path = vhfPathWithPathComponents(path, folder, name, nil); 252 253 if ( (dict = [NSDictionary dictionaryWithContentsOfFile:path]) ) 254 return dict; 255 } 256 257 return nil; 258} 259 260 261/* DEPRECATED: use [document convertToUnit:uValue] 262 * converts a value from internal unit (1/72 inch) to the current unit 263 */ 264float convertToUnit(float value) 265{ 266 switch ( [[NSUserDefaults standardUserDefaults] integerForKey:@"unit"] ) 267 { 268 case UNIT_MM: return (value*25.4/72.0); 269 case UNIT_INCH: return (value / 72.0); 270 case UNIT_POINT: return value; 271 } 272 return value; 273} 274 275/* DEPRECATED: use [document convertFrUnit:iValue] 276 * converts a value from the current unit to internal unit (1/72 inch) 277 */ 278float convertFromUnit(float value) 279{ 280 switch ( [[NSUserDefaults standardUserDefaults] integerForKey:@"unit"] ) 281 { 282 case UNIT_MM: return (value/25.4*72.0); 283 case UNIT_INCH: return (value * 72.0); 284 case UNIT_POINT: return value; 285 } 286 return value; 287} 288 289/* DEPRECATED: use [document convertMMToUnit:mmValue] 290 * converts a value from mm to the current unit 291 */ 292float convertMMToUnit(float value) 293{ 294 switch ( [[NSUserDefaults standardUserDefaults] integerForKey:@"unit"] ) 295 { 296 case UNIT_MM: return value; 297 case UNIT_INCH: return value / 25.4; 298 case UNIT_POINT: return value*72.0/25.4; 299 } 300 return value; 301} 302 303/* DEPRECATED: use [document convertUnitToMM:uValue] 304 * converts a value from the current unit to mm 305 */ 306float convertUnitToMM(float value) 307{ 308 switch ( [[NSUserDefaults standardUserDefaults] integerForKey:@"unit"] ) 309 { 310 case UNIT_MM: return value; 311 case UNIT_INCH: return value * 25.4; 312 case UNIT_POINT: return value/72.0*25.4; 313 } 314 return value; 315} 316 317/* color/string functions 318 */ 319NSString *vhfStringFromRGBColor(NSColor *color) 320{ 321 if (![[color colorSpaceName] isEqualToString:NSCalibratedRGBColorSpace]) 322 color = [color colorUsingColorSpaceName:NSCalibratedRGBColorSpace]; 323 return [NSString stringWithFormat:@"%.3f %.3f %.3f", [color redComponent], [color greenComponent], [color blueComponent]]; 324} 325NSColor *vhfRGBColorFromString(NSString *string) 326{ NSScanner *scanner; 327 float r, g, b; 328 329 if (!string) 330 { NSLog(@"vhfRGBColorFromString(): string != nil expected !"); 331 return nil; 332 } 333 scanner = [NSScanner scannerWithString:string]; 334 [scanner scanFloat:&r]; 335 [scanner scanFloat:&g]; 336 [scanner scanFloat:&b]; 337 return [NSColor colorWithCalibratedRed:r green:g blue:b alpha:1.0]; 338} 339