Code

family name field on svgfonts dialog now properly saves attribute. Should do the...
[inkscape.git] / src / ui / dialog / input.cpp
index 1400ce93ff0c47b785b27e58acadb31584c352cf..25f1237977508568ed7a9d355067334ac627960f 100644 (file)
@@ -1,7 +1,7 @@
 
 
 /* XPM */
-static char * core_xpm[] = {
+static char const * core_xpm[] = {
 "16 16 4 1",
 "      c None",
 ".     c #808080",
@@ -25,7 +25,7 @@ static char * core_xpm[] = {
 "                "};
 
 /* XPM */
-static char *eraser[] = {
+static char const *eraser[] = {
 /* columns rows colors chars-per-pixel */
 "16 16 5 1",
 "  c black",
@@ -53,7 +53,7 @@ static char *eraser[] = {
 };
 
 /* XPM */
-static char *mouse[] = {
+static char const *mouse[] = {
 /* columns rows colors chars-per-pixel */
 "16 16 3 1",
 "  c black",
@@ -79,7 +79,7 @@ static char *mouse[] = {
 };
 
 /* XPM */
-static char *pen[] = {
+static char const *pen[] = {
 /* columns rows colors chars-per-pixel */
 "16 16 3 1",
 "  c black",
@@ -105,7 +105,7 @@ static char *pen[] = {
 };
 
 /* XPM */
-static char *sidebuttons[] = {
+static char const *sidebuttons[] = {
 /* columns rows colors chars-per-pixel */
 "16 16 4 1",
 "  c black",
@@ -132,7 +132,7 @@ static char *sidebuttons[] = {
 };
 
 /* XPM */
-static char *tablet[] = {
+static char const *tablet[] = {
 /* columns rows colors chars-per-pixel */
 "16 16 3 1",
 "  c black",
@@ -158,7 +158,7 @@ static char *tablet[] = {
 };
 
 /* XPM */
-static char *tip[] = {
+static char const *tip[] = {
 /* columns rows colors chars-per-pixel */
 "16 16 5 1",
 "  c black",
@@ -186,7 +186,7 @@ static char *tip[] = {
 };
 
 /* XPM */
-static char *button_none[] = {
+static char const *button_none[] = {
 /* columns rows colors chars-per-pixel */
 "8 8 3 1",
 "  c black",
@@ -203,7 +203,7 @@ static char *button_none[] = {
 "XXXXXXXX"
 };
 /* XPM */
-static char *button_off[] = {
+static char const *button_off[] = {
 /* columns rows colors chars-per-pixel */
 "8 8 4 1",
 "  c black",
@@ -221,7 +221,7 @@ static char *button_off[] = {
 "oooooooo"
 };
 /* XPM */
-static char *button_on[] = {
+static char const *button_on[] = {
 /* columns rows colors chars-per-pixel */
 "8 8 3 1",
 "  c black",
@@ -239,7 +239,7 @@ static char *button_on[] = {
 };
 
 /* XPM */
-static char * axis_none_xpm[] = {
+static char const * axis_none_xpm[] = {
 "24 8 3 1",
 "      c None",
 ".     c #000000",
@@ -253,7 +253,7 @@ static char * axis_none_xpm[] = {
 "  .++++++++++++++++++.  ",
 "                        "};
 /* XPM */
-static char * axis_off_xpm[] = {
+static char const * axis_off_xpm[] = {
 "24 8 4 1",
 "      c None",
 ".     c #808080",
@@ -268,7 +268,7 @@ static char * axis_off_xpm[] = {
 "  .++++++++++++++++++.  ",
 "                        "};
 /* XPM */
-static char * axis_on_xpm[] = {
+static char const * axis_on_xpm[] = {
 "24 8 3 1",
 "      c None",
 ".     c #000000",
@@ -360,6 +360,7 @@ private:
 
     MyModelColumns cols;
     Glib::RefPtr<Gtk::TreeStore> store;
+    Gtk::TreeIter tabletIter;
     Gtk::TreeView tree;
     Gtk::Frame frame2;
     Gtk::Frame testFrame;
@@ -395,8 +396,16 @@ private:
     void linkComboChanged();
     void resyncToSelection();
     void handleDeviceChange(const Glib::RefPtr<InputDevice>& device);
+    void updateDeviceAxes(const Glib::RefPtr<InputDevice>& device);
     void updateDeviceButtons(const Glib::RefPtr<InputDevice>& device);
     void updateDeviceLinks(const Glib::RefPtr<InputDevice>& device);
+
+    bool findDevice(const Gtk::TreeModel::iterator& iter,
+                    Glib::ustring id,
+                    Gtk::TreeModel::iterator* result);
+    bool findDeviceByLink(const Gtk::TreeModel::iterator& iter,
+                          Glib::ustring link,
+                          Gtk::TreeModel::iterator* result);
 };
 
 
@@ -521,7 +530,7 @@ InputDialogImpl::InputDialogImpl() :
                       ::Gtk::SHRINK);
     rowNum++;
 
-    lbl = Gtk::manage(new Gtk::Label("Reported axes count:"));
+    lbl = Gtk::manage(new Gtk::Label("Axes count:"));
     devDetails.attach(*lbl, 0, 1, rowNum, rowNum+ 1,
                       ::Gtk::FILL,
                       ::Gtk::SHRINK);
@@ -531,6 +540,7 @@ InputDialogImpl::InputDialogImpl() :
 
     rowNum++;
 
+/*
     lbl = Gtk::manage(new Gtk::Label("Actual axes count:"));
     devDetails.attach(*lbl, 0, 1, rowNum, rowNum+ 1,
                       ::Gtk::FILL,
@@ -540,6 +550,7 @@ InputDialogImpl::InputDialogImpl() :
                       ::Gtk::SHRINK);
 
     rowNum++;
+*/
 
     for ( guint barNum = 0; barNum < static_cast<guint>(G_N_ELEMENTS(axesValues)); barNum++ ) {
         lbl = Gtk::manage(new Gtk::Label("axis:"));
@@ -554,7 +565,7 @@ InputDialogImpl::InputDialogImpl() :
         rowNum++;
     }
 
-    lbl = Gtk::manage(new Gtk::Label("Reported button count:"));
+    lbl = Gtk::manage(new Gtk::Label("Button count:"));
     devDetails.attach(*lbl, 0, 1, rowNum, rowNum+ 1,
                       ::Gtk::FILL,
                       ::Gtk::SHRINK);
@@ -630,7 +641,8 @@ InputDialogImpl::InputDialogImpl() :
         row = *(store->append());
         row[cols.description] = "Hardware";
 
-        childrow = *(store->append(row.children()));
+        tabletIter = store->append(row.children());
+        childrow = *tabletIter;
         childrow[cols.description] = "Tablet";
         childrow[cols.thumbnail] = tabletPix;
 
@@ -674,6 +686,7 @@ InputDialogImpl::InputDialogImpl() :
         g_warning("No devices found");
     }
     Inkscape::DeviceManager::getManager().signalDeviceChanged().connect(sigc::mem_fun(*this, &InputDialogImpl::handleDeviceChange));
+    Inkscape::DeviceManager::getManager().signalAxesChanged().connect(sigc::mem_fun(*this, &InputDialogImpl::updateDeviceAxes));
     Inkscape::DeviceManager::getManager().signalButtonsChanged().connect(sigc::mem_fun(*this, &InputDialogImpl::updateDeviceButtons));
     Inkscape::DeviceManager::getManager().signalLinkChanged().connect(sigc::mem_fun(*this, &InputDialogImpl::updateDeviceLinks));
 
@@ -686,6 +699,23 @@ void InputDialogImpl::handleDeviceChange(const Glib::RefPtr<InputDevice>& /*devi
 //     g_message("OUCH!!!! for %p  hits %s", &device, device->getId().c_str());
 }
 
+void InputDialogImpl::updateDeviceAxes(const Glib::RefPtr<InputDevice>& device)
+{
+    gint live = device->getLiveAxes();
+
+    std::map<guint, std::pair<guint, gdouble> > existing = axesMap[device->getId()];
+    gint mask = 0x1;
+    for ( gint num = 0; num < 32; num++, mask <<= 1) {
+        if ( (mask & live) != 0 ) {
+            if ( (existing.find(num) == existing.end()) || (existing[num].first < 2) ) {
+                axesMap[device->getId()][num].first = 2;
+                axesMap[device->getId()][num].second = 0.0;
+            }
+        }
+    }
+    updateTestAxes( device->getId(), 0 );
+}
+
 void InputDialogImpl::updateDeviceButtons(const Glib::RefPtr<InputDevice>& device)
 {
     gint live = device->getLiveButtons();
@@ -701,9 +731,119 @@ void InputDialogImpl::updateDeviceButtons(const Glib::RefPtr<InputDevice>& devic
     updateTestButtons(device->getId(), -1);
 }
 
-void InputDialogImpl::updateDeviceLinks(const Glib::RefPtr<InputDevice>& /*device*/)
+
+bool InputDialogImpl::findDevice(const Gtk::TreeModel::iterator& iter,
+                                 Glib::ustring id,
+                                 Gtk::TreeModel::iterator* result)
+{
+    bool stop = false;
+    const InputDevice* dev = (*iter)[cols.device];
+    if ( dev && (dev->getId() == id) ) {
+        if ( result ) {
+            *result = iter;
+        }
+        stop = true;
+    }
+    return stop;
+}
+
+bool InputDialogImpl::findDeviceByLink(const Gtk::TreeModel::iterator& iter,
+                                       Glib::ustring link,
+                                       Gtk::TreeModel::iterator* result)
+{
+    bool stop = false;
+    const InputDevice* dev = (*iter)[cols.device];
+    if ( dev && (dev->getLink() == link) ) {
+        if ( result ) {
+            *result = iter;
+        }
+        stop = true;
+    }
+    return stop;
+}
+
+void InputDialogImpl::updateDeviceLinks(const Glib::RefPtr<InputDevice>& device)
 {
-//     g_message("Links!!!! for %p  hits %s  with link of %s", &device, device->getId().c_str(), device->getLink().c_str());
+//     g_message("Links!!!! for %p  hits [%s]  with link of [%s]", &device, device->getId().c_str(), device->getLink().c_str());
+    Gtk::TreeModel::iterator deviceIter;
+    store->foreach_iter( sigc::bind<Glib::ustring, Gtk::TreeModel::iterator*>(
+                             sigc::mem_fun(*this, &InputDialogImpl::findDevice),
+                             device->getId(),
+                             &deviceIter) );
+
+    if ( deviceIter ) {
+        // Found the device concerned. Can proceed.
+
+        if ( device->getLink().empty() ) {
+            // is now unlinked
+//             g_message("Item %s is unlinked", device->getId().c_str());
+            if ( deviceIter->parent() != tabletIter ) {
+                // Not the child of the tablet. move on up
+                
+                InputDevice const *dev = (*deviceIter)[cols.device];
+                Glib::ustring descr = (*deviceIter)[cols.description];
+                Glib::RefPtr<Gdk::Pixbuf> thumb = (*deviceIter)[cols.thumbnail];
+
+                Gtk::TreeModel::Row deviceRow = *store->append(tabletIter->children());
+                deviceRow[cols.description] = descr;
+                deviceRow[cols.thumbnail] = thumb;
+                deviceRow[cols.device] = dev;
+
+                Gtk::TreeModel::iterator oldParent = deviceIter->parent();
+                store->erase(deviceIter);
+                if ( oldParent->children().empty() ) {
+                    store->erase(oldParent);
+                }
+            }
+        } else {
+            // is linking
+            if ( deviceIter->parent() == tabletIter ) {
+                // Simple case. Not already linked
+
+                Gtk::TreeIter newGroup = store->append(tabletIter->children());
+                (*newGroup)[cols.description] = "Pen";
+                (*newGroup)[cols.thumbnail] = penPix;
+
+                InputDevice const *dev = (*deviceIter)[cols.device];
+                Glib::ustring descr = (*deviceIter)[cols.description];
+                Glib::RefPtr<Gdk::Pixbuf> thumb = (*deviceIter)[cols.thumbnail];
+
+                Gtk::TreeModel::Row deviceRow = *store->append(newGroup->children());
+                deviceRow[cols.description] = descr;
+                deviceRow[cols.thumbnail] = thumb;
+                deviceRow[cols.device] = dev;
+
+                
+                Gtk::TreeModel::iterator linkIter;
+                store->foreach_iter( sigc::bind<Glib::ustring, Gtk::TreeModel::iterator*>(
+                                         sigc::mem_fun(*this, &InputDialogImpl::findDeviceByLink),
+                                         device->getId(),
+                                         &linkIter) );
+                if ( linkIter ) {
+                    dev = (*linkIter)[cols.device];
+                    descr = (*linkIter)[cols.description];
+                    thumb = (*linkIter)[cols.thumbnail];
+
+                    deviceRow = *store->append(newGroup->children());
+                    deviceRow[cols.description] = descr;
+                    deviceRow[cols.thumbnail] = thumb;
+                    deviceRow[cols.device] = dev;
+                    Gtk::TreeModel::iterator oldParent = linkIter->parent();
+                    store->erase(linkIter);
+                    if ( oldParent->children().empty() ) {
+                        store->erase(oldParent);
+                    }
+                }
+
+                Gtk::TreeModel::iterator oldParent = deviceIter->parent();
+                store->erase(deviceIter);
+                if ( oldParent->children().empty() ) {
+                    store->erase(oldParent);
+                }
+                tree.expand_row(Gtk::TreePath(newGroup), true);
+            }
+        }
+    }
 }
 
 void InputDialogImpl::linkComboChanged() {
@@ -714,12 +854,17 @@ void InputDialogImpl::linkComboChanged() {
         Glib::ustring val = row[cols.description];
         InputDevice const * dev = row[cols.device];
         if ( dev ) {
-            Glib::ustring linkName = linkCombo.get_active_text();
-            std::list<InputDevice const *> devList = Inkscape::DeviceManager::getManager().getDevices();
-            for ( std::list<InputDevice const *>::const_iterator it = devList.begin(); it != devList.end(); ++it ) {
-                if ( linkName == (*it)->getName() ) {
-                    DeviceManager::getManager().setLinkedTo(dev->getId(), (*it)->getId());
-                    break;
+            if ( linkCombo.get_active_row_number() == 0 ) {
+                // It is the "None" entry
+                DeviceManager::getManager().setLinkedTo(dev->getId(), "");
+            } else {
+                Glib::ustring linkName = linkCombo.get_active_text();
+                std::list<InputDevice const *> devList = Inkscape::DeviceManager::getManager().getDevices();
+                for ( std::list<InputDevice const *>::const_iterator it = devList.begin(); it != devList.end(); ++it ) {
+                    if ( linkName == (*it)->getName() ) {
+                        DeviceManager::getManager().setLinkedTo(dev->getId(), (*it)->getId());
+                        break;
+                    }
                 }
             }
         }
@@ -877,31 +1022,32 @@ void InputDialogImpl::mapAxesValues( Glib::ustring const& key, guint numAxes, gd
 {
     static gdouble epsilon = 0.0001;
     if ( (numAxes > 0) && axes) {
-        for ( guint axesNum = 0; axesNum < numAxes; axesNum++ ) {
+        for ( guint axisNum = 0; axisNum < numAxes; axisNum++ ) {
             // 0 == new, 1 == set value, 2 == changed value, 3 == active
-            gdouble diff = axesMap[key][axesNum].second - axes[axesNum];
-            switch(axesMap[key][axesNum].first) {
+            gdouble diff = axesMap[key][axisNum].second - axes[axisNum];
+            switch(axesMap[key][axisNum].first) {
                 case 0:
                 {
-                    axesMap[key][axesNum].first = 1;
-                    axesMap[key][axesNum].second = axes[axesNum];
+                    axesMap[key][axisNum].first = 1;
+                    axesMap[key][axisNum].second = axes[axisNum];
                 }
                 break;
                 case 1:
                 {
                     if ( (diff > epsilon) || (diff < -epsilon) ) {
-//                         g_message("Axis %d changed on %s]", axesNum, key.c_str());
-                        axesMap[key][axesNum].first = 3;
-                        axesMap[key][axesNum].second = axes[axesNum];
+//                         g_message("Axis %d changed on %s]", axisNum, key.c_str());
+                        axesMap[key][axisNum].first = 3;
+                        axesMap[key][axisNum].second = axes[axisNum];
                         updateTestAxes(key, dev);
+                        DeviceManager::getManager().addAxis(key, axisNum);
                     }
                 }
                 break;
                 case 2:
                 {
                     if ( (diff > epsilon) || (diff < -epsilon) ) {
-                        axesMap[key][axesNum].first = 3;
-                        axesMap[key][axesNum].second = axes[axesNum];
+                        axesMap[key][axisNum].first = 3;
+                        axesMap[key][axisNum].second = axes[axisNum];
                         updateTestAxes(key, dev);
                     }
                 }
@@ -909,9 +1055,9 @@ void InputDialogImpl::mapAxesValues( Glib::ustring const& key, guint numAxes, gd
                 case 3:
                 {
                     if ( (diff > epsilon) || (diff < -epsilon) ) {
-                        axesMap[key][axesNum].second = axes[axesNum];
+                        axesMap[key][axisNum].second = axes[axisNum];
                     } else {
-                        axesMap[key][axesNum].first = 2;
+                        axesMap[key][axisNum].first = 2;
                         updateTestAxes(key, dev);
                     }
                 }