src/util.cpp

Go to the documentation of this file.
00001 // Copyright (c) 2003 - 2004 Anselm R. Garbe <anselmg at t-online.de>
00002 // See ../LICENSE.txt for license details.
00003 //
00004 // $Id: util.cpp 7 2007-05-24 11:03:53Z eg1981 $
00005 
00006 extern "C" {
00007 #include <unistd.h>
00008 #include <X11/Xlib.h>
00009 }
00010 
00011 #include <sstream>
00012 #include <iostream>
00013 
00014 #include "util.h"
00015 
00016 #include "action.h"
00017 
00018 #include "rectangle.h"
00019 
00020 Util::Util() {
00021 }
00022 
00023 Util::~Util() {
00024 }
00025 
00026 string Util::lowerCase(string str) {
00027     string input = str;
00028 
00029     for (string::iterator it = input.begin(); it != input.end(); it++) {
00030         *it = tolower(*it);
00031     }
00032 
00033     return input;
00034 }
00035 
00036 bool Util::containsWhitespaces(string str) {
00037 
00038     for (string::iterator it = str.begin(); it != str.end(); it++) {
00039         if (*it == ' ' || *it == '\t') {
00040             return true;
00041         }
00042     }
00043 
00044     return false;
00045 }
00046 
00047 string Util::truncate(string str, char c) {
00048 
00049     string result = "";
00050 
00051     for (string::iterator it = str.begin(); it != str.end(); it++) {
00052         if ((*it != c) && (*it != '\t')) {
00053             result += *it;
00054         }
00055     }
00056 
00057     return result;
00058 }
00059 
00060 string Util::canonicalDir(string path) {
00061     string dir = canonicalPath(path);
00062     unsigned int pos = 0;
00063 
00064     pos = dir.find_last_of('/');
00065     if (pos != string::npos) {
00066         dir = dir.substr(0, pos);
00067     }
00068 
00069     return dir;
00070 }
00071 
00072 string Util::canonicalPath(string file) {
00073 
00074     string result = "";
00075     for (string::iterator it = file.begin(); it != file.end(); it++) {
00076 
00077         if (*it == '~') { // found HOME
00078             char *home = getenv("HOME");
00079             // Note: if home would be 0, NCWM won't have started
00080             // but who knows what boxes there're around :)
00081             if (home == 0) {
00082                 cerr << "ncwm[E " << timestamp() << "]: "
00083                      << "Util::canonicalPath() cannot determine your "
00084                      << "$HOME directory, giving up";
00085                 exit(1);
00086             }
00087 
00088             result += home;
00089         }
00090         else {
00091             result += *it;
00092         }
00093     }
00094     return result;
00095 }
00096 
00097 string Util::encodeEscapes(string str) {
00098     string encoded = "";
00099 
00100     for (string::iterator it = str.begin(); it != str.end(); it++) {
00101         switch (*it) {
00102         case '\\':
00103             encoded += "\\\\";
00104             break;
00105         case '#':
00106             encoded += "\\#";
00107             break;
00108         case '"':
00109             encoded += "\\\"";
00110             break;
00111         case '=':
00112             encoded += "\\=";
00113             break;
00114         default:
00115             encoded += *it;
00116             break;
00117         }
00118     }
00119 
00120     return encoded;
00121 }
00122 
00123 string Util::lastToken(string str, char delim) {
00124 
00125     string result = "";
00126     unsigned int pos = str.find_last_of(delim);
00127 
00128     if (pos != string::npos) {
00129         result = str.substr(pos + 1, str.length() - pos);
00130     }
00131 
00132     return result;
00133 }
00134 
00135 string Util::nthToken(string str, char delim, unsigned int n) {
00136 
00137     unsigned int delimCounter = 1;
00138     string token = "";
00139 
00140     for (string::iterator it = str.begin(); it != str.end(); it++) {
00141 
00142         if (*it == delim) {
00143             delimCounter++;
00144             continue;
00145         }
00146 
00147 
00148         if (delimCounter == n) {
00149             token += *it;
00150         }
00151         else if (delimCounter > n) {
00152             return token; // token ready
00153         }
00154     }
00155 
00156     return token;
00157 }
00158 
00159 char **Util::arguments(string command) {
00160 
00161     string arg = "";
00162     list<const char *> args;
00163 
00164     bool proceed = true;
00165     for (string::iterator it = command.begin(); proceed; it++) {
00166 
00167         proceed = it != command.end();
00168         if (!proceed || (*it == ' ') || (*it == '\t'))
00169         {
00170             if (arg.length() > 0) {
00171                 args.push_back((new string(arg))->c_str());
00172             }
00173             arg = "";
00174         }
00175         else {
00176             arg += *it;
00177         }
00178     }
00179 
00180     const char **result = new const char *[args.size() + 1];
00181     unsigned int i = 0;
00182     for (list<const char *>::iterator it = args.begin();
00183          it != args.end(); it++, i++)
00184     {
00185         result[i] = *it;
00186     }
00187     result[i] = 0;
00188 
00189     return (char **)result;
00190 }
00191 
00192 unsigned int Util::numDigits(unsigned int number)
00193 {
00194     unsigned int n = 0;
00195     do {
00196         ++n; number /= 10;
00197     } while (number);
00198 
00199     return n;
00200 }
00201 
00202 string Util::timestamp() {
00203     static time_t utctime;
00204     static struct tm *todaylocal;
00205     static char timestamp[16];
00206     time(&utctime);
00207     todaylocal = localtime(&utctime);
00208     strftime(timestamp, 16,"%Y%m%d%H%M%S", todaylocal);
00209 
00210     return (string)timestamp;
00211 }
00212 
00213 string Util::stringForButton(unsigned int button) {
00214     ostringstream oss;
00215 
00216     oss << "Button" << button;
00217     return oss.str();
00218 }
00219 
00220 unsigned int Util::buttonForString(string button) {
00221 
00222     if (button.find("Button1") != string::npos) {
00223         return Button1;
00224     }
00225     else if (button.find("Button2") != string::npos) {
00226         return Button2;
00227     }
00228     else if (button.find("Button3") != string::npos) {
00229         return Button3;
00230     }
00231     else if (button.find("Button4") != string::npos) {
00232         return Button4;
00233     }
00234     else if (button.find("Button5") != string::npos) {
00235         return Button5;
00236     }
00237 
00238     return 0;
00239 }
00240 
00241 string Util::stringForModMask(unsigned long modMask) {
00242 
00243     string result = "";
00244     if (modMask & ShiftMask) {
00245         result += "shift + ";
00246     }
00247     if (modMask & LockMask) {
00248         result += "lock + ";
00249     }
00250     if (modMask & ControlMask) {
00251         result += "ctrl + ";
00252     }
00253     if (modMask & Mod1Mask) {
00254         result += "mod1 + ";
00255     }
00256     if (modMask & Mod2Mask) {
00257         result += "mod2 + ";
00258     }
00259     if (modMask & Mod3Mask) {
00260         result += "mod3 + ";
00261     }
00262     if (modMask & Mod4Mask) {
00263         result += "mod4 + ";
00264     }
00265     if (modMask & Mod5Mask) {
00266         result += "mod5 + ";
00267     }
00268     if (!modMask) {
00269         result += "none + ";
00270     }
00271     return result;
00272 }
00273 
00274 unsigned long Util::modMaskForString(string modKeys)
00275 {
00276     unsigned long modMask = 0;
00277     if (modKeys.find("shift") != string::npos) {
00278         modMask |= ShiftMask;
00279     }
00280     if (modKeys.find("lock") != string::npos) {
00281         modMask |= LockMask;
00282     }
00283     if ((modKeys.find("control") != string::npos) ||
00284         (modKeys.find("ctrl") != string::npos)) {
00285         modMask |= ControlMask;
00286     }
00287     if ((modKeys.find("alt") != string::npos) ||
00288         (modKeys.find("mod1") != string::npos)) {
00289         modMask |= Mod1Mask;
00290     }
00291     if (modKeys.find("mod2") != string::npos) {
00292         modMask |= Mod2Mask;
00293     }
00294     if (modKeys.find("mod3") != string::npos) {
00295         modMask |= Mod3Mask;
00296     }
00297     if (modKeys.find("mod4") != string::npos) {
00298         modMask |= Mod4Mask;
00299     }
00300     if (modKeys.find("mod5") != string::npos) {
00301         modMask |= Mod5Mask;
00302     }
00303     return modMask;
00304 }
00305 
00306 unsigned int Util::strToUInt(string str) {
00307 
00308     return atoi(str.c_str());
00309 }
00310 
00311 void Util::fitIntoDirection(int horigin, int hw, int *corigin, int *cw)
00312 {
00313     int horigin1 = horigin;
00314     int horigin2 = horigin + hw;
00315     int corigin1 = *corigin;
00316     int corigin2 = *corigin + *cw;
00317 
00318     if ((corigin1 < horigin1) && (corigin2 <= horigin2)) {
00319         *corigin = horigin;
00320         if (*corigin + *cw > horigin2) {
00321             *cw = hw;
00322         }
00323     }
00324     else if ((corigin1 < horigin1) && (corigin2 > horigin2)) {
00325         *corigin = horigin;
00326         *cw = hw;
00327     }
00328     else if ((corigin1 >= horigin1) && (corigin2 > horigin2)) {
00329         *cw = horigin2 - *corigin;
00330     }
00331 }
00332 
00333 
00334 void Util::fitInto(Rectangle *client, Rectangle *host) {
00335 
00336     int cx = client->x();
00337     int cw = client->width();
00338 
00339     fitIntoDirection(host->x(), host->width(), &cx, &cw);
00340     client->setX(cx);
00341     client->setWidth(cw);
00342 
00343     int cy = client->y();
00344     int ch = client->height();
00345 
00346     fitIntoDirection(host->y(), host->height(), &cy, &ch);
00347     client->setY(cy);
00348     client->setHeight(ch);
00349 }
00350 
00351 Direction Util::dirForString(string str) {
00352 
00353     string dirStr;
00354 
00355     dirStr = lowerCase(str);
00356 
00357     if (dirStr == "left") {
00358         return LEFT;
00359     }
00360     else if (dirStr == "right") {
00361         return RIGHT;
00362     }
00363     else if (dirStr == "up") {
00364         return UP;
00365     }
00366     else {
00367         return DOWN;
00368     }
00369 }
00370 
00371 bool Util::exists(const char *path) {
00372 
00373     return access(path, F_OK) == 0;
00374 }
00375 
00376 string Util::shortenString(string str, unsigned int n) {
00377 
00378     return str.substr(0, n) + "...";
00379 }
00380 
00381 
00382 set<string> Util::stringSplit(string s, string delimiter){
00383     set<string> res;
00384     unsigned int pos = 0;
00385     while (pos != string::npos){
00386         pos = s.find_first_of(delimiter);
00387         res.insert(s.substr(0, pos));
00388         s.erase(0, pos + 1);
00389     }
00390     return(res);
00391 }
00392 
00393 string Util::trimL(string s){
00394     return s.substr(s.find_first_not_of(' '));
00395 }
00396 
00397 
00398 bool Util::isPointWithinRect(unsigned int x, unsigned int y, Rectangle *rect,
00399                         Rectangle *offset)
00400 {
00401     unsigned int offsetX = rect->x();
00402     unsigned int offsetY = rect->y();
00403     if (offset) {
00404         offsetX += offset->x();
00405         offsetY += offset->y();
00406     }
00407 
00408     return ((offsetX <= x) && (offsetY <= y) &&
00409             (offsetX + rect->width() >= x) &&
00410             (offsetY + rect->height() >= y));
00411 }
00412 
00413 
00414 void Util::swapChars(string *str, char from, char to,
00415                        unsigned int *swapCount)
00416 {
00417     for (string::iterator it = str->begin(); it != str->end(); it++) {
00418         if (*it == from) {
00419             *it = to;
00420             if (swapCount) {
00421                 (*swapCount)++;
00422             }
00423         }
00424     }
00425 }
00426 
00427 Direction Util::reverseDir(Direction dir) {
00428     switch (dir) {
00429     case LEFT:
00430         return RIGHT;
00431         break;
00432     case RIGHT:
00433         return LEFT;
00434         break;
00435     case UP:
00436         return DOWN;
00437         break;
00438     case DOWN:
00439         return UP;
00440         break;
00441     case NORTH_WEST:
00442         return SOUTH_EAST;
00443         break;
00444     case NORTH_EAST:
00445         return SOUTH_WEST;
00446         break;
00447     case SOUTH_WEST:
00448         return NORTH_EAST;
00449         break;
00450     case SOUTH_EAST:
00451         return NORTH_WEST;
00452         break;
00453     }
00454     return LEFT;
00455 }
00456 
00457 string Util::get(MSettings *settings, string key) {
00458     MSettings::iterator it = settings->find(key);
00459     return (it != settings->end()) ? (*it).second : "";
00460 }
00461 
00462 void Util::remove(MSettings *settings, string prefix) {
00463 
00464     unsigned int length = prefix.length();
00465     for (MSettings::iterator it = settings->begin();
00466             it != settings->end(); it++)
00467     {
00468         string key = (*it).first;
00469         if (key.length() >= length) {
00470             if (key.substr(0, length) == prefix) {
00471                 settings->erase(it);
00472             }
00473         }
00474     }
00475 }
00476 
00477 Action *Util::get(MBindings *bindings, string key) {
00478     MBindings::iterator it = bindings->find(key);
00479     return (it != bindings->end()) ? (*it).second : 0;
00480 }
00481 
00482 void Util::remove(MBindings *bindings, string prefix) {
00483 
00484     unsigned int length = prefix.length();
00485     for (MBindings::iterator it = bindings->begin();
00486             it != bindings->end(); it++)
00487     {
00488         string key = (*it).first;
00489         if (key.length() >= length) {
00490             if (key.substr(0, length) == prefix) {
00491                 bindings->erase(it);
00492             }
00493         }
00494     }
00495 }

Generated on Thu May 24 15:19:32 2007 for ncwm by  doxygen 1.5.1