Back to index

easystroke  0.5.5.1
prefdb.cc
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2008-2009, Thomas Jaeger <ThJaeger@gmail.com>
00003  *
00004  * Permission to use, copy, modify, and/or distribute this software for any
00005  * purpose with or without fee is hereby granted, provided that the above
00006  * copyright notice and this permission notice appear in all copies.
00007  *
00008  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
00009  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
00010  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
00011  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
00012  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
00013  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
00014  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
00015  */
00016 #include "prefdb.h"
00017 #include "main.h"
00018 #include "win.h"
00019 #include <glibmm/i18n.h>
00020 
00021 #include <fstream>
00022 #include <iostream>
00023 #include <boost/archive/text_oarchive.hpp>
00024 #include <boost/archive/text_iarchive.hpp>
00025 #include <boost/serialization/set.hpp>
00026 #include <boost/serialization/vector.hpp>
00027 #include <boost/serialization/map.hpp>
00028 #include <boost/serialization/shared_ptr.hpp>
00029 #include <boost/serialization/export.hpp>
00030 
00031 const ButtonInfo default_button(Button2);
00032 const int default_pressure_threshold = 192;
00033 
00034 PrefDB::PrefDB() :
00035        TimeoutWatcher(5000),
00036        good_state(true),
00037        button(default_button),
00038        trace(TraceDefault),
00039        advanced_ignore(false),
00040        pressure_abort(false),
00041        pressure_threshold(default_pressure_threshold),
00042        proximity(false),
00043        feedback(true),
00044        left_handed(false),
00045        init_timeout(250),
00046        final_timeout(250),
00047        timeout_profile(TimeoutDefault),
00048        timeout_gestures(false),
00049        tray_icon(true),
00050        color(Gdk::Color("#980101")),
00051        trace_width(3),
00052        advanced_popups(true),
00053        scroll_invert(true),
00054        scroll_speed(2.0),
00055        tray_feedback(false),
00056        show_osd(true),
00057        move_back(false)
00058 {}
00059 
00060 template<class Archive> void PrefDB::serialize(Archive & ar, const unsigned int version) {
00061        if (version < 11) {
00062               std::set<std::string> old;
00063               ar & old;
00064               for (std::set<std::string>::iterator i = old.begin(); i != old.end(); i++)
00065                      exceptions.unsafe_ref()[*i] = RButtonInfo();
00066        } else ar & exceptions.unsafe_ref();
00067        if (version < 14) {
00068               double p = 0.5;
00069               ar & p;
00070        }
00071        ar & button.unsafe_ref();
00072        if (version < 2) {
00073               bool help;
00074               ar & help;
00075        }
00076        ar & trace.unsafe_ref();
00077        if (trace.get() == TraceShape)
00078               trace.unsafe_ref() = TraceDefault;
00079        if (version < 3) {
00080               int delay;
00081               ar & delay;
00082        }
00083        if (version == 1) {
00084               ButtonInfo foo;
00085               ar & foo;
00086               ar & foo;
00087               return;
00088        }
00089        if (version < 2) return;
00090        if (version != 6)
00091               ar & advanced_ignore.unsafe_ref();
00092        int radius = 16;
00093        ar & radius;
00094        if (version < 4) return;
00095        bool ignore_grab = false;
00096        ar & ignore_grab;
00097        bool timing_workaround = false;
00098        ar & timing_workaround;
00099        bool show_clicks = false;
00100        ar & show_clicks;
00101        ar & pressure_abort.unsafe_ref();
00102        ar & pressure_threshold.unsafe_ref();
00103        ar & proximity.unsafe_ref();
00104        if (version < 5) return;
00105        ar & feedback.unsafe_ref();
00106        ar & left_handed.unsafe_ref();
00107        ar & init_timeout.unsafe_ref();
00108        ar & final_timeout.unsafe_ref();
00109        if (version < 8) return;
00110        ar & timeout_profile.unsafe_ref();
00111        if (version < 9) return;
00112        ar & timeout_gestures.unsafe_ref();
00113        ar & tray_icon.unsafe_ref();
00114        if (version < 10) return;
00115        ar & excluded_devices.unsafe_ref();
00116        if (version < 12) {
00117               unsigned long c = 0;
00118               ar & c;
00119               color.unsafe_ref().color.set_rgb(257*(c >> 16), 257*((c >> 8) % 256), 257*(c % 256));
00120               return;
00121        } else {
00122               ar & color.unsafe_ref();
00123        }
00124        ar & trace_width.unsafe_ref();
00125        if (version < 13) return;
00126        ar & extra_buttons.unsafe_ref();
00127        ar & advanced_popups.unsafe_ref();
00128        ar & scroll_invert.unsafe_ref();
00129        ar & scroll_speed.unsafe_ref();
00130        ar & tray_feedback.unsafe_ref();
00131        ar & show_osd.unsafe_ref();
00132        if (version < 16) return;
00133        ar & move_back.unsafe_ref();
00134        if (version < 17) return;
00135        ar & device_timeout.unsafe_ref();
00136 }
00137 
00138 void PrefDB::timeout() {
00139        std::string filename = config_dir+"preferences"+prefs_versions[0];
00140        std::string tmp = filename + ".tmp";
00141        try {
00142               std::ofstream ofs(tmp.c_str());
00143               boost::archive::text_oarchive oa(ofs);
00144               const PrefDB *me = this;
00145               oa << *me;
00146               ofs.close();
00147               if (rename(tmp.c_str(), filename.c_str()))
00148                      throw std::runtime_error("rename() failed");
00149               if (verbosity >= 2)
00150                      printf("Saved preferences.\n");
00151        } catch (std::exception &e) {
00152               printf(_("Error: Couldn't save preferences: %s.\n"), e.what());
00153               if (!good_state)
00154                      return;
00155               good_state = false;
00156               error_dialog(Glib::ustring::compose(_( "Couldn't save %1.  Your changes will be lost.  "
00157                             "Make sure that \"%2\" is a directory and that you have write access to it.  "
00158                             "You can change the configuration directory "
00159                             "using the -c or --config-dir command line options."), _("preferences"), config_dir));
00160        }
00161 }
00162 
00163 
00164 bool ButtonInfo::overlap(const ButtonInfo &bi) const {
00165        if (button != bi.button)
00166               return false;
00167        if (state == AnyModifier || bi.state == AnyModifier)
00168               return true;
00169        return !((state ^ bi.state) & ~LockMask & ~Mod2Mask);
00170 }
00171 
00172 void PrefDB::init() {
00173        std::string filename = config_dir+"preferences";
00174        for (const char **v = prefs_versions; *v; v++) {
00175               if (is_file(filename + *v)) {
00176                      filename += *v;
00177                      try {
00178                             std::ifstream ifs(filename.c_str(), std::ios::binary);
00179                             if (!ifs.fail()) {
00180                                    boost::archive::text_iarchive ia(ifs);
00181                                    ia >> *this;
00182                                    if (verbosity >= 2)
00183                                           std::cout << "Loaded preferences." << std::endl;
00184                             }
00185                      } catch (...) {
00186                             printf(_("Error: Couldn't read preferences.\n"));
00187                      }
00188                      break;
00189               }
00190        }
00191        std::map<std::string, RButtonInfo>::iterator i = exceptions.unsafe_ref().find("(window manager frame)");
00192        if (i != exceptions.unsafe_ref().end()) {
00193               RButtonInfo bi = i->second;
00194               exceptions.unsafe_ref().erase(i);
00195               exceptions.unsafe_ref()[""] = bi;
00196        }
00197 }
00198 
00199 PrefDB prefs;