util.cpp (10822B)
1 // Copyright (c) 2003 - 2009 Anselm R Garbe <anselm@garbe.us> 2 // See LICENSE for license details. 3 4 extern "C" { 5 #include <unistd.h> 6 #include <stdlib.h> 7 #include <X11/Xlib.h> 8 } 9 10 #include <sstream> 11 #include <iostream> 12 13 #include "util.h" 14 15 #include "action.h" 16 17 #include "rectangle.h" 18 19 Util::Util() { 20 } 21 22 Util::~Util() { 23 } 24 25 string Util::lowerCase(string str) { 26 string input = str; 27 28 for (string::iterator it = input.begin(); it != input.end(); it++) { 29 *it = tolower(*it); 30 } 31 32 return input; 33 } 34 35 bool Util::containsWhitespaces(string str) { 36 37 for (string::iterator it = str.begin(); it != str.end(); it++) { 38 if (*it == ' ' || *it == '\t') { 39 return true; 40 } 41 } 42 43 return false; 44 } 45 46 string Util::truncate(string str, char c) { 47 48 string result = ""; 49 50 for (string::iterator it = str.begin(); it != str.end(); it++) { 51 if ((*it != c) && (*it != '\t')) { 52 result += *it; 53 } 54 } 55 56 return result; 57 } 58 59 string Util::canonicalDir(string path) { 60 string dir = canonicalPath(path); 61 unsigned int pos = 0; 62 63 pos = dir.find_last_of('/'); 64 if (pos != string::npos) { 65 dir = dir.substr(0, pos); 66 } 67 68 return dir; 69 } 70 71 string Util::canonicalPath(string file) { 72 73 string result = ""; 74 for (string::iterator it = file.begin(); it != file.end(); it++) { 75 76 if (*it == '~') { // found HOME 77 char *home = getenv("HOME"); 78 // Note: if home would be 0, WMI won't have started 79 // but who knows what boxes there're around :) 80 if (home == 0) { 81 cerr << "wmi[E " << timestamp() << "]: " 82 << "Util::canonicalPath() cannot determine your " 83 << "$HOME directory, giving up"; 84 exit(1); 85 } 86 87 result += home; 88 } 89 else { 90 result += *it; 91 } 92 } 93 return result; 94 } 95 96 string Util::encodeEscapes(string str) { 97 string encoded = ""; 98 99 for (string::iterator it = str.begin(); it != str.end(); it++) { 100 switch (*it) { 101 case '\\': 102 encoded += "\\\\"; 103 break; 104 case '#': 105 encoded += "\\#"; 106 break; 107 case '"': 108 encoded += "\\\""; 109 break; 110 case '=': 111 encoded += "\\="; 112 break; 113 default: 114 encoded += *it; 115 break; 116 } 117 } 118 119 return encoded; 120 } 121 122 string Util::lastToken(string str, char delim) { 123 124 string result = ""; 125 unsigned int pos = str.find_last_of(delim); 126 127 if (pos != string::npos) { 128 result = str.substr(pos + 1, str.length() - pos); 129 } 130 131 return result; 132 } 133 134 string Util::nthToken(string str, char delim, unsigned int n) { 135 136 unsigned int delimCounter = 1; 137 string token = ""; 138 139 for (string::iterator it = str.begin(); it != str.end(); it++) { 140 141 if (*it == delim) { 142 delimCounter++; 143 continue; 144 } 145 146 147 if (delimCounter == n) { 148 token += *it; 149 } 150 else if (delimCounter > n) { 151 return token; // token ready 152 } 153 } 154 155 return token; 156 } 157 158 char **Util::arguments(string command) { 159 160 string arg = ""; 161 list<const char *> args; 162 163 bool proceed = true; 164 for (string::iterator it = command.begin(); proceed; it++) { 165 166 proceed = it != command.end(); 167 if (!proceed || (*it == ' ') || (*it == '\t')) 168 { 169 if (arg.length() > 0) { 170 args.push_back((new string(arg))->c_str()); 171 } 172 arg = ""; 173 } 174 else { 175 arg += *it; 176 } 177 } 178 179 const char **result = new const char *[args.size() + 1]; 180 unsigned int i = 0; 181 for (list<const char *>::iterator it = args.begin(); 182 it != args.end(); it++, i++) 183 { 184 result[i] = *it; 185 } 186 result[i] = 0; 187 188 return (char **)result; 189 } 190 191 unsigned int Util::numDigits(unsigned int number) 192 { 193 unsigned int n = 0; 194 do { 195 ++n; number /= 10; 196 } while (number); 197 198 return n; 199 } 200 201 string Util::timestamp() { 202 static time_t utctime; 203 static struct tm *todaylocal; 204 static char timestamp[16]; 205 time(&utctime); 206 todaylocal = localtime(&utctime); 207 strftime(timestamp, 16,"%Y%m%d%H%M%S", todaylocal); 208 209 return (string)timestamp; 210 } 211 212 string Util::stringForButton(unsigned int button) { 213 ostringstream oss; 214 215 oss << "Button" << button; 216 return oss.str(); 217 } 218 219 unsigned int Util::buttonForString(string button) { 220 221 if (button.find("Button1") != string::npos) { 222 return Button1; 223 } 224 else if (button.find("Button2") != string::npos) { 225 return Button2; 226 } 227 else if (button.find("Button3") != string::npos) { 228 return Button3; 229 } 230 else if (button.find("Button4") != string::npos) { 231 return Button4; 232 } 233 else if (button.find("Button5") != string::npos) { 234 return Button5; 235 } 236 237 return 0; 238 } 239 240 string Util::stringForModMask(unsigned long modMask) { 241 242 string result = ""; 243 if (modMask & ShiftMask) { 244 result += "shift + "; 245 } 246 if (modMask & LockMask) { 247 result += "lock + "; 248 } 249 if (modMask & ControlMask) { 250 result += "ctrl + "; 251 } 252 if (modMask & Mod1Mask) { 253 result += "mod1 + "; 254 } 255 if (modMask & Mod2Mask) { 256 result += "mod2 + "; 257 } 258 if (modMask & Mod3Mask) { 259 result += "mod3 + "; 260 } 261 if (modMask & Mod4Mask) { 262 result += "mod4 + "; 263 } 264 if (modMask & Mod5Mask) { 265 result += "mod5 + "; 266 } 267 if (!modMask) { 268 result += "none + "; 269 } 270 return result; 271 } 272 273 unsigned long Util::modMaskForString(string modKeys) 274 { 275 unsigned long modMask = 0; 276 if (modKeys.find("shift") != string::npos) { 277 modMask |= ShiftMask; 278 } 279 if (modKeys.find("lock") != string::npos) { 280 modMask |= LockMask; 281 } 282 if ((modKeys.find("control") != string::npos) || 283 (modKeys.find("ctrl") != string::npos)) { 284 modMask |= ControlMask; 285 } 286 if ((modKeys.find("alt") != string::npos) || 287 (modKeys.find("mod1") != string::npos)) { 288 modMask |= Mod1Mask; 289 } 290 if (modKeys.find("mod2") != string::npos) { 291 modMask |= Mod2Mask; 292 } 293 if (modKeys.find("mod3") != string::npos) { 294 modMask |= Mod3Mask; 295 } 296 if (modKeys.find("mod4") != string::npos) { 297 modMask |= Mod4Mask; 298 } 299 if (modKeys.find("mod5") != string::npos) { 300 modMask |= Mod5Mask; 301 } 302 return modMask; 303 } 304 305 unsigned int Util::strToUInt(string str) { 306 307 return atoi(str.c_str()); 308 } 309 310 void Util::fitIntoDirection(int horigin, int hw, int *corigin, int *cw) 311 { 312 int horigin1 = horigin; 313 int horigin2 = horigin + hw; 314 int corigin1 = *corigin; 315 int corigin2 = *corigin + *cw; 316 317 if ((corigin1 < horigin1) && (corigin2 <= horigin2)) { 318 *corigin = horigin; 319 if (*corigin + *cw > horigin2) { 320 *cw = hw; 321 } 322 } 323 else if ((corigin1 < horigin1) && (corigin2 > horigin2)) { 324 *corigin = horigin; 325 *cw = hw; 326 } 327 else if ((corigin1 >= horigin1) && (corigin2 > horigin2)) { 328 *cw = horigin2 - *corigin; 329 } 330 } 331 332 333 void Util::fitInto(Rectangle *client, Rectangle *host) { 334 335 int cx = client->x(); 336 int cw = client->width(); 337 338 fitIntoDirection(host->x(), host->width(), &cx, &cw); 339 client->setX(cx); 340 client->setWidth(cw); 341 342 int cy = client->y(); 343 int ch = client->height(); 344 345 fitIntoDirection(host->y(), host->height(), &cy, &ch); 346 client->setY(cy); 347 client->setHeight(ch); 348 } 349 350 Direction Util::dirForString(string str) { 351 352 string dirStr; 353 354 dirStr = lowerCase(str); 355 356 if (dirStr == "left") { 357 return LEFT; 358 } 359 else if (dirStr == "right") { 360 return RIGHT; 361 } 362 else if (dirStr == "up") { 363 return UP; 364 } 365 else { 366 return DOWN; 367 } 368 } 369 370 bool Util::exists(const char *path) { 371 372 return access(path, F_OK) == 0; 373 } 374 375 string Util::shortenString(string str, unsigned int n) { 376 377 return str.substr(0, n) + "..."; 378 } 379 380 381 set<string> Util::stringSplit(string s, string delimiter){ 382 set<string> res; 383 unsigned int pos = 0; 384 while (pos != string::npos){ 385 pos = s.find_first_of(delimiter); 386 res.insert(s.substr(0, pos)); 387 s.erase(0, pos + 1); 388 } 389 return(res); 390 } 391 392 string Util::trimL(string s){ 393 return s.substr(s.find_first_not_of(' ')); 394 } 395 396 397 bool Util::isPointWithinRect(unsigned int x, unsigned int y, Rectangle *rect, 398 Rectangle *offset) 399 { 400 unsigned int offsetX = rect->x(); 401 unsigned int offsetY = rect->y(); 402 if (offset) { 403 offsetX += offset->x(); 404 offsetY += offset->y(); 405 } 406 407 return ((offsetX <= x) && (offsetY <= y) && 408 (offsetX + rect->width() >= x) && 409 (offsetY + rect->height() >= y)); 410 } 411 412 413 void Util::swapChars(string *str, char from, char to, 414 unsigned int *swapCount) 415 { 416 for (string::iterator it = str->begin(); it != str->end(); it++) { 417 if (*it == from) { 418 *it = to; 419 if (swapCount) { 420 (*swapCount)++; 421 } 422 } 423 } 424 } 425 426 Direction Util::reverseDir(Direction dir) { 427 switch (dir) { 428 case LEFT: 429 return RIGHT; 430 break; 431 case RIGHT: 432 return LEFT; 433 break; 434 case UP: 435 return DOWN; 436 break; 437 case DOWN: 438 return UP; 439 break; 440 case NORTH_WEST: 441 return SOUTH_EAST; 442 break; 443 case NORTH_EAST: 444 return SOUTH_WEST; 445 break; 446 case SOUTH_WEST: 447 return NORTH_EAST; 448 break; 449 case SOUTH_EAST: 450 return NORTH_WEST; 451 break; 452 } 453 return LEFT; 454 } 455 456 string Util::get(MSettings *settings, string key) { 457 MSettings::iterator it = settings->find(key); 458 return (it != settings->end()) ? (*it).second : ""; 459 } 460 461 void Util::remove(MSettings *settings, string prefix) { 462 463 unsigned int length = prefix.length(); 464 for (MSettings::iterator it = settings->begin(); 465 it != settings->end(); it++) 466 { 467 string key = (*it).first; 468 if (key.length() >= length) { 469 if (key.substr(0, length) == prefix) { 470 settings->erase(it); 471 } 472 } 473 } 474 } 475 476 Action *Util::get(MBindings *bindings, string key) { 477 MBindings::iterator it = bindings->find(key); 478 return (it != bindings->end()) ? (*it).second : 0; 479 } 480 481 void Util::remove(MBindings *bindings, string prefix) { 482 483 unsigned int length = prefix.length(); 484 for (MBindings::iterator it = bindings->begin(); 485 it != bindings->end(); it++) 486 { 487 string key = (*it).first; 488 if (key.length() >= length) { 489 if (key.substr(0, length) == prefix) { 490 bindings->erase(it); 491 } 492 } 493 } 494 }