From 436f57a29cb5e6e44e87389986bfa1306ed877dd Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Sat, 8 Jun 2019 20:31:59 +0200 Subject: Fixes on selector dialog based in LGM input --- src/ui/dialog/selectordialog.cpp | 583 +++++++++++++++++++++++---------------- src/ui/dialog/selectordialog.h | 15 +- 2 files changed, 352 insertions(+), 246 deletions(-) diff --git a/src/ui/dialog/selectordialog.cpp b/src/ui/dialog/selectordialog.cpp index d44528df1..263851d16 100644 --- a/src/ui/dialog/selectordialog.cpp +++ b/src/ui/dialog/selectordialog.cpp @@ -28,6 +28,7 @@ #include #include +#include #include #include @@ -43,6 +44,8 @@ using Inkscape::XML::AttributeRecord; * parsing is done to update XML style element or row labels in this dialog. */ #define REMOVE_SPACES(x) x.erase(0, x.find_first_not_of(' ')); \ + if(x.size() && x[0] == ',') x.erase(0, 1); \ + if(x.size() && x[x.size()-1] == ',') x.erase(x.size()-1, 1); \ x.erase(x.find_last_not_of(' ') + 1); namespace Inkscape { @@ -181,12 +184,70 @@ SelectorDialog::TreeStore::row_draggable_vfunc(const Gtk::TreeModel::Path& path) if (iter) { Gtk::TreeModel::Row row = *iter; bool is_draggable = - row[_selectordialog->_mColumns._colType] == SELECTOR || row[_selectordialog->_mColumns._colType] == UNHANDLED; + row[_selectordialog->_mColumns._colType] == SELECTOR; return is_draggable; } return Gtk::TreeStore::row_draggable_vfunc(path); } +void +SelectorDialog::fixCSSSelectors(Glib::ustring &selector) +{ + REMOVE_SPACES(selector); + Glib::ustring my_selector = selector + " {"; // Parsing fails sometimes without '{'. Fix me + CRSelector *cr_selector = cr_selector_parse_from_buf ((guchar*)my_selector.c_str(), CR_UTF_8); + selector = Glib::ustring(""); + CRSelector const *cur = nullptr; + for (cur = cr_selector; cur; cur = cur->next) { + if (cur->simple_sel) { + gchar *selectorchar = reinterpret_cast(cr_simple_sel_to_string(cur->simple_sel)); + if (selectorchar) { + Glib::ustring toadd = Glib::ustring(selectorchar); + selector = selector.empty() ? toadd : selector + "," + toadd; + g_free(selectorchar); + } + } + } + std::vector tokens = Glib::Regex::split_simple("[,]+", selector); + std::vector selectorresult; + selector = Glib::ustring(""); + for (auto token : tokens) { + REMOVE_SPACES(token); + std::vector tokensplus = Glib::Regex::split_simple("[ ]+", token); + Glib::ustring selectorpart = Glib::ustring(""); + for (auto tokenplus : tokensplus) { + REMOVE_SPACES(tokenplus); + Glib::ustring toparse = Glib::ustring(tokenplus); + Glib::ustring tag = Glib::ustring(""); + if (toparse[0] != '.' && toparse[0] != '#') { + auto i = std::min(toparse.find("#"), toparse.find(".")); + tag = toparse.substr(0,i); + if (!SPAttributeRelSVG::isSVGElement(tag)) { + continue; + } + if (i != std::string::npos) { + toparse.erase(0, i); + } + } + auto i = toparse.find("#"); + if (i != std::string::npos) { + toparse.erase(i, 1); + } + auto j = toparse.find("#"); + if (i != std::string::npos && j != std::string::npos) { + continue; + } else if (i != std::string::npos) { + toparse.insert(i, "#"); + } + toparse = tag + toparse; + selectorpart = selectorpart == Glib::ustring("") ? toparse : selectorpart + " " + toparse; + } + selectorresult.push_back(selectorpart); + } + for (auto selectorpart : selectorresult) { + selector = selector == Glib::ustring("") ? selectorpart : selector + "," + selectorpart; + } +} /** * Allow dropping only in between other selectors. @@ -242,7 +303,6 @@ SelectorDialog::SelectorDialog() : new Inkscape::UI::Widget::IconRenderer() ); addRenderer->add_icon("edit-delete"); addRenderer->add_icon("list-add"); - addRenderer->add_icon("object-locked"); _store = TreeStore::create(this); _treeView.set_model(_store); @@ -443,20 +503,21 @@ void SelectorDialog::_readStyleElement() } } _store->clear(); - + bool rewrite = false; for (unsigned i = 0; i < tokens.size()-1; i += 2) { Glib::ustring selector = tokens[i]; REMOVE_SPACES(selector); // Remove leading/trailing spaces + Glib::ustring selector_old = selector; + fixCSSSelectors(selector); + if (selector_old != selector) { + rewrite = true; + } + if (selector.empty()) { + continue; + } std::vector tokensplus = Glib::Regex::split_simple("[,]+", selector); coltype colType = SELECTOR; - for (auto tok : tokensplus) { - REMOVE_SPACES(tok); - if (SPAttributeRelSVG::isSVGElement(tok) || tok.find(" ") != -1 || tok[0] == '>' || tok[0] == '+' || - tok[0] == '~' || tok[0] == '*' || tok.erase(0, 1).find(".") != -1) { - colType = UNHANDLED; - } - } // Get list of objects selector matches std::vector objVec = _getObjVec( selector ); @@ -488,7 +549,7 @@ void SelectorDialog::_readStyleElement() Gtk::TreeModel::Row childrow = *(_store->append(row->children())); childrow[_mColumns._colSelector] = "#" + Glib::ustring(obj->getId()); childrow[_mColumns._colExpand] = false; - childrow[_mColumns._colType] = colType == UNHANDLED ? UNHANDLED : OBJECT; + childrow[_mColumns._colType] = colType == OBJECT; ; childrow[_mColumns._colObj] = std::vector(1, obj); childrow[_mColumns._colProperties] = ""; // Unused @@ -498,6 +559,9 @@ void SelectorDialog::_readStyleElement() _updating = false; + if (rewrite) { + _writeStyleElement(); + } } void SelectorDialog::_rowExpand(const Gtk::TreeModel::iterator &iter, const Gtk::TreeModel::Path &path) @@ -537,7 +601,6 @@ void SelectorDialog::_writeStyleElement() } // We could test if styleContent is empty and then delete the style node here but there is no // harm in keeping it around ... - Inkscape::XML::Node *textNode = _getStyleTextNode(); textNode->setContent(styleContent.c_str()); @@ -584,7 +647,75 @@ void SelectorDialog::_updateWatchers() _updating = false; } +/* +void sp_get_selector_active(Glib::ustring &selector) +{ + std::vector tokensplus = Glib::Regex::split_simple("[ ]+", selector); + selector = tokensplus[tokensplus.size() - 1]; + // Erase any comma/space + REMOVE_SPACES(selector); + Glib::ustring toadd = Glib::ustring(selector); + Glib::ustring toparse = Glib::ustring(selector); + Glib::ustring tag = ""; + if (toadd[0] != '.' || toadd[0] != '#') { + auto i = std::min(toadd.find("#"), toadd.find(".")); + tag = toadd.substr(0,i-1); + toparse.erase(0, i-1); + } + auto i = toparse.find("#"); + toparse.erase(i, 1); + auto j = toparse.find("#"); + if (j == std::string::npos) { + selector = ""; + } else if (i != std::string::npos) { + Glib::ustring post = toadd.substr(0,i-1); + Glib::ustring pre = toadd.substr(i, (toadd.size()-1)-i); + selector = tag + pre + post; + } +} */ +Glib::ustring +sp_get_selector_classes(Glib::ustring selector)//, SelectorType selectortype, Glib::ustring id = "") +{ + std::pair result; + std::vector tokensplus = Glib::Regex::split_simple("[ ]+", selector); + selector = tokensplus[tokensplus.size() - 1]; + // Erase any comma/space + REMOVE_SPACES(selector); + Glib::ustring toparse = Glib::ustring(selector); + selector = Glib::ustring(""); + if (toparse[0] != '.' && toparse[0] != '#') { + auto i = std::min(toparse.find("#"), toparse.find(".")); + Glib::ustring tag = toparse.substr(0,i); + if (!SPAttributeRelSVG::isSVGElement(tag)) { + return selector; + } + if (i != std::string::npos) { + toparse.erase(0, i); + } + } + auto i = toparse.find("#"); + if (i != std::string::npos) { + toparse.erase(i, 1); + } + auto j = toparse.find("#"); + if (j != std::string::npos) { + return selector; + } + if (i != std::string::npos) { + toparse.insert(i, "#"); + if (i) { + Glib::ustring post = toparse.substr(0,i); + Glib::ustring pre = toparse.substr(i, toparse.size()-i); + toparse = pre + post; + } + auto k = toparse.find("."); + if (k != std::string::npos) { + toparse = toparse.substr(k, toparse.size()-k); + } + } + return toparse; +} /** * @param row @@ -594,93 +725,63 @@ void SelectorDialog::_addToSelector(Gtk::TreeModel::Row row) { g_debug("SelectorDialog::_addToSelector: Entrance"); if (*row) { - - Glib::ustring selector = row[_mColumns._colSelector]; - - if (selector[0] == '#') { - // 'id' selector... add selected object's id's to list. - Inkscape::Selection* selection = getDesktop()->getSelection(); - for (auto& obj: selection->objects()) { - - Glib::ustring id = (obj->getId()?obj->getId():""); - - std::vector objVec = row[_mColumns._colObj]; - bool found = false; - for (auto& obj: objVec) { - if (id == obj->getId()) { - found = true; - break; + // Store list of selected elements on desktop (not to be confused with selector). + _updating = true; + Inkscape::Selection* selection = getDesktop()->getSelection(); + std::vector toAddObjVec( selection->objects().begin(), + selection->objects().end() ); + Glib::ustring multiselector = row[_mColumns._colSelector]; + std::vector objVec = _getObjVec(multiselector); + row[_mColumns._colObj] = objVec; + row[_mColumns._colExpand] = true; + std::vector tokens = Glib::Regex::split_simple("[,]+", multiselector); + for (auto &obj : toAddObjVec) { + Glib::ustring id = (obj->getId()?obj->getId():""); + for (auto tok : tokens) { + Glib::ustring clases = sp_get_selector_classes(tok); + if (!clases.empty()) { + _insertClass(obj, clases); + std::vector currentobjs = _getObjVec(multiselector); + bool removeclass = true; + for (auto currentobj : currentobjs) { + if (currentobj->getId() == id) { + removeclass = false; + } } - } - - if (!found) { - // Update row - objVec.push_back(obj); // Adding to copy so need to update tree - row[_mColumns._colObj] = objVec; - row[_mColumns._colSelector] = _getIdList( objVec ); - row[_mColumns._colExpand] = true; - // Add child row - Gtk::TreeModel::Row childrow = *(_store->append(row->children())); - childrow[_mColumns._colSelector] = "#" + Glib::ustring(obj->getId()); - childrow[_mColumns._colType] = OBJECT; - childrow[_mColumns._colObj] = std::vector(1, obj); - childrow[_mColumns._colProperties] = ""; // Unused - childrow[_mColumns._colVisible] = true; // Unused - } - } - } - - else if (selector[0] == '.') { - // 'class' selector... add value to class attribute of selected objects. - - // Get first class (split on white space or comma) - std::vector tokens = Glib::Regex::split_simple("[,\\s]+", selector); - Glib::ustring className = tokens[0]; - className.erase(0,1); - Inkscape::Selection* selection = getDesktop()->getSelection(); - std::vector sel_obj(selection->objects().begin(), selection->objects().end()); - _insertClass(sel_obj, className); - std::vector objVec = _getObjVec(selector); - ; - for (auto &obj : sel_obj) { - - Glib::ustring id = (obj->getId() ? obj->getId() : ""); - bool found = false; - for (auto &obj : objVec) { - if (id == obj->getId()) { - found = true; - break; + if (removeclass) { + _removeClass(obj, clases); } } - - if (!found) { - // Update row - objVec.push_back(obj); // Adding to copy so need to update tree - row[_mColumns._colObj] = objVec; - row[_mColumns._colExpand] = true; - - // Update row - Gtk::TreeModel::Row childrow = *(_store->append(row->children())); - childrow[_mColumns._colSelector] = "#" + Glib::ustring(obj->getId()); - childrow[_mColumns._colExpand] = false; - childrow[_mColumns._colType] = OBJECT; - childrow[_mColumns._colObj] = std::vector(1, obj); - childrow[_mColumns._colProperties] = ""; // Unused - childrow[_mColumns._colVisible] = true; // Unused + } + std::vector currentobjs = _getObjVec(multiselector); + bool insertid = true; + for (auto currentobj : currentobjs) { + if (currentobj->getId() == id) { + insertid = false; } } - } + if (insertid) { + multiselector = multiselector + ",#" + id; + } + Gtk::TreeModel::Row childrow = *(_store->append(row->children())); + childrow[_mColumns._colSelector] = "#" + Glib::ustring(id); + childrow[_mColumns._colExpand] = false; + childrow[_mColumns._colType] = OBJECT; + childrow[_mColumns._colObj] = std::vector(1, obj); + childrow[_mColumns._colProperties] = ""; // Unused + childrow[_mColumns._colVisible] = true; // Unused + } + objVec = _getObjVec(multiselector); + row[_mColumns._colSelector] = multiselector; + row[_mColumns._colObj] = objVec; + row[_mColumns._colExpand] = true; + _updating = false; - else { - // Do nothing for element selectors. - // std::cout << " Element selector... doing nothing!" << std::endl; - } + // Add entry to style element + _writeStyleElement(); } - - _writeStyleElement(); } - /** * @param row * Remove the object corresponding to 'row' from the parent selector. @@ -689,76 +790,46 @@ void SelectorDialog::_removeFromSelector(Gtk::TreeModel::Row row) { g_debug("SelectorDialog::_removeFromSelector: Entrance"); if (*row) { - + _updating = true; Glib::ustring objectLabel = row[_mColumns._colSelector]; - if (row[_mColumns._colType] == UNHANDLED) { - return; - }; Gtk::TreeModel::iterator iter = row->parent(); if (iter) { Gtk::TreeModel::Row parent = *iter; - Glib::ustring selector = parent[_mColumns._colSelector]; - REMOVE_SPACES(selector); - if (selector[0] == '#') { - // 'id' selector... remove selected object's id's to list. - - // Erase from selector label. - auto i = selector.find(objectLabel); - if (i != Glib::ustring::npos) { - selector.erase(i, objectLabel.length()); + Glib::ustring multiselector = parent[_mColumns._colSelector]; + REMOVE_SPACES(multiselector); + SPObject *obj = _getObjVec(objectLabel)[0]; + std::vector tokens = Glib::Regex::split_simple("[,]+", multiselector); + Glib::ustring selector = ""; + for (auto tok : tokens) { + if (tok.empty()) { + continue; } - // Erase any comma/space - REMOVE_SPACES(selector); - if (i != Glib::ustring::npos && selector[i] == ',') { - selector.erase(i, 1); - } - if (i != Glib::ustring::npos && selector[i] == ' ') { - selector.erase(i, 1); + // TODO: handle when other selectors has the removed class applied to maybe not remove + Glib::ustring clases = sp_get_selector_classes(tok); + if (!clases.empty()) { + _removeClass(obj, tok, true); } - REMOVE_SPACES(selector); - if (selector[selector.size() - 1] == ',') { - selector.erase(selector.size() - 1, 1); - } - - // Update store - if (selector.empty()) { - _store->erase(parent); - } else { - // Save new selector and update object vector. - parent[_mColumns._colSelector] = selector; - parent[_mColumns._colObj] = _getObjVec( selector ); - parent[_mColumns._colExpand] = true; - _store->erase(row); + auto i = tok.find(row[_mColumns._colSelector]); + if (i == std::string::npos) { + selector = selector.empty()? tok : selector + "," + tok; } } + REMOVE_SPACES(selector); + if (selector.empty()) { + _store->erase(parent); - else if (selector[0] == '.') { - // 'class' selector... remove value to class attribute of selected objects. - - std::vector objVec = row[_mColumns._colObj]; // Just one - // Get first class (split on white space or comma) - std::vector tokens = Glib::Regex::split_simple("[,\\s]+", selector); - Glib::ustring className = tokens[0]; - className.erase(0, 1); - // Erase class name from 'class' attribute. - Glib::ustring classAttr = objVec[0]->getRepr()->attribute("class"); - auto i = classAttr.find( className ); - if (i != Glib::ustring::npos) { - classAttr.erase(i, className.length()); - } - if (i != Glib::ustring::npos && classAttr[i] == ' ') { - classAttr.erase(i, 1); - } - _store->erase(row); - objVec[0]->setAttribute("class", classAttr); - parent[_mColumns._colExpand] = true; } else { - // Do nothing for element selectors. - // std::cout << " Element selector... doing nothing!" << std::endl; + _store->erase(row); + parent[_mColumns._colSelector] = selector; + parent[_mColumns._colExpand] = true; + parent[_mColumns._colObj] = _getObjVec(selector); } } + _updating = false; + + // Add entry to style element + _writeStyleElement(); } - _writeStyleElement(); } @@ -790,24 +861,24 @@ std::vector SelectorDialog::_getObjVec(Glib::ustring selector) { g_debug("SelectorDialog::_getObjVec: | %s |", selector.c_str()); std::vector objVec; std::vector tokensplus = Glib::Regex::split_simple("[,]+", selector); - bool unhandled = false; for (auto tok : tokensplus) { REMOVE_SPACES(tok); - if (SPAttributeRelSVG::isSVGElement(tok) || tok.find(" ") != -1 || tok[0] == '>' || tok[0] == '+' || - tok[0] == '~' || tok[0] == '*' || tok.erase(0, 1).find(".") != -1) { - unhandled = true; - std::vector objVecSplited = SP_ACTIVE_DOCUMENT->getObjectsBySelector(tok); - objVec.insert(objVec.end(), objVecSplited.begin(), objVecSplited.end()); + std::vector objVecSplited = SP_ACTIVE_DOCUMENT->getObjectsBySelector(tok); + for (auto obj : objVecSplited) { + bool insert = true; + for (auto objv : objVec) { + if (objv->getId() == obj->getId()) { + insert = false; + } + } + if (insert) { + objVec.push_back(obj); + } } } - if (!unhandled) { - objVec = SP_ACTIVE_DOCUMENT->getObjectsBySelector(selector); - } - - for (auto& obj: objVec) { + /* for (auto& obj: objVec) { g_debug(" %s", obj->getId() ? obj->getId() : "null"); - } - + } */ return objVec; } @@ -817,32 +888,86 @@ std::vector SelectorDialog::_getObjVec(Glib::ustring selector) { * @param class: class to insert * Insert a class name into objects' 'class' attribute. */ -void SelectorDialog::_insertClass(const std::vector& objVec, const Glib::ustring& className) { - +void SelectorDialog::_insertClass(const std::vector& objVec, const Glib::ustring& className) +{ for (auto& obj: objVec) { + _insertClass(obj, className); + } +} - if (!obj->getRepr()->attribute("class")) { - // 'class' attribute does not exist, create it. - obj->setAttribute("class", className); - } else { - // 'class' attribute exists, append. - Glib::ustring classAttr = obj->getRepr()->attribute("class"); - - // Split on white space. - std::vector tokens = Glib::Regex::split_simple("\\s+", classAttr); - bool add = true; - for (auto& token: tokens) { - if (token == className) { - add = false; // Might be useful to still add... - break; - } +/** + * @param objs: list of objects to insert class + * @param class: class to insert + * Insert a class name into objects' 'class' attribute. + */ +void SelectorDialog::_insertClass(SPObject * obj, const Glib::ustring& className) +{ + Glib::ustring classAttr = Glib::ustring(""); + if (obj->getRepr()->attribute("class")) { + classAttr = obj->getRepr()->attribute("class"); + } + std::vector tokens = Glib::Regex::split_simple("[.]+", className); + std::sort(tokens.begin(), tokens.end()); + tokens.erase(std::unique(tokens.begin(), tokens.end()), tokens.end()); + std::vector tokensplus = Glib::Regex::split_simple("[\\s]+", classAttr); + for (auto tok : tokens) { + bool exist = false; + for (auto& tokenplus: tokensplus) { + if (tokenplus == tok) { + exist = true; } - if (add) { - obj->setAttribute("class", classAttr + " " + className); + } + if (!exist) { + classAttr = classAttr.empty() ? tok : classAttr + " " + tok; + } + } + obj->getRepr()->setAttribute("class", classAttr); +} + +/** + * @param objs: list of objects to insert class + * @param class: class to insert + * Insert a class name into objects' 'class' attribute. + */ +void SelectorDialog::_removeClass(const std::vector& objVec, const Glib::ustring& className, bool all) +{ + for (auto& obj: objVec) { + _removeClass(obj, className, all); + } +} + +/** + * @param objs: list of objects to insert class + * @param class: class to insert + * Insert a class name into objects' 'class' attribute. + */ +void SelectorDialog::_removeClass(SPObject * obj, const Glib::ustring& className, bool all) //without "." +{ + if (obj->getRepr()->attribute("class")) { + std::vector tokens = Glib::Regex::split_simple("[.]+", className); + Glib::ustring classAttr = obj->getRepr()->attribute("class"); + Glib::ustring classAttrRestore = classAttr; + bool notfound = false; + for (auto tok : tokens) { + auto i = classAttr.find(tok); + if (i != std::string::npos) { + classAttr.erase(i, tok.length()); + } else { + notfound = true; +>>>>>>> Fixes on selector dialog based in LGM input } } + if (all && notfound) { + classAttr = classAttrRestore; + } + REMOVE_SPACES(classAttr); + if (classAttr.empty()) { + obj->getRepr()->setAttribute("class", nullptr); + } else { + obj->getRepr()->setAttribute("class", classAttr); + } } - } +} /** @@ -879,7 +1004,6 @@ void SelectorDialog::_selectObjects(int eventX, int eventY) } } - /** * This function opens a dialog to add a selector. The dialog is prefilled * with an 'id' selector containing a list of the id's of selected objects @@ -905,7 +1029,7 @@ void SelectorDialog::_addSelector() textDialogPtr->get_content_area()->pack_start(*textEditPtr, Gtk::PACK_SHRINK); Gtk::Label *textLabelPtr = manage ( new Gtk::Label( - _("Invalid entry: Not an id (#), class (.), or element CSS selector.") + _("Invalid CSS selector.") ) ); textDialogPtr->get_content_area()->pack_start(*textLabelPtr, Gtk::PACK_SHRINK); @@ -936,7 +1060,6 @@ void SelectorDialog::_addSelector() int result = -1; bool invalid = true; Glib::ustring selectorValue; - bool handled = true; while (invalid) { result = textDialogPtr->run(); if (result != Gtk::RESPONSE_OK) { // Cancel, close dialog, etc. @@ -952,38 +1075,8 @@ void SelectorDialog::_addSelector() */ selectorValue = textEditPtr->get_text(); del->show(); - std::vector tokensplus = Glib::Regex::split_simple("[,]+", selectorValue); - bool unhandled = false; - bool partialinvalid = false; - for (auto tok : tokensplus) { - REMOVE_SPACES(tok); - if (SPAttributeRelSVG::isSVGElement(tok) || tok.find(" ") != -1 || tok[0] == '>' || tok[0] == '+' || - tok[0] == '~' || tok[0] == '*' || tok.erase(0, 1).find(".") != -1) { - unhandled = true; - Glib::ustring firstWord = tok.substr(0, tok.find_first_of(" >+~")); - if (firstWord != tok) { - handled = false; - } - if (!partialinvalid && - (tok[0] == '.' || tok[0] == '#' || tok[0] == '*' || SPAttributeRelSVG::isSVGElement(tok))) { - partialinvalid = false; - } else { - partialinvalid = true; - } - } - } - if (!unhandled) { - Glib::ustring firstWord = selectorValue.substr(0, selectorValue.find_first_of(" >+~")); - if (firstWord != selectorValue) { - handled = false; - } - if (selectorValue[0] == '.' || selectorValue[0] == '#' || selectorValue[0] == '*' || - SPAttributeRelSVG::isSVGElement(selectorValue)) { - invalid = false; - } else { - textLabelPtr->show(); - } - } else if (partialinvalid) { + fixCSSSelectors(selectorValue); + if (selectorValue.empty()) { textLabelPtr->show(); } else { invalid = false; @@ -993,40 +1086,44 @@ void SelectorDialog::_addSelector() // ==== Handle response ==== // If class selector, add selector name to class attribute for each object - if (selectorValue[0] == '.' && handled) { - std::vector tokens = Glib::Regex::split_simple("[,\\s]+", selectorValue); - Glib::ustring originClassName = tokens[0]; - originClassName.erase(0, 1); - std::vector classes = Glib::Regex::split_simple("[\\.]+", originClassName); - if (classes.size() == 1) { - _insertClass(objVec, classes[0]); - } else { - handled = false; + REMOVE_SPACES(selectorValue); + std::vector tokens = Glib::Regex::split_simple("[,]+", selectorValue); + for (auto &obj : objVec) { + for (auto tok : tokens) { + Glib::ustring clases = sp_get_selector_classes(tok); + if (clases.empty()) { + continue; + } + _insertClass(obj, clases); + std::vector currentobjs = _getObjVec(selectorValue); + bool removeclass = true; + for (auto currentobj : currentobjs) { + if (currentobj->getId() == obj->getId()) { + removeclass = false; + } + } + if (removeclass) { + _removeClass(obj, clases); + } } } - - // Generate a new object vector (we could have an element selector, - // the user could have edited the id selector list, etc.). - objVec = _getObjVec( selectorValue ); - - // Add entry to GUI tree + objVec = _getObjVec(selectorValue); Gtk::TreeModel::Row row = *(_store->append()); - row[_mColumns._colSelector] = selectorValue; row[_mColumns._colExpand] = true; - row[_mColumns._colType] = handled ? SELECTOR : UNHANDLED; + row[_mColumns._colType] = SELECTOR; + row[_mColumns._colSelector] = selectorValue; row[_mColumns._colObj] = objVec; - - // Add as children objects that match selector. - if (handled) { - for (auto &obj : objVec) { - Gtk::TreeModel::Row childrow = *(_store->append(row->children())); - childrow[_mColumns._colSelector] = "#" + Glib::ustring(obj->getId()); - childrow[_mColumns._colExpand] = false; - childrow[_mColumns._colType] = OBJECT; - childrow[_mColumns._colObj] = std::vector(1, obj); - } + row[_mColumns._colProperties] = ""; + row[_mColumns._colVisible] = true; + for (auto &obj : objVec) { + Gtk::TreeModel::Row childrow = *(_store->append(row->children())); + childrow[_mColumns._colSelector] = "#" + Glib::ustring(obj->getId()); + childrow[_mColumns._colExpand] = false; + childrow[_mColumns._colType] = OBJECT; + childrow[_mColumns._colObj] = std::vector(1, obj); + childrow[_mColumns._colProperties] = ""; // Unused + childrow[_mColumns._colVisible] = true; // Unused } - // Add entry to style element _writeStyleElement(); } diff --git a/src/ui/dialog/selectordialog.h b/src/ui/dialog/selectordialog.h index 1702f087d..ad1a39576 100644 --- a/src/ui/dialog/selectordialog.h +++ b/src/ui/dialog/selectordialog.h @@ -59,13 +59,18 @@ public: // Monitor all objects for addition/removal/attribute change class NodeWatcher; - + enum SelectorType { + CLASS, + ID, + TAG + }; + void fixCSSSelectors(Glib::ustring &selector); std::vector _nodeWatchers; void _nodeAdded( Inkscape::XML::Node &repr ); void _nodeRemoved( Inkscape::XML::Node &repr ); void _nodeChanged( Inkscape::XML::Node &repr ); // Data structure - enum coltype { OBJECT, SELECTOR, UNHANDLED }; + enum coltype { OBJECT, SELECTOR}; class ModelColumns : public Gtk::TreeModel::ColumnRecord { public: ModelColumns() { @@ -133,8 +138,12 @@ public: Glib::ustring _getIdList(std::vector); std::vector _getObjVec(Glib::ustring selector); void _insertClass(const std::vector& objVec, const Glib::ustring& className); - void _selectObjects(int, int); + void _insertClass(SPObject * obj, const Glib::ustring& className); + void _removeClass(const std::vector& objVec, const Glib::ustring& className, bool all = false); + void _removeClass(SPObject * obj, const Glib::ustring& className, bool all = false); + + void _selectObjects(int, int); // Variables bool _updating; // Prevent cyclic actions: read <-> write, select via dialog <-> via desktop Inkscape::XML::Node *_textNode; // Track so we know when to add a NodeObserver. -- cgit v1.2.3 From bf6673c9782a1dbb69e98664f52bda0c645676a8 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Sat, 8 Jun 2019 20:36:36 +0200 Subject: fix coding style --- clang_format_diff | 258 +++++++++++++++++++++++++++++++++++++++ src/ui/dialog/selectordialog.cpp | 71 ++++++----- src/ui/dialog/selectordialog.h | 16 +-- 3 files changed, 298 insertions(+), 47 deletions(-) create mode 100644 clang_format_diff diff --git a/clang_format_diff b/clang_format_diff new file mode 100644 index 000000000..ae35ae8e8 --- /dev/null +++ b/clang_format_diff @@ -0,0 +1,258 @@ +--- src/ui/dialog/selectordialog.cpp (before formatting) ++++ src/ui/dialog/selectordialog.cpp (after formatting) +@@ -28,8 +28,8 @@ + #include + #include + ++#include + #include +-#include + #include + + //#define DEBUG_SELECTORDIALOG +@@ -43,9 +43,12 @@ + * This macro is used to remove spaces around selectors or any strings when + * parsing is done to update XML style element or row labels in this dialog. + */ +-#define REMOVE_SPACES(x) x.erase(0, x.find_first_not_of(' ')); \ +- if(x.size() && x[0] == ',') x.erase(0, 1); \ +- if(x.size() && x[x.size()-1] == ',') x.erase(x.size()-1, 1); \ ++#define REMOVE_SPACES(x) \ ++ x.erase(0, x.find_first_not_of(' ')); \ ++ if (x.size() && x[0] == ',') \ ++ x.erase(0, 1); \ ++ if (x.size() && x[x.size() - 1] == ',') \ ++ x.erase(x.size() - 1, 1); \ + x.erase(x.find_last_not_of(' ') + 1); + + namespace Inkscape { +@@ -183,19 +186,17 @@ + const_iterator iter = unconstThis->get_iter(path); + if (iter) { + Gtk::TreeModel::Row row = *iter; +- bool is_draggable = +- row[_selectordialog->_mColumns._colType] == SELECTOR; ++ bool is_draggable = row[_selectordialog->_mColumns._colType] == SELECTOR; + return is_draggable; + } + return Gtk::TreeStore::row_draggable_vfunc(path); + } + +-void +-SelectorDialog::fixCSSSelectors(Glib::ustring &selector) ++void SelectorDialog::fixCSSSelectors(Glib::ustring &selector) + { + REMOVE_SPACES(selector); +- Glib::ustring my_selector = selector + " {"; // Parsing fails sometimes without '{'. Fix me +- CRSelector *cr_selector = cr_selector_parse_from_buf ((guchar*)my_selector.c_str(), CR_UTF_8); ++ Glib::ustring my_selector = selector + " {"; // Parsing fails sometimes without '{'. Fix me ++ CRSelector *cr_selector = cr_selector_parse_from_buf((guchar *)my_selector.c_str(), CR_UTF_8); + selector = Glib::ustring(""); + CRSelector const *cur = nullptr; + for (cur = cr_selector; cur; cur = cur->next) { +@@ -221,7 +222,7 @@ + Glib::ustring tag = Glib::ustring(""); + if (toparse[0] != '.' && toparse[0] != '#') { + auto i = std::min(toparse.find("#"), toparse.find(".")); +- tag = toparse.substr(0,i); ++ tag = toparse.substr(0, i); + if (!SPAttributeRelSVG::isSVGElement(tag)) { + continue; + } +@@ -647,7 +648,7 @@ + + _updating = false; + } +-/* ++/* + void sp_get_selector_active(Glib::ustring &selector) + { + std::vector tokensplus = Glib::Regex::split_simple("[ ]+", selector); +@@ -674,10 +675,9 @@ + } + } */ + +-Glib::ustring +-sp_get_selector_classes(Glib::ustring selector)//, SelectorType selectortype, Glib::ustring id = "") +-{ +- std::pair result; ++Glib::ustring sp_get_selector_classes(Glib::ustring selector) //, SelectorType selectortype, Glib::ustring id = "") ++{ ++ std::pair result; + std::vector tokensplus = Glib::Regex::split_simple("[ ]+", selector); + selector = tokensplus[tokensplus.size() - 1]; + // Erase any comma/space +@@ -686,7 +686,7 @@ + selector = Glib::ustring(""); + if (toparse[0] != '.' && toparse[0] != '#') { + auto i = std::min(toparse.find("#"), toparse.find(".")); +- Glib::ustring tag = toparse.substr(0,i); ++ Glib::ustring tag = toparse.substr(0, i); + if (!SPAttributeRelSVG::isSVGElement(tag)) { + return selector; + } +@@ -705,13 +705,13 @@ + if (i != std::string::npos) { + toparse.insert(i, "#"); + if (i) { +- Glib::ustring post = toparse.substr(0,i); +- Glib::ustring pre = toparse.substr(i, toparse.size()-i); ++ Glib::ustring post = toparse.substr(0, i); ++ Glib::ustring pre = toparse.substr(i, toparse.size() - i); + toparse = pre + post; + } + auto k = toparse.find("."); + if (k != std::string::npos) { +- toparse = toparse.substr(k, toparse.size()-k); ++ toparse = toparse.substr(k, toparse.size() - k); + } + } + return toparse; +@@ -727,16 +727,15 @@ + if (*row) { + // Store list of selected elements on desktop (not to be confused with selector). + _updating = true; +- Inkscape::Selection* selection = getDesktop()->getSelection(); +- std::vector toAddObjVec( selection->objects().begin(), +- selection->objects().end() ); ++ Inkscape::Selection *selection = getDesktop()->getSelection(); ++ std::vector toAddObjVec(selection->objects().begin(), selection->objects().end()); + Glib::ustring multiselector = row[_mColumns._colSelector]; + std::vector objVec = _getObjVec(multiselector); +- row[_mColumns._colObj] = objVec; ++ row[_mColumns._colObj] = objVec; + row[_mColumns._colExpand] = true; + std::vector tokens = Glib::Regex::split_simple("[,]+", multiselector); + for (auto &obj : toAddObjVec) { +- Glib::ustring id = (obj->getId()?obj->getId():""); ++ Glib::ustring id = (obj->getId() ? obj->getId() : ""); + for (auto tok : tokens) { + Glib::ustring clases = sp_get_selector_classes(tok); + if (!clases.empty()) { +@@ -770,7 +769,7 @@ + childrow[_mColumns._colObj] = std::vector(1, obj); + childrow[_mColumns._colProperties] = ""; // Unused + childrow[_mColumns._colVisible] = true; // Unused +- } ++ } + objVec = _getObjVec(multiselector); + row[_mColumns._colSelector] = multiselector; + row[_mColumns._colObj] = objVec; +@@ -811,7 +810,7 @@ + } + auto i = tok.find(row[_mColumns._colSelector]); + if (i == std::string::npos) { +- selector = selector.empty()? tok : selector + "," + tok; ++ selector = selector.empty() ? tok : selector + "," + tok; + } + } + REMOVE_SPACES(selector); +@@ -821,8 +820,8 @@ + } else { + _store->erase(row); + parent[_mColumns._colSelector] = selector; +- parent[_mColumns._colExpand] = true; +- parent[_mColumns._colObj] = _getObjVec(selector); ++ parent[_mColumns._colExpand] = true; ++ parent[_mColumns._colObj] = _getObjVec(selector); + } + } + _updating = false; +@@ -888,7 +887,7 @@ + * @param class: class to insert + * Insert a class name into objects' 'class' attribute. + */ +-void SelectorDialog::_insertClass(const std::vector& objVec, const Glib::ustring& className) ++void SelectorDialog::_insertClass(const std::vector &objVec, const Glib::ustring &className) + { + for (auto& obj: objVec) { + _insertClass(obj, className); +@@ -900,7 +899,7 @@ + * @param class: class to insert + * Insert a class name into objects' 'class' attribute. + */ +-void SelectorDialog::_insertClass(SPObject * obj, const Glib::ustring& className) ++void SelectorDialog::_insertClass(SPObject *obj, const Glib::ustring &className) + { + Glib::ustring classAttr = Glib::ustring(""); + if (obj->getRepr()->attribute("class")) { +@@ -912,7 +911,7 @@ + std::vector tokensplus = Glib::Regex::split_simple("[\\s]+", classAttr); + for (auto tok : tokens) { + bool exist = false; +- for (auto& tokenplus: tokensplus) { ++ for (auto &tokenplus : tokensplus) { + if (tokenplus == tok) { + exist = true; + } +@@ -929,9 +928,9 @@ + * @param class: class to insert + * Insert a class name into objects' 'class' attribute. + */ +-void SelectorDialog::_removeClass(const std::vector& objVec, const Glib::ustring& className, bool all) +-{ +- for (auto& obj: objVec) { ++void SelectorDialog::_removeClass(const std::vector &objVec, const Glib::ustring &className, bool all) ++{ ++ for (auto &obj : objVec) { + _removeClass(obj, className, all); + } + } +@@ -941,7 +940,7 @@ + * @param class: class to insert + * Insert a class name into objects' 'class' attribute. + */ +-void SelectorDialog::_removeClass(SPObject * obj, const Glib::ustring& className, bool all) //without "." ++void SelectorDialog::_removeClass(SPObject *obj, const Glib::ustring &className, bool all) // without "." + { + if (obj->getRepr()->attribute("class")) { + std::vector tokens = Glib::Regex::split_simple("[.]+", className); +@@ -1028,9 +1027,7 @@ + sigc::bind(sigc::mem_fun(*this, &SelectorDialog::_closeDialog), textDialogPtr)); + textDialogPtr->get_content_area()->pack_start(*textEditPtr, Gtk::PACK_SHRINK); + +- Gtk::Label *textLabelPtr = manage ( new Gtk::Label( +- _("Invalid CSS selector.") +- ) ); ++ Gtk::Label *textLabelPtr = manage(new Gtk::Label(_("Invalid CSS selector."))); + textDialogPtr->get_content_area()->pack_start(*textLabelPtr, Gtk::PACK_SHRINK); + + /** +--- src/ui/dialog/selectordialog.h (before formatting) ++++ src/ui/dialog/selectordialog.h (after formatting) +@@ -59,18 +59,14 @@ + + // Monitor all objects for addition/removal/attribute change + class NodeWatcher; +- enum SelectorType { +- CLASS, +- ID, +- TAG +- }; ++ enum SelectorType { CLASS, ID, TAG }; + void fixCSSSelectors(Glib::ustring &selector); + std::vector _nodeWatchers; + void _nodeAdded( Inkscape::XML::Node &repr ); + void _nodeRemoved( Inkscape::XML::Node &repr ); + void _nodeChanged( Inkscape::XML::Node &repr ); + // Data structure +- enum coltype { OBJECT, SELECTOR}; ++ enum coltype { OBJECT, SELECTOR }; + class ModelColumns : public Gtk::TreeModel::ColumnRecord { + public: + ModelColumns() { +@@ -138,10 +134,10 @@ + Glib::ustring _getIdList(std::vector); + std::vector _getObjVec(Glib::ustring selector); + void _insertClass(const std::vector& objVec, const Glib::ustring& className); +- void _insertClass(SPObject * obj, const Glib::ustring& className); +- void _removeClass(const std::vector& objVec, const Glib::ustring& className, bool all = false); +- void _removeClass(SPObject * obj, const Glib::ustring& className, bool all = false); +- ++ void _insertClass(SPObject *obj, const Glib::ustring &className); ++ void _removeClass(const std::vector &objVec, const Glib::ustring &className, bool all = false); ++ void _removeClass(SPObject *obj, const Glib::ustring &className, bool all = false); ++ + + void _selectObjects(int, int); + // Variables diff --git a/src/ui/dialog/selectordialog.cpp b/src/ui/dialog/selectordialog.cpp index 263851d16..06a327246 100644 --- a/src/ui/dialog/selectordialog.cpp +++ b/src/ui/dialog/selectordialog.cpp @@ -28,8 +28,8 @@ #include #include -#include #include +#include #include //#define DEBUG_SELECTORDIALOG @@ -43,9 +43,12 @@ using Inkscape::XML::AttributeRecord; * This macro is used to remove spaces around selectors or any strings when * parsing is done to update XML style element or row labels in this dialog. */ -#define REMOVE_SPACES(x) x.erase(0, x.find_first_not_of(' ')); \ - if(x.size() && x[0] == ',') x.erase(0, 1); \ - if(x.size() && x[x.size()-1] == ',') x.erase(x.size()-1, 1); \ +#define REMOVE_SPACES(x) \ + x.erase(0, x.find_first_not_of(' ')); \ + if (x.size() && x[0] == ',') \ + x.erase(0, 1); \ + if (x.size() && x[x.size() - 1] == ',') \ + x.erase(x.size() - 1, 1); \ x.erase(x.find_last_not_of(' ') + 1); namespace Inkscape { @@ -183,19 +186,17 @@ SelectorDialog::TreeStore::row_draggable_vfunc(const Gtk::TreeModel::Path& path) const_iterator iter = unconstThis->get_iter(path); if (iter) { Gtk::TreeModel::Row row = *iter; - bool is_draggable = - row[_selectordialog->_mColumns._colType] == SELECTOR; + bool is_draggable = row[_selectordialog->_mColumns._colType] == SELECTOR; return is_draggable; } return Gtk::TreeStore::row_draggable_vfunc(path); } -void -SelectorDialog::fixCSSSelectors(Glib::ustring &selector) +void SelectorDialog::fixCSSSelectors(Glib::ustring &selector) { REMOVE_SPACES(selector); - Glib::ustring my_selector = selector + " {"; // Parsing fails sometimes without '{'. Fix me - CRSelector *cr_selector = cr_selector_parse_from_buf ((guchar*)my_selector.c_str(), CR_UTF_8); + Glib::ustring my_selector = selector + " {"; // Parsing fails sometimes without '{'. Fix me + CRSelector *cr_selector = cr_selector_parse_from_buf((guchar *)my_selector.c_str(), CR_UTF_8); selector = Glib::ustring(""); CRSelector const *cur = nullptr; for (cur = cr_selector; cur; cur = cur->next) { @@ -221,7 +222,7 @@ SelectorDialog::fixCSSSelectors(Glib::ustring &selector) Glib::ustring tag = Glib::ustring(""); if (toparse[0] != '.' && toparse[0] != '#') { auto i = std::min(toparse.find("#"), toparse.find(".")); - tag = toparse.substr(0,i); + tag = toparse.substr(0, i); if (!SPAttributeRelSVG::isSVGElement(tag)) { continue; } @@ -647,7 +648,7 @@ void SelectorDialog::_updateWatchers() _updating = false; } -/* +/* void sp_get_selector_active(Glib::ustring &selector) { std::vector tokensplus = Glib::Regex::split_simple("[ ]+", selector); @@ -674,10 +675,9 @@ void sp_get_selector_active(Glib::ustring &selector) } } */ -Glib::ustring -sp_get_selector_classes(Glib::ustring selector)//, SelectorType selectortype, Glib::ustring id = "") +Glib::ustring sp_get_selector_classes(Glib::ustring selector) //, SelectorType selectortype, Glib::ustring id = "") { - std::pair result; + std::pair result; std::vector tokensplus = Glib::Regex::split_simple("[ ]+", selector); selector = tokensplus[tokensplus.size() - 1]; // Erase any comma/space @@ -686,7 +686,7 @@ sp_get_selector_classes(Glib::ustring selector)//, SelectorType selectortype, G selector = Glib::ustring(""); if (toparse[0] != '.' && toparse[0] != '#') { auto i = std::min(toparse.find("#"), toparse.find(".")); - Glib::ustring tag = toparse.substr(0,i); + Glib::ustring tag = toparse.substr(0, i); if (!SPAttributeRelSVG::isSVGElement(tag)) { return selector; } @@ -705,13 +705,13 @@ sp_get_selector_classes(Glib::ustring selector)//, SelectorType selectortype, G if (i != std::string::npos) { toparse.insert(i, "#"); if (i) { - Glib::ustring post = toparse.substr(0,i); - Glib::ustring pre = toparse.substr(i, toparse.size()-i); + Glib::ustring post = toparse.substr(0, i); + Glib::ustring pre = toparse.substr(i, toparse.size() - i); toparse = pre + post; } auto k = toparse.find("."); if (k != std::string::npos) { - toparse = toparse.substr(k, toparse.size()-k); + toparse = toparse.substr(k, toparse.size() - k); } } return toparse; @@ -727,16 +727,15 @@ void SelectorDialog::_addToSelector(Gtk::TreeModel::Row row) if (*row) { // Store list of selected elements on desktop (not to be confused with selector). _updating = true; - Inkscape::Selection* selection = getDesktop()->getSelection(); - std::vector toAddObjVec( selection->objects().begin(), - selection->objects().end() ); + Inkscape::Selection *selection = getDesktop()->getSelection(); + std::vector toAddObjVec(selection->objects().begin(), selection->objects().end()); Glib::ustring multiselector = row[_mColumns._colSelector]; std::vector objVec = _getObjVec(multiselector); - row[_mColumns._colObj] = objVec; + row[_mColumns._colObj] = objVec; row[_mColumns._colExpand] = true; std::vector tokens = Glib::Regex::split_simple("[,]+", multiselector); for (auto &obj : toAddObjVec) { - Glib::ustring id = (obj->getId()?obj->getId():""); + Glib::ustring id = (obj->getId() ? obj->getId() : ""); for (auto tok : tokens) { Glib::ustring clases = sp_get_selector_classes(tok); if (!clases.empty()) { @@ -770,7 +769,7 @@ void SelectorDialog::_addToSelector(Gtk::TreeModel::Row row) childrow[_mColumns._colObj] = std::vector(1, obj); childrow[_mColumns._colProperties] = ""; // Unused childrow[_mColumns._colVisible] = true; // Unused - } + } objVec = _getObjVec(multiselector); row[_mColumns._colSelector] = multiselector; row[_mColumns._colObj] = objVec; @@ -811,7 +810,7 @@ void SelectorDialog::_removeFromSelector(Gtk::TreeModel::Row row) } auto i = tok.find(row[_mColumns._colSelector]); if (i == std::string::npos) { - selector = selector.empty()? tok : selector + "," + tok; + selector = selector.empty() ? tok : selector + "," + tok; } } REMOVE_SPACES(selector); @@ -821,8 +820,8 @@ void SelectorDialog::_removeFromSelector(Gtk::TreeModel::Row row) } else { _store->erase(row); parent[_mColumns._colSelector] = selector; - parent[_mColumns._colExpand] = true; - parent[_mColumns._colObj] = _getObjVec(selector); + parent[_mColumns._colExpand] = true; + parent[_mColumns._colObj] = _getObjVec(selector); } } _updating = false; @@ -888,7 +887,7 @@ std::vector SelectorDialog::_getObjVec(Glib::ustring selector) { * @param class: class to insert * Insert a class name into objects' 'class' attribute. */ -void SelectorDialog::_insertClass(const std::vector& objVec, const Glib::ustring& className) +void SelectorDialog::_insertClass(const std::vector &objVec, const Glib::ustring &className) { for (auto& obj: objVec) { _insertClass(obj, className); @@ -900,7 +899,7 @@ void SelectorDialog::_insertClass(const std::vector& objVec, const G * @param class: class to insert * Insert a class name into objects' 'class' attribute. */ -void SelectorDialog::_insertClass(SPObject * obj, const Glib::ustring& className) +void SelectorDialog::_insertClass(SPObject *obj, const Glib::ustring &className) { Glib::ustring classAttr = Glib::ustring(""); if (obj->getRepr()->attribute("class")) { @@ -912,7 +911,7 @@ void SelectorDialog::_insertClass(SPObject * obj, const Glib::ustring& className std::vector tokensplus = Glib::Regex::split_simple("[\\s]+", classAttr); for (auto tok : tokens) { bool exist = false; - for (auto& tokenplus: tokensplus) { + for (auto &tokenplus : tokensplus) { if (tokenplus == tok) { exist = true; } @@ -929,9 +928,9 @@ void SelectorDialog::_insertClass(SPObject * obj, const Glib::ustring& className * @param class: class to insert * Insert a class name into objects' 'class' attribute. */ -void SelectorDialog::_removeClass(const std::vector& objVec, const Glib::ustring& className, bool all) +void SelectorDialog::_removeClass(const std::vector &objVec, const Glib::ustring &className, bool all) { - for (auto& obj: objVec) { + for (auto &obj : objVec) { _removeClass(obj, className, all); } } @@ -941,7 +940,7 @@ void SelectorDialog::_removeClass(const std::vector& objVec, const G * @param class: class to insert * Insert a class name into objects' 'class' attribute. */ -void SelectorDialog::_removeClass(SPObject * obj, const Glib::ustring& className, bool all) //without "." +void SelectorDialog::_removeClass(SPObject *obj, const Glib::ustring &className, bool all) // without "." { if (obj->getRepr()->attribute("class")) { std::vector tokens = Glib::Regex::split_simple("[.]+", className); @@ -1028,9 +1027,7 @@ void SelectorDialog::_addSelector() sigc::bind(sigc::mem_fun(*this, &SelectorDialog::_closeDialog), textDialogPtr)); textDialogPtr->get_content_area()->pack_start(*textEditPtr, Gtk::PACK_SHRINK); - Gtk::Label *textLabelPtr = manage ( new Gtk::Label( - _("Invalid CSS selector.") - ) ); + Gtk::Label *textLabelPtr = manage(new Gtk::Label(_("Invalid CSS selector."))); textDialogPtr->get_content_area()->pack_start(*textLabelPtr, Gtk::PACK_SHRINK); /** diff --git a/src/ui/dialog/selectordialog.h b/src/ui/dialog/selectordialog.h index ad1a39576..a3bae04a1 100644 --- a/src/ui/dialog/selectordialog.h +++ b/src/ui/dialog/selectordialog.h @@ -59,18 +59,14 @@ public: // Monitor all objects for addition/removal/attribute change class NodeWatcher; - enum SelectorType { - CLASS, - ID, - TAG - }; + enum SelectorType { CLASS, ID, TAG }; void fixCSSSelectors(Glib::ustring &selector); std::vector _nodeWatchers; void _nodeAdded( Inkscape::XML::Node &repr ); void _nodeRemoved( Inkscape::XML::Node &repr ); void _nodeChanged( Inkscape::XML::Node &repr ); // Data structure - enum coltype { OBJECT, SELECTOR}; + enum coltype { OBJECT, SELECTOR }; class ModelColumns : public Gtk::TreeModel::ColumnRecord { public: ModelColumns() { @@ -138,10 +134,10 @@ public: Glib::ustring _getIdList(std::vector); std::vector _getObjVec(Glib::ustring selector); void _insertClass(const std::vector& objVec, const Glib::ustring& className); - void _insertClass(SPObject * obj, const Glib::ustring& className); - void _removeClass(const std::vector& objVec, const Glib::ustring& className, bool all = false); - void _removeClass(SPObject * obj, const Glib::ustring& className, bool all = false); - + void _insertClass(SPObject *obj, const Glib::ustring &className); + void _removeClass(const std::vector &objVec, const Glib::ustring &className, bool all = false); + void _removeClass(SPObject *obj, const Glib::ustring &className, bool all = false); + void _selectObjects(int, int); // Variables -- cgit v1.2.3 From aab35278bf88e913b89b2227056fbd9dc84f8c17 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Sat, 8 Jun 2019 20:41:22 +0200 Subject: remove clang diff --- clang_format_diff | 258 ------------------------------------------------------ 1 file changed, 258 deletions(-) delete mode 100644 clang_format_diff diff --git a/clang_format_diff b/clang_format_diff deleted file mode 100644 index ae35ae8e8..000000000 --- a/clang_format_diff +++ /dev/null @@ -1,258 +0,0 @@ ---- src/ui/dialog/selectordialog.cpp (before formatting) -+++ src/ui/dialog/selectordialog.cpp (after formatting) -@@ -28,8 +28,8 @@ - #include - #include - -+#include - #include --#include - #include - - //#define DEBUG_SELECTORDIALOG -@@ -43,9 +43,12 @@ - * This macro is used to remove spaces around selectors or any strings when - * parsing is done to update XML style element or row labels in this dialog. - */ --#define REMOVE_SPACES(x) x.erase(0, x.find_first_not_of(' ')); \ -- if(x.size() && x[0] == ',') x.erase(0, 1); \ -- if(x.size() && x[x.size()-1] == ',') x.erase(x.size()-1, 1); \ -+#define REMOVE_SPACES(x) \ -+ x.erase(0, x.find_first_not_of(' ')); \ -+ if (x.size() && x[0] == ',') \ -+ x.erase(0, 1); \ -+ if (x.size() && x[x.size() - 1] == ',') \ -+ x.erase(x.size() - 1, 1); \ - x.erase(x.find_last_not_of(' ') + 1); - - namespace Inkscape { -@@ -183,19 +186,17 @@ - const_iterator iter = unconstThis->get_iter(path); - if (iter) { - Gtk::TreeModel::Row row = *iter; -- bool is_draggable = -- row[_selectordialog->_mColumns._colType] == SELECTOR; -+ bool is_draggable = row[_selectordialog->_mColumns._colType] == SELECTOR; - return is_draggable; - } - return Gtk::TreeStore::row_draggable_vfunc(path); - } - --void --SelectorDialog::fixCSSSelectors(Glib::ustring &selector) -+void SelectorDialog::fixCSSSelectors(Glib::ustring &selector) - { - REMOVE_SPACES(selector); -- Glib::ustring my_selector = selector + " {"; // Parsing fails sometimes without '{'. Fix me -- CRSelector *cr_selector = cr_selector_parse_from_buf ((guchar*)my_selector.c_str(), CR_UTF_8); -+ Glib::ustring my_selector = selector + " {"; // Parsing fails sometimes without '{'. Fix me -+ CRSelector *cr_selector = cr_selector_parse_from_buf((guchar *)my_selector.c_str(), CR_UTF_8); - selector = Glib::ustring(""); - CRSelector const *cur = nullptr; - for (cur = cr_selector; cur; cur = cur->next) { -@@ -221,7 +222,7 @@ - Glib::ustring tag = Glib::ustring(""); - if (toparse[0] != '.' && toparse[0] != '#') { - auto i = std::min(toparse.find("#"), toparse.find(".")); -- tag = toparse.substr(0,i); -+ tag = toparse.substr(0, i); - if (!SPAttributeRelSVG::isSVGElement(tag)) { - continue; - } -@@ -647,7 +648,7 @@ - - _updating = false; - } --/* -+/* - void sp_get_selector_active(Glib::ustring &selector) - { - std::vector tokensplus = Glib::Regex::split_simple("[ ]+", selector); -@@ -674,10 +675,9 @@ - } - } */ - --Glib::ustring --sp_get_selector_classes(Glib::ustring selector)//, SelectorType selectortype, Glib::ustring id = "") --{ -- std::pair result; -+Glib::ustring sp_get_selector_classes(Glib::ustring selector) //, SelectorType selectortype, Glib::ustring id = "") -+{ -+ std::pair result; - std::vector tokensplus = Glib::Regex::split_simple("[ ]+", selector); - selector = tokensplus[tokensplus.size() - 1]; - // Erase any comma/space -@@ -686,7 +686,7 @@ - selector = Glib::ustring(""); - if (toparse[0] != '.' && toparse[0] != '#') { - auto i = std::min(toparse.find("#"), toparse.find(".")); -- Glib::ustring tag = toparse.substr(0,i); -+ Glib::ustring tag = toparse.substr(0, i); - if (!SPAttributeRelSVG::isSVGElement(tag)) { - return selector; - } -@@ -705,13 +705,13 @@ - if (i != std::string::npos) { - toparse.insert(i, "#"); - if (i) { -- Glib::ustring post = toparse.substr(0,i); -- Glib::ustring pre = toparse.substr(i, toparse.size()-i); -+ Glib::ustring post = toparse.substr(0, i); -+ Glib::ustring pre = toparse.substr(i, toparse.size() - i); - toparse = pre + post; - } - auto k = toparse.find("."); - if (k != std::string::npos) { -- toparse = toparse.substr(k, toparse.size()-k); -+ toparse = toparse.substr(k, toparse.size() - k); - } - } - return toparse; -@@ -727,16 +727,15 @@ - if (*row) { - // Store list of selected elements on desktop (not to be confused with selector). - _updating = true; -- Inkscape::Selection* selection = getDesktop()->getSelection(); -- std::vector toAddObjVec( selection->objects().begin(), -- selection->objects().end() ); -+ Inkscape::Selection *selection = getDesktop()->getSelection(); -+ std::vector toAddObjVec(selection->objects().begin(), selection->objects().end()); - Glib::ustring multiselector = row[_mColumns._colSelector]; - std::vector objVec = _getObjVec(multiselector); -- row[_mColumns._colObj] = objVec; -+ row[_mColumns._colObj] = objVec; - row[_mColumns._colExpand] = true; - std::vector tokens = Glib::Regex::split_simple("[,]+", multiselector); - for (auto &obj : toAddObjVec) { -- Glib::ustring id = (obj->getId()?obj->getId():""); -+ Glib::ustring id = (obj->getId() ? obj->getId() : ""); - for (auto tok : tokens) { - Glib::ustring clases = sp_get_selector_classes(tok); - if (!clases.empty()) { -@@ -770,7 +769,7 @@ - childrow[_mColumns._colObj] = std::vector(1, obj); - childrow[_mColumns._colProperties] = ""; // Unused - childrow[_mColumns._colVisible] = true; // Unused -- } -+ } - objVec = _getObjVec(multiselector); - row[_mColumns._colSelector] = multiselector; - row[_mColumns._colObj] = objVec; -@@ -811,7 +810,7 @@ - } - auto i = tok.find(row[_mColumns._colSelector]); - if (i == std::string::npos) { -- selector = selector.empty()? tok : selector + "," + tok; -+ selector = selector.empty() ? tok : selector + "," + tok; - } - } - REMOVE_SPACES(selector); -@@ -821,8 +820,8 @@ - } else { - _store->erase(row); - parent[_mColumns._colSelector] = selector; -- parent[_mColumns._colExpand] = true; -- parent[_mColumns._colObj] = _getObjVec(selector); -+ parent[_mColumns._colExpand] = true; -+ parent[_mColumns._colObj] = _getObjVec(selector); - } - } - _updating = false; -@@ -888,7 +887,7 @@ - * @param class: class to insert - * Insert a class name into objects' 'class' attribute. - */ --void SelectorDialog::_insertClass(const std::vector& objVec, const Glib::ustring& className) -+void SelectorDialog::_insertClass(const std::vector &objVec, const Glib::ustring &className) - { - for (auto& obj: objVec) { - _insertClass(obj, className); -@@ -900,7 +899,7 @@ - * @param class: class to insert - * Insert a class name into objects' 'class' attribute. - */ --void SelectorDialog::_insertClass(SPObject * obj, const Glib::ustring& className) -+void SelectorDialog::_insertClass(SPObject *obj, const Glib::ustring &className) - { - Glib::ustring classAttr = Glib::ustring(""); - if (obj->getRepr()->attribute("class")) { -@@ -912,7 +911,7 @@ - std::vector tokensplus = Glib::Regex::split_simple("[\\s]+", classAttr); - for (auto tok : tokens) { - bool exist = false; -- for (auto& tokenplus: tokensplus) { -+ for (auto &tokenplus : tokensplus) { - if (tokenplus == tok) { - exist = true; - } -@@ -929,9 +928,9 @@ - * @param class: class to insert - * Insert a class name into objects' 'class' attribute. - */ --void SelectorDialog::_removeClass(const std::vector& objVec, const Glib::ustring& className, bool all) --{ -- for (auto& obj: objVec) { -+void SelectorDialog::_removeClass(const std::vector &objVec, const Glib::ustring &className, bool all) -+{ -+ for (auto &obj : objVec) { - _removeClass(obj, className, all); - } - } -@@ -941,7 +940,7 @@ - * @param class: class to insert - * Insert a class name into objects' 'class' attribute. - */ --void SelectorDialog::_removeClass(SPObject * obj, const Glib::ustring& className, bool all) //without "." -+void SelectorDialog::_removeClass(SPObject *obj, const Glib::ustring &className, bool all) // without "." - { - if (obj->getRepr()->attribute("class")) { - std::vector tokens = Glib::Regex::split_simple("[.]+", className); -@@ -1028,9 +1027,7 @@ - sigc::bind(sigc::mem_fun(*this, &SelectorDialog::_closeDialog), textDialogPtr)); - textDialogPtr->get_content_area()->pack_start(*textEditPtr, Gtk::PACK_SHRINK); - -- Gtk::Label *textLabelPtr = manage ( new Gtk::Label( -- _("Invalid CSS selector.") -- ) ); -+ Gtk::Label *textLabelPtr = manage(new Gtk::Label(_("Invalid CSS selector."))); - textDialogPtr->get_content_area()->pack_start(*textLabelPtr, Gtk::PACK_SHRINK); - - /** ---- src/ui/dialog/selectordialog.h (before formatting) -+++ src/ui/dialog/selectordialog.h (after formatting) -@@ -59,18 +59,14 @@ - - // Monitor all objects for addition/removal/attribute change - class NodeWatcher; -- enum SelectorType { -- CLASS, -- ID, -- TAG -- }; -+ enum SelectorType { CLASS, ID, TAG }; - void fixCSSSelectors(Glib::ustring &selector); - std::vector _nodeWatchers; - void _nodeAdded( Inkscape::XML::Node &repr ); - void _nodeRemoved( Inkscape::XML::Node &repr ); - void _nodeChanged( Inkscape::XML::Node &repr ); - // Data structure -- enum coltype { OBJECT, SELECTOR}; -+ enum coltype { OBJECT, SELECTOR }; - class ModelColumns : public Gtk::TreeModel::ColumnRecord { - public: - ModelColumns() { -@@ -138,10 +134,10 @@ - Glib::ustring _getIdList(std::vector); - std::vector _getObjVec(Glib::ustring selector); - void _insertClass(const std::vector& objVec, const Glib::ustring& className); -- void _insertClass(SPObject * obj, const Glib::ustring& className); -- void _removeClass(const std::vector& objVec, const Glib::ustring& className, bool all = false); -- void _removeClass(SPObject * obj, const Glib::ustring& className, bool all = false); -- -+ void _insertClass(SPObject *obj, const Glib::ustring &className); -+ void _removeClass(const std::vector &objVec, const Glib::ustring &className, bool all = false); -+ void _removeClass(SPObject *obj, const Glib::ustring &className, bool all = false); -+ - - void _selectObjects(int, int); - // Variables -- cgit v1.2.3 From 3473bec48ef9b55fc29c8a10e22287839eb735ef Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Sat, 8 Jun 2019 21:06:51 +0200 Subject: fix rebase --- src/ui/dialog/selectordialog.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ui/dialog/selectordialog.cpp b/src/ui/dialog/selectordialog.cpp index 06a327246..cca029e2b 100644 --- a/src/ui/dialog/selectordialog.cpp +++ b/src/ui/dialog/selectordialog.cpp @@ -953,7 +953,6 @@ void SelectorDialog::_removeClass(SPObject *obj, const Glib::ustring &className, classAttr.erase(i, tok.length()); } else { notfound = true; ->>>>>>> Fixes on selector dialog based in LGM input } } if (all && notfound) { -- cgit v1.2.3 From 86b7e8583d00c1db6b71a7e3dbdddc4ff5e86b4a Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Sun, 9 Jun 2019 01:50:23 +0200 Subject: rsync with last merge in 2Geom --- src/2geom/intersection-graph.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/2geom/intersection-graph.cpp b/src/2geom/intersection-graph.cpp index 4ee4f65fa..1d065527f 100644 --- a/src/2geom/intersection-graph.cpp +++ b/src/2geom/intersection-graph.cpp @@ -89,6 +89,7 @@ void PathIntersectionGraph::_prepareArguments() for (std::size_t i = _pv[w].size(); i > 0; --i) { if (_pv[w][i-1].empty()) { _pv[w].erase(_pv[w].begin() + (i-1)); + continue; } for (std::size_t j = _pv[w][i-1].size(); j > 0; --j) { if (_pv[w][i-1][j-1].isDegenerate()) { -- cgit v1.2.3 From 2b4b777418d9cdf03dcc4e5cf3a1e2ab2c274769 Mon Sep 17 00:00:00 2001 From: Patrick Storz Date: Sun, 9 Jun 2019 02:34:06 +0200 Subject: Minor cleanup (remove unneeded win32-specific defines) --- src/object/color-profile.cpp | 3 --- src/ui/dialog/filedialogimpl-win32.h | 5 +---- src/winconsole.cpp | 1 - 3 files changed, 1 insertion(+), 8 deletions(-) diff --git a/src/object/color-profile.cpp b/src/object/color-profile.cpp index 36bb32142..cdfea4bad 100644 --- a/src/object/color-profile.cpp +++ b/src/object/color-profile.cpp @@ -30,9 +30,6 @@ #include #ifdef _WIN32 -#ifndef _WIN32_WINDOWS // Allow use of features specific to Windows 98 or later. Required for correctly including icm.h -#define _WIN32_WINDOWS 0x0410 -#endif #include #endif diff --git a/src/ui/dialog/filedialogimpl-win32.h b/src/ui/dialog/filedialogimpl-win32.h index a086962b7..9dedaa30c 100644 --- a/src/ui/dialog/filedialogimpl-win32.h +++ b/src/ui/dialog/filedialogimpl-win32.h @@ -18,10 +18,7 @@ #include "filedialogimpl-gtkmm.h" #include "inkgc/gc-core.h" -// define WINVER high enough so we get the correct OPENFILENAMEW size -#ifndef WINVER -#define WINVER 0x0500 -#endif + #include diff --git a/src/winconsole.cpp b/src/winconsole.cpp index aa04128fd..398608e78 100644 --- a/src/winconsole.cpp +++ b/src/winconsole.cpp @@ -40,7 +40,6 @@ */ #ifdef _WIN32 -#undef DATADIR #include struct echo_thread_info { -- cgit v1.2.3 From 5d824f8bb5b0dc11f0459600d277838ed6f2e057 Mon Sep 17 00:00:00 2001 From: Patrick Storz Date: Sat, 8 Jun 2019 23:07:02 +0200 Subject: CMake: Use bin subfolder for binaries on Windows Second part of https://gitlab.com/inkscape/inkscape/issues/82 --- CMakeScripts/InstallMSYS2.cmake | 16 ++++++++-------- src/CMakeLists.txt | 22 +++++----------------- 2 files changed, 13 insertions(+), 25 deletions(-) diff --git a/CMakeScripts/InstallMSYS2.cmake b/CMakeScripts/InstallMSYS2.cmake index f19f19417..36fd94264 100644 --- a/CMakeScripts/InstallMSYS2.cmake +++ b/CMakeScripts/InstallMSYS2.cmake @@ -123,16 +123,16 @@ if(WIN32) ${MINGW_BIN}/tcl[0-9]*.dll ${MINGW_BIN}/tk[0-9]*.dll ${MINGW_BIN}/zlib1.dll) - INSTALL(FILES ${MINGW_LIBS} DESTINATION .) + INSTALL(FILES ${MINGW_LIBS} DESTINATION bin) # There are differences for 64-Bit and 32-Bit build environments. if(HAVE_MINGW64) install(FILES ${MINGW_BIN}/libgcc_s_seh-1.dll - DESTINATION .) + DESTINATION bin) else() install(FILES ${MINGW_BIN}/libgcc_s_dw2-1.dll - DESTINATION .) + DESTINATION bin) endif() # Install hicolor/index.theme to avoid bug 1635207 @@ -223,26 +223,26 @@ if(WIN32) install(FILES ${MINGW_BIN}/gspawn-win64-helper.exe ${MINGW_BIN}/gspawn-win64-helper-console.exe - DESTINATION .) + DESTINATION bin) else() install(FILES ${MINGW_BIN}/gspawn-win32-helper.exe ${MINGW_BIN}/gspawn-win32-helper-console.exe - DESTINATION .) + DESTINATION bin) endif() # Python (a bit hacky for backwards compatibility with devlibs at this point) install(FILES ${MINGW_BIN}/python2.exe RENAME python.exe - DESTINATION .) + DESTINATION bin) install(FILES ${MINGW_BIN}/python2w.exe RENAME pythonw.exe - DESTINATION .) + DESTINATION bin) install(FILES ${MINGW_BIN}/libpython2.7.dll - DESTINATION .) + DESTINATION bin) install(DIRECTORY ${MINGW_LIB}/python2.7 DESTINATION lib PATTERN "python2.7/site-packages" EXCLUDE # specify individual packages to install below diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index bfe00f7b0..d317cbeb1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -379,22 +379,10 @@ target_link_libraries(inkview inkscape_base) #Define the installation -if(NOT WIN32) - install(TARGETS - inkscape - inkview - RUNTIME DESTINATION bin) - if(BUILD_SHARED_LIBS) +install(TARGETS inkscape inkview RUNTIME DESTINATION bin) +if(WIN32) + install(TARGETS inkscape_com inkview_com) +endif() +if(BUILD_SHARED_LIBS) install(TARGETS inkscape_base LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/inkscape) - endif() -else() - install(TARGETS - inkscape - inkscape_com - inkview - inkview_com - RUNTIME DESTINATION .) - if(BUILD_SHARED_LIBS) - install(TARGETS inkscape_base RUNTIME DESTINATION .) - endif() endif() -- cgit v1.2.3 From 96b241fb243ab79600aaeb29b38f4d163e753bd3 Mon Sep 17 00:00:00 2001 From: Patrick Storz Date: Sun, 9 Jun 2019 01:25:47 +0200 Subject: CI: Update for move to bin/ Also add --working-directory switch to dependency checking script. --- buildtools/appveyor.sh | 8 ++--- buildtools/msys2checkdeps.py | 73 +++++++++++++++++++++++++------------------- 2 files changed, 46 insertions(+), 35 deletions(-) diff --git a/buildtools/appveyor.sh b/buildtools/appveyor.sh index cfd289886..36af0dcef 100644 --- a/buildtools/appveyor.sh +++ b/buildtools/appveyor.sh @@ -68,14 +68,14 @@ appveyor SetVariable -Name APPVEYOR_SAVE_CACHE_ON_ERROR -Value true # build succ # install message "--- Installing the project" ninja install || error "installation failed" -python ../buildtools/msys2checkdeps.py check inkscape/ || error "missing libraries in installed project" +python ../buildtools/msys2checkdeps.py check inkscape -w inkscape/bin || error "missing libraries in installed project" # test message "--- Running tests" # check if the installed executable works -inkscape/inkscape.exe -V || error "installed executable won't run" -PATH= inkscape/inkscape.exe -V >/dev/null || error "installed executable won't run with empty PATH (missing dependencies?)" -err=$(PATH= inkscape/inkscape.exe -V 2>&1 >/dev/null) +inkscape/bin/inkscape.exe -V || error "installed executable won't run" +PATH= inkscape/bin/inkscape.exe -V >/dev/null || error "installed executable won't run with empty PATH (missing dependencies?)" +err=$(PATH= inkscape/bin/inkscape.exe -V 2>&1 >/dev/null) if [ -n "$err" ]; then warning "installed executable produces output on stderr:"; echo "$err"; fi # check if the uninstalled executable works ninja inkscape_datadir_symlink diff --git a/buildtools/msys2checkdeps.py b/buildtools/msys2checkdeps.py index eebeea15c..3259a17db 100644 --- a/buildtools/msys2checkdeps.py +++ b/buildtools/msys2checkdeps.py @@ -2,24 +2,13 @@ # ------------------------------------------------------------------------------------------------------------------ # list or check dependencies for binary distributions based on MSYS2 (requires the package mingw-w64-ntldd) # -# Usage: -# python msys2checkdeps.py MODE PATH -# -# MODE -# list - list dependencies in human-readable form with full path and list of dependents -# list-compact - list dependencies in compact form (as a plain list of filenames) -# check - check for missing or unused dependencies (see below for details) -# check-missing - check if all required dependencies are present in PATH -# exits with error code 2 if missing dependencies are found and prints the list to stderr -# check-unused - check if any of the libraries in the root of PATH are unused and prints the list to stderr -# -# PATH -# full or relative path to a single file or a directory to work on (directories will be checked recursively) +# run './msys2checkdeps.py --help' for usage information # ------------------------------------------------------------------------------------------------------------------ from __future__ import print_function +import argparse import os import subprocess import sys @@ -101,10 +90,8 @@ def collect_dependencies(path): # - the corresponding value is an instance of class Dependency (containing full path and dependents) deps = {} if os.path.isfile(path): - os.chdir(os.path.dirname(path)) deps = get_dependencies(path, deps) elif os.path.isdir(path): - os.chdir(path) extensions = ['.exe', '.pyd', '.dll'] exclusions = ['python2.7/distutils/command/wininst'] for base, dirs, files in os.walk(path): @@ -118,22 +105,46 @@ def collect_dependencies(path): if __name__ == '__main__': - - # get mode from command line - mode = sys.argv[1] modes = ['list', 'list-compact', 'check', 'check-missing', 'check-unused'] - if mode not in modes: - error("First argument needs to be a valid mode (" + (', ').join(modes) + ").") - # get path from command line - path = sys.argv[2] - path = os.path.abspath(path) - if not os.path.exists(path): - error("Can't find file/folder '" + path + "'") - root = path if os.path.isdir(path) else os.path.dirname(path) + # parse arguments from command line + parser = argparse.ArgumentParser(description="List or check dependencies for binary distributions based on MSYS2.\n" + "(requires the package 'mingw-w64-ntldd')", + formatter_class=argparse.RawTextHelpFormatter) + parser.add_argument('mode', metavar="MODE", choices=modes, + help="One of the following:\n" + " list - list dependencies in human-readable form\n" + " with full path and list of dependents\n" + " list-compact - list dependencies in compact form (as a plain list of filenames)\n" + " check - check for missing or unused dependencies (see below for details)\n" + " check-missing - check if all required dependencies are present in PATH\n" + " exits with error code 2 if missing dependencies are found\n" + " and prints the list to stderr\n" + " check-unused - check if any of the libraries in the root of PATH are unused\n" + " and prints the list to stderr") + parser.add_argument('path', metavar='PATH', + help="full or relative path to a single file or a directory to work on\n" + "(directories will be checked recursively)") + parser.add_argument('-w', '--working-directory', metavar="DIR", + help="Use custom working directory (instead of 'dirname PATH')") + args = parser.parse_args() + + # check if path exists + args.path = os.path.abspath(args.path) + if not os.path.exists(args.path): + error("Can't find file/folder '" + args.path + "'") + + # get root and set it as working directory (unless one is explicitly specified) + if args.working_directory: + root = os.path.abspath(args.working_directory) + elif os.path.isdir(args.path): + root = args.path + elif os.path.isfile(args.path): + root = os.path.dirname(args.path) + os.chdir(root) # get dependencies for path recursively - deps = collect_dependencies(path) + deps = collect_dependencies(args.path) # print output / prepare exit code exit_code = 0 @@ -141,19 +152,19 @@ if __name__ == '__main__': location = deps[dep].location dependents = deps[dep].dependents - if mode == 'list': + if args.mode == 'list': if (location is None): location = '---MISSING---' print(dep + " - " + location + " (" + ", ".join(dependents) + ")") - elif mode == 'list-compact': + elif args.mode == 'list-compact': print(dep) - elif mode in ['check', 'check-missing']: + elif args.mode in ['check', 'check-missing']: if ((location is None) or (root not in os.path.abspath(location))): warning("Missing dependency " + dep + " (" + ", ".join(dependents) + ")") exit_code = 2 # check for unused libraries - if mode in ['check', 'check-unused']: + if args.mode in ['check', 'check-unused']: installed_libs = [file for file in os.listdir(root) if file.endswith(".dll")] deps_lower = [dep.lower() for dep in deps] top_level_libs = [lib for lib in installed_libs if lib.lower() not in deps_lower] -- cgit v1.2.3