From: Iceyer Date: Mon, 22 Jan 2018 08:10:31 +0000 (+0800) Subject: refactor: split tool to libdtkcore-bin X-Git-Tag: archive/raspbian/5.7.12-2+rpi1^2~130^2~15 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=3ebc7956f1f9d36d926ce571f1c5e29ee3ca9ef3;p=dtkcore.git refactor: split tool to libdtkcore-bin Change-Id: Ide59c0f11faea6592b2801daa41816336358ad85 --- diff --git a/debian/control b/debian/control index 92f6430..910fc9b 100644 --- a/debian/control +++ b/debian/control @@ -15,6 +15,14 @@ Description: Deepin Tool Kit Core library . This package contains the shared libraries. +Package: libdtkcore-bin +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends}, libdtkcore2( =${binary:Version}) +Description: Deepin Tool Kit Core Utilities + DtkCore is base devel library of Deepin Qt/C++ applications. + . + This package contains the utilities of DtkCore + Package: libdtkcore-dev Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends}, libdtkcore2( =${binary:Version}) diff --git a/debian/libdtkcore-bin.install b/debian/libdtkcore-bin.install new file mode 100644 index 0000000..b808e55 --- /dev/null +++ b/debian/libdtkcore-bin.install @@ -0,0 +1 @@ +usr/lib/dtk2/* diff --git a/debian/libdtkcore-dev.install b/debian/libdtkcore-dev.install index df188d8..60e21e3 100644 --- a/debian/libdtkcore-dev.install +++ b/debian/libdtkcore-dev.install @@ -1,6 +1,5 @@ usr/lib/*/lib*.so usr/include usr/lib/*/pkgconfig/*.pc -usr/lib/dtk2/* usr/lib/*/cmake/*/*.cmake usr/lib/*/libdtk/modules/* diff --git a/dtkcore.pro b/dtkcore.pro index c776e70..370c5fd 100644 --- a/dtkcore.pro +++ b/dtkcore.pro @@ -6,4 +6,4 @@ SUBDIRS += \ src \ tests -!mac:!win*: SUBDIRS += tool +!mac:!win*: SUBDIRS += tools diff --git a/tool/license/license-updater.py b/tool/license/license-updater.py deleted file mode 100644 index bc3a071..0000000 --- a/tool/license/license-updater.py +++ /dev/null @@ -1,320 +0,0 @@ -#!/usr/bin/env python - -import fnmatch -import os -import argparse -import re -import datetime - - -license_header = '''/*\n''' -license_empty = ''' *\n''' -license_copyright_prifix = ''' * Copyright (C) {0}\n''' -license_copyright_indent = ''' * {0}\n''' -license_author_prifix = ''' * Author: {0}\n''' -license_person_indent = ''' * {0}\n''' -license_maintainer_prifix = ''' * Maintainer: {0}\n''' -license_tail = ''' */\n\n''' -default_license_body = ''' * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -''' - - -def isInt(value): - try: - int(value) - return True - except ValueError: - return False - - -class Copyright: - def __init__(self, line): - self.year_start = datetime.datetime.now().year - self.year_end = datetime.datetime.now().year - - if "copyright" in line.lower(): - line = line[re.search("copyright", line, re.IGNORECASE).end():] - - copyright_sysbol = re.search("\(.\)", line, re.IGNORECASE) - if copyright_sysbol is not None: - copyright_brace_end_pos = copyright_sysbol.end() - line = line[copyright_brace_end_pos:] - pass - - if re.search("[0-9]+", line) is not None: - year_start_pos = re.search("[0-9]+", line).start() - year_start_end_pos = re.search("[0-9]+", line).end() - self.year_start = int(line[year_start_pos: year_start_end_pos]) - line = line[year_start_end_pos:] - - if re.search("[0-9]+", line) is not None: - year_end_pos = re.search("[0-9]+", line).start() - year_end_end_pos = re.search("[0-9]+", line).end() - if re.search("~", line) is not None: - year_spilt = re.search("~", line).start() - if (year_spilt < year_end_pos): - self.year_end = int(line[year_end_pos: year_end_end_pos]) - line = line[year_end_end_pos:] - - self.name = line.strip() - - def string(self): - return "{0} ~ {1} {2}".format( - self.year_start, - self.year_end, - self.name) - - -class Person: - def __init__(self, line): - if re.search(":", line, re.IGNORECASE) is not None: - split_end = re.search(":", line).end() - line = line[split_end:] - - self.name = line.strip() - - -def filter_files(file_list, ext_list): - for file in file_list: - for ext in ext_list: - if fnmatch.fnmatch(file, ext): - yield file - break - - -class Source: - def __init__(self, filename): - self.body = [] - self.copyrights = {} - self.authors = {} - self.maintainers = {} - self.filename = filename - self.is_deepin_copyright = False - self.update_license(filename) - - def update_license(self, filename): - find_license_start = False - find_license_end = False - - parse_copyright_start = False - parse_author_start = False - parse_maintainer_start = False - - with open(filename, "r") as f: - print("process:", filename) - for line in f: - if line.strip().startswith("/*") and (0 == len(self.body)): - find_license_start = True - - if (0 != len(self.body)) or (0 != len(line.strip())): - self.body.append(line) - - if "*/" in line.strip() and find_license_start: - if not find_license_end: - # print("clean body") - self.body = [] - find_license_end = True - - if find_license_start and not find_license_end: - if re.search("(\*)+", line): - # remove ***** - line = line[re.search("(\*)+", line).end():] - - if "copyright" in line.lower(): - parse_copyright_start = True - parse_author_start = False - parse_maintainer_start = False - if "author" in line.lower(): - parse_copyright_start = False - parse_author_start = True - parse_maintainer_start = False - if "maintainer" in line.lower(): - parse_copyright_start = False - parse_author_start = False - parse_maintainer_start = True - if 0 == len(line.strip()): - parse_copyright_start = False - parse_author_start = False - parse_maintainer_start = False - - if parse_copyright_start: - cr = Copyright(line) - self.copyrights[cr.name] = cr - - if parse_author_start: - p = Person(line) - self.authors[p.name] = p - - if parse_maintainer_start: - p = Person(line) - self.maintainers[p.name] = p - - def fix_deepin(self): - new_cr = {} - self.is_deepin_copyright = False - for k, cr in self.copyrights.items(): - if "deepin" in cr.name.lower(): - cr.name = "Deepin Technology Co., Ltd." - self.is_deepin_copyright = True - new_cr[cr.name] = cr - self.copyrights = new_cr - - def dump(self): - for cr in self.copyrights: - print(cr.year_start, cr.year_end, cr.name) - for a in self.authors: - print(a.name) - for a in self.maintainers: - print(a.name) - print("body size:", len(self.body)) - - def save(self): - wf = open(self.filename, 'w') - wf.write(license_header) - - if len(self.copyrights): - write_first = False - for k, cr in self.copyrights.items(): - if not write_first: - wf.write(license_copyright_prifix.format(cr.string())) - write_first = True - else: - wf.write(license_copyright_indent.format(cr.string())) - wf.write(license_empty) - - if len(self.authors): - write_first = False - for k, author in self.authors.items(): - if not write_first: - wf.write(license_author_prifix.format(author.name)) - write_first = True - else: - wf.write(license_person_indent.format(author.name)) - wf.write(license_empty) - - if len(self.maintainers): - write_first = False - for k, maintainer in self.maintainers.items(): - if not write_first: - wf.write(license_maintainer_prifix.format(maintainer.name)) - write_first = True - else: - wf.write(license_person_indent.format(maintainer.name)) - wf.write(license_empty) - - wf.write(default_license_body) - wf.write(license_tail) - - for l in self.body: - wf.write(l) - wf.close() - - -def parse_args(): - parser = argparse.ArgumentParser() - parser.add_argument('--authors', help='''authors split by ":". For example:\n - "Iceyer :Li He "''') - parser.add_argument('--maintainers', help='''maintainers split by ":". For example: \n - "Iceyer :Li He "''') - parser.add_argument('--copyrights', help='''copyrights split by ":". For example: \n - "2011 ~ 2017 Deepin Technology Co., Ltd.:2011 ~ 2017 Li He"''') - parser.add_argument('--fix-deepin', dest='fixdeepin', - action='store_const', const=True, default=False, help=''' - fix deein copyrights''') - parser.add_argument('dir', help=''' - source code dir''') - - args = parser.parse_args() - return args - - -def match_files(dir): - EXTENSIONS = "*.cpp", "*.c", "*.h", "*.go" - matches = [] - for root, dirnames, filenames in os.walk(dir): - for filename in filter_files(filenames, EXTENSIONS): - matches.append(os.path.join(root, filename)) - return matches - - -def test(): - cr = Copyright("Copyright (C) Deepin Technology Co., Ltd.") - print(cr.year_start, cr.year_end, cr.name) - cr = Copyright("Copyright (C) 2007 Deepin Technology Co., Ltd.") - print(cr.year_start, cr.year_end, cr.name) - cr = Copyright("Copyright (C) 2007 ~ 2016 Deepin Technology Co., Ltd.") - print(cr.year_start, cr.year_end, cr.name) - - p = Person("Author: Wang Yong ") - print(p.name) - p = Person(" Wang Yong ") - print(p.name) - - -def get_authors(args): - authors = [] - if args.authors is not None: - for a in args.authors.split(":"): - authors.append(Person(a)) - return authors - - -def get_copyrights(args): - copyrights = [] - if args.copyrights is not None: - for a in args.copyrights.split(":"): - copyrights.append(Copyright(a)) - return copyrights - - -def get_maintainers(args): - maintainers = [] - if args.maintainers is not None: - for a in args.maintainers.split(":"): - maintainers.append(Copyright(a)) - return maintainers - - -def main(): - args = parse_args() - authors = get_authors(args) - copyrights = get_copyrights(args) - maintainers = get_maintainers(args) - fixdeepin = args.fixdeepin - files = match_files(args.dir) - - for filename in files: - s = Source(filename) - # s.dump() - if fixdeepin: - s.fix_deepin() - if not s.is_deepin_copyright and 0 != len(s.copyrights): - continue - - if 0 == len(s.copyrights): - for cr in copyrights: - s.copyrights[cr.name] = cr - - for p in authors: - s.authors[p.name] = p - - for p in maintainers: - s.maintainers[p.name] = p - - s.save() - # s.dump() - - -if __name__ == "__main__": - main() diff --git a/tool/settings/main.cpp b/tool/settings/main.cpp deleted file mode 100644 index c976b85..0000000 --- a/tool/settings/main.cpp +++ /dev/null @@ -1,287 +0,0 @@ -/* - * Copyright (C) 2017 ~ 2017 Deepin Technology Co., Ltd. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include - -#include - -#include -#include -#include - -#include "settings/dsettings.h" -#include "settings/dsettingsgroup.h" -#include "settings/dsettingsoption.h" - -#include -#include -#include - -#include - -static QString CppTemplate = - "#include \n" - "\n" - "void GenerateSettingTranslate()\n" - "{\n" - "%1" - "}\n"; - -/* - * GVariant Type Name/Code C++ Type Name QVariant Type Name - * -------------------------------------------------------------------------- - * boolean b bool QVariant::Bool - * byte y char QVariant::Char - * int16 n int QVariant::Int - * uint16 q unsigned int QVariant::UInt - * int32 i int QVariant::Int - * uint32 u unsigned int QVariant::UInt - * int64 x long long QVariant::LongLong - * uint64 t unsigned long long QVariant::ULongLong - * double d double QVariant::Double - * string s QString QVariant::String - * string array* as QStringList QVariant::StringList - * byte array ay QByteArray QVariant::ByteArray - * dictionary a{ss} QVariantMap QVariant::Map -*/ - -QString gsettings_type_from_QVarint(const QVariant::Type qtype) -{ - switch (qtype) { - case QVariant::Bool: - return "b"; - case QVariant::Int: - return "i"; - case QVariant::UInt: - return "u"; - case QVariant::LongLong: - return "x"; - case QVariant::ULongLong: - return "t"; - case QVariant::Double: - return "d"; - case QVariant::String: - return "s"; - case QVariant::StringList: - return "as"; - case QVariant::ByteArray: - return "ay"; - case QVariant::Map: - return "a{ss}"; - default: - return ""; - } -} - -QString gsettings_value_from_QVarint(const QVariant value) -{ - switch (value.type()) { - case QVariant::Bool: - return value.toString(); - case QVariant::Int: - return value.toString(); - case QVariant::UInt: - return value.toString(); - case QVariant::LongLong: - return value.toString(); - case QVariant::ULongLong: - return value.toString(); - case QVariant::Double: - return value.toString(); - case QVariant::String: - return QString("\"%1\"").arg(value.toString()); - case QVariant::StringList: - return value.toString(); - case QVariant::ByteArray: - return value.toString(); - case QVariant::Map: - return value.toString(); - default: - return ""; - } -} - - -QJsonObject parseGSettingsMeta(const QString &jsonPath) -{ - QFile jsonFile(jsonPath); - jsonFile.open(QIODevice::ReadOnly); - auto jsonData = jsonFile.readAll(); - jsonFile.close(); - - QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonData); - return jsonDoc.object().value("gsettings").toObject(); -} - -static bool writeGSettingXML(Dtk::Core::DSettings *settings, - QJsonObject gsettingsMeta, - const QString &xmlPath) -{ - QDomDocument document; - - QDomProcessingInstruction header = document.createProcessingInstruction("xml", - "version=\"1.0\" encoding=\"utf-8\""); - document.appendChild(header); - - QDomElement schemalist = document.createElement("schemalist"); - - auto id = gsettingsMeta.value("id").toString(); - auto path = gsettingsMeta.value("path").toString(); - QDomElement schema = document.createElement("schema"); - schema.setAttribute("id", id); - schema.setAttribute("path", path); - - for (QString key : settings->keys()) { - auto codeKey = QString(key).replace(".", "-").replace("_", "-"); - auto value = settings->option(key)->value(); - auto gtype = gsettings_type_from_QVarint(value.type()); - if (gtype.isEmpty()) { - qDebug() << "skip unsupport type:" << value.type() << key; - continue; - } - - QDomElement keyXml = document.createElement("key"); - keyXml.setAttribute("name", codeKey); - keyXml.setAttribute("type", gtype); - - QString defaultData = gsettings_value_from_QVarint(value); - QDomElement defaultEle = document.createElement("default"); - QDomCharacterData data = document.createTextNode(defaultData); - defaultEle.appendChild(data); - keyXml.appendChild(defaultEle); - - schema.appendChild(keyXml); - } - - schemalist.appendChild(schema); - document.appendChild(schemalist); - - QFile file(xmlPath); - if (!file.open(QIODevice::WriteOnly)) { - return false; - } - QTextStream stream(&file); - stream << document.toString(); - file.close(); - return true; -} - -int main(int argc, char *argv[]) -{ - QCoreApplication app(argc, argv); - app.setOrganizationName("deepin"); - app.setApplicationName("dtk-settings-tools"); - app.setApplicationVersion("0.1.2"); - - QCommandLineParser parser; - parser.setApplicationDescription("Generate translation of dtksetting."); - parser.addHelpOption(); - parser.addVersionOption(); - - QCommandLineOption gsettingsArg(QStringList() << "g" << "gsettings", - QCoreApplication::tr("generate gsetting schema"), - "xml-file"); - - QCommandLineOption outputFileArg(QStringList() << "o" << "output", - QCoreApplication::tr("Output cpp file"), - "cpp-file"); - parser.addOption(gsettingsArg); - parser.addOption(outputFileArg); - parser.addPositionalArgument("json-file", QCoreApplication::tr("Json file description config")); - parser.process(app); - - if (0 == (parser.optionNames().length() + parser.positionalArguments().length())) { - parser.showHelp(0); - } - - auto jsonFile = parser.positionalArguments().value(0); - auto settings = Dtk::Core::DSettings::fromJsonFile(jsonFile); - - QMap transtaleMaps; - -// qDebug() << settings->groupKeys(); - for (QString groupKey : settings->groupKeys()) { - auto codeKey = QString(groupKey).replace(".", "_"); - auto group = settings->group(groupKey); -// qDebug() << codeKey << group->name(); - // add Name - if (!group->name().isEmpty()) { - transtaleMaps.insert("group_" + codeKey + "Name", group->name()); - } - - // TODO: only two level - for (auto childGroup : group->childGroups()) { - auto codeKey = childGroup->key().replace(".", "_"); -// qDebug() << codeKey << childGroup->name(); - // add Name - if (!childGroup->name().isEmpty()) { - transtaleMaps.insert("group_" + codeKey + "Name", childGroup->name()); - } - } - } - - for (QString key : settings->keys()) { - auto codeKey = QString(key).replace(".", "_"); - auto opt = settings->option(key); - - // add Name - if (!opt->name().isEmpty()) { - transtaleMaps.insert(codeKey + "Name", opt->name()); - } - - // add text - if (!opt->data("text").toString().isEmpty()) { - transtaleMaps.insert(codeKey + "Text", opt->data("text").toString()); - } - - // add items - if (!opt->data("items").toStringList().isEmpty()) { - auto items = opt->data("items").toStringList(); - for (int i = 0; i < items.length(); ++i) { - transtaleMaps.insert(codeKey + QString("Text%1").arg(i), items.value(i)); - } - } - } - - transtaleMaps.insert("reset_button_name", "Restore Defaults"); - - QString cppCode; - for (auto key : transtaleMaps.keys()) { - auto stringCode = QString(" auto %1 = QObject::tr(\"%2\");\n").arg(key).arg(transtaleMaps.value(key)); - cppCode.append(stringCode); - } - - - if (parser.isSet(outputFileArg)) { - QString outputCpp = CppTemplate.arg(cppCode); - QFile outputFile(parser.value(outputFileArg)); - if (!outputFile.open(QIODevice::WriteOnly)) { - qCritical() << "can not open output file!"; - exit(1); - } - outputFile.write(outputCpp.toUtf8()); - outputFile.close(); - } - - if (parser.isSet(gsettingsArg)) { - QString outputXml = parser.value(gsettingsArg); - writeGSettingXML(settings, parseGSettingsMeta(jsonFile), outputXml); - } - - return 0; -} - diff --git a/tool/settings/settings.pro b/tool/settings/settings.pro deleted file mode 100644 index 8dcb34c..0000000 --- a/tool/settings/settings.pro +++ /dev/null @@ -1,29 +0,0 @@ -QT += core xml -QT -= gui - -CONFIG += c++11 - -TARGET = dtk-settings-tool -CONFIG += console link_pkgconfig -CONFIG -= app_bundle -PKGCONFIG += gsettings-qt - -TEMPLATE = app - -SOURCES += main.cpp - -isEmpty(PREFIX){ - PREFIX = /usr -} - -binary.files += $${OUT_PWD}/dtk-settings-tool -binary.path = $${PREFIX}/lib/dtk2 - -INSTALLS += binary - -win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../../src/release/ -ldtkcore -else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../../src/debug/ -ldtkcore -else:unix: LIBS += -L$$OUT_PWD/../../src/ -ldtkcore - -INCLUDEPATH += $$PWD/../../src -DEPENDPATH += $$PWD/../../src diff --git a/tool/tool.pro b/tool/tool.pro deleted file mode 100644 index aeaeb47..0000000 --- a/tool/tool.pro +++ /dev/null @@ -1,6 +0,0 @@ -TEMPLATE = subdirs - -CONFIG += ordered - -SUBDIRS += \ - settings \ diff --git a/tools/script/dtk-license.py b/tools/script/dtk-license.py new file mode 100644 index 0000000..bc3a071 --- /dev/null +++ b/tools/script/dtk-license.py @@ -0,0 +1,320 @@ +#!/usr/bin/env python + +import fnmatch +import os +import argparse +import re +import datetime + + +license_header = '''/*\n''' +license_empty = ''' *\n''' +license_copyright_prifix = ''' * Copyright (C) {0}\n''' +license_copyright_indent = ''' * {0}\n''' +license_author_prifix = ''' * Author: {0}\n''' +license_person_indent = ''' * {0}\n''' +license_maintainer_prifix = ''' * Maintainer: {0}\n''' +license_tail = ''' */\n\n''' +default_license_body = ''' * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +''' + + +def isInt(value): + try: + int(value) + return True + except ValueError: + return False + + +class Copyright: + def __init__(self, line): + self.year_start = datetime.datetime.now().year + self.year_end = datetime.datetime.now().year + + if "copyright" in line.lower(): + line = line[re.search("copyright", line, re.IGNORECASE).end():] + + copyright_sysbol = re.search("\(.\)", line, re.IGNORECASE) + if copyright_sysbol is not None: + copyright_brace_end_pos = copyright_sysbol.end() + line = line[copyright_brace_end_pos:] + pass + + if re.search("[0-9]+", line) is not None: + year_start_pos = re.search("[0-9]+", line).start() + year_start_end_pos = re.search("[0-9]+", line).end() + self.year_start = int(line[year_start_pos: year_start_end_pos]) + line = line[year_start_end_pos:] + + if re.search("[0-9]+", line) is not None: + year_end_pos = re.search("[0-9]+", line).start() + year_end_end_pos = re.search("[0-9]+", line).end() + if re.search("~", line) is not None: + year_spilt = re.search("~", line).start() + if (year_spilt < year_end_pos): + self.year_end = int(line[year_end_pos: year_end_end_pos]) + line = line[year_end_end_pos:] + + self.name = line.strip() + + def string(self): + return "{0} ~ {1} {2}".format( + self.year_start, + self.year_end, + self.name) + + +class Person: + def __init__(self, line): + if re.search(":", line, re.IGNORECASE) is not None: + split_end = re.search(":", line).end() + line = line[split_end:] + + self.name = line.strip() + + +def filter_files(file_list, ext_list): + for file in file_list: + for ext in ext_list: + if fnmatch.fnmatch(file, ext): + yield file + break + + +class Source: + def __init__(self, filename): + self.body = [] + self.copyrights = {} + self.authors = {} + self.maintainers = {} + self.filename = filename + self.is_deepin_copyright = False + self.update_license(filename) + + def update_license(self, filename): + find_license_start = False + find_license_end = False + + parse_copyright_start = False + parse_author_start = False + parse_maintainer_start = False + + with open(filename, "r") as f: + print("process:", filename) + for line in f: + if line.strip().startswith("/*") and (0 == len(self.body)): + find_license_start = True + + if (0 != len(self.body)) or (0 != len(line.strip())): + self.body.append(line) + + if "*/" in line.strip() and find_license_start: + if not find_license_end: + # print("clean body") + self.body = [] + find_license_end = True + + if find_license_start and not find_license_end: + if re.search("(\*)+", line): + # remove ***** + line = line[re.search("(\*)+", line).end():] + + if "copyright" in line.lower(): + parse_copyright_start = True + parse_author_start = False + parse_maintainer_start = False + if "author" in line.lower(): + parse_copyright_start = False + parse_author_start = True + parse_maintainer_start = False + if "maintainer" in line.lower(): + parse_copyright_start = False + parse_author_start = False + parse_maintainer_start = True + if 0 == len(line.strip()): + parse_copyright_start = False + parse_author_start = False + parse_maintainer_start = False + + if parse_copyright_start: + cr = Copyright(line) + self.copyrights[cr.name] = cr + + if parse_author_start: + p = Person(line) + self.authors[p.name] = p + + if parse_maintainer_start: + p = Person(line) + self.maintainers[p.name] = p + + def fix_deepin(self): + new_cr = {} + self.is_deepin_copyright = False + for k, cr in self.copyrights.items(): + if "deepin" in cr.name.lower(): + cr.name = "Deepin Technology Co., Ltd." + self.is_deepin_copyright = True + new_cr[cr.name] = cr + self.copyrights = new_cr + + def dump(self): + for cr in self.copyrights: + print(cr.year_start, cr.year_end, cr.name) + for a in self.authors: + print(a.name) + for a in self.maintainers: + print(a.name) + print("body size:", len(self.body)) + + def save(self): + wf = open(self.filename, 'w') + wf.write(license_header) + + if len(self.copyrights): + write_first = False + for k, cr in self.copyrights.items(): + if not write_first: + wf.write(license_copyright_prifix.format(cr.string())) + write_first = True + else: + wf.write(license_copyright_indent.format(cr.string())) + wf.write(license_empty) + + if len(self.authors): + write_first = False + for k, author in self.authors.items(): + if not write_first: + wf.write(license_author_prifix.format(author.name)) + write_first = True + else: + wf.write(license_person_indent.format(author.name)) + wf.write(license_empty) + + if len(self.maintainers): + write_first = False + for k, maintainer in self.maintainers.items(): + if not write_first: + wf.write(license_maintainer_prifix.format(maintainer.name)) + write_first = True + else: + wf.write(license_person_indent.format(maintainer.name)) + wf.write(license_empty) + + wf.write(default_license_body) + wf.write(license_tail) + + for l in self.body: + wf.write(l) + wf.close() + + +def parse_args(): + parser = argparse.ArgumentParser() + parser.add_argument('--authors', help='''authors split by ":". For example:\n + "Iceyer :Li He "''') + parser.add_argument('--maintainers', help='''maintainers split by ":". For example: \n + "Iceyer :Li He "''') + parser.add_argument('--copyrights', help='''copyrights split by ":". For example: \n + "2011 ~ 2017 Deepin Technology Co., Ltd.:2011 ~ 2017 Li He"''') + parser.add_argument('--fix-deepin', dest='fixdeepin', + action='store_const', const=True, default=False, help=''' + fix deein copyrights''') + parser.add_argument('dir', help=''' + source code dir''') + + args = parser.parse_args() + return args + + +def match_files(dir): + EXTENSIONS = "*.cpp", "*.c", "*.h", "*.go" + matches = [] + for root, dirnames, filenames in os.walk(dir): + for filename in filter_files(filenames, EXTENSIONS): + matches.append(os.path.join(root, filename)) + return matches + + +def test(): + cr = Copyright("Copyright (C) Deepin Technology Co., Ltd.") + print(cr.year_start, cr.year_end, cr.name) + cr = Copyright("Copyright (C) 2007 Deepin Technology Co., Ltd.") + print(cr.year_start, cr.year_end, cr.name) + cr = Copyright("Copyright (C) 2007 ~ 2016 Deepin Technology Co., Ltd.") + print(cr.year_start, cr.year_end, cr.name) + + p = Person("Author: Wang Yong ") + print(p.name) + p = Person(" Wang Yong ") + print(p.name) + + +def get_authors(args): + authors = [] + if args.authors is not None: + for a in args.authors.split(":"): + authors.append(Person(a)) + return authors + + +def get_copyrights(args): + copyrights = [] + if args.copyrights is not None: + for a in args.copyrights.split(":"): + copyrights.append(Copyright(a)) + return copyrights + + +def get_maintainers(args): + maintainers = [] + if args.maintainers is not None: + for a in args.maintainers.split(":"): + maintainers.append(Copyright(a)) + return maintainers + + +def main(): + args = parse_args() + authors = get_authors(args) + copyrights = get_copyrights(args) + maintainers = get_maintainers(args) + fixdeepin = args.fixdeepin + files = match_files(args.dir) + + for filename in files: + s = Source(filename) + # s.dump() + if fixdeepin: + s.fix_deepin() + if not s.is_deepin_copyright and 0 != len(s.copyrights): + continue + + if 0 == len(s.copyrights): + for cr in copyrights: + s.copyrights[cr.name] = cr + + for p in authors: + s.authors[p.name] = p + + for p in maintainers: + s.maintainers[p.name] = p + + s.save() + # s.dump() + + +if __name__ == "__main__": + main() diff --git a/tools/script/dtk-translate.py b/tools/script/dtk-translate.py new file mode 100644 index 0000000..9cb06f8 --- /dev/null +++ b/tools/script/dtk-translate.py @@ -0,0 +1,18 @@ +#!env python + +import sys,os,fnmatch +from subprocess import call + +translations_dir = os.getcwd() + "/translations" +if (len(sys.argv) == 2): + translations_dir = sys.argv[1] + "/translations" + +print("set translations dir:", translations_dir) + +tslist = fnmatch.filter(os.listdir(translations_dir), '*.ts') + +# This would print all the files and directories +for tsfile in tslist: + tspath = translations_dir + "/" + tsfile + print ("process", tspath) + call(["lrelease", tspath]) diff --git a/tools/settings/main.cpp b/tools/settings/main.cpp new file mode 100644 index 0000000..c976b85 --- /dev/null +++ b/tools/settings/main.cpp @@ -0,0 +1,287 @@ +/* + * Copyright (C) 2017 ~ 2017 Deepin Technology Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include + +#include +#include +#include + +#include "settings/dsettings.h" +#include "settings/dsettingsgroup.h" +#include "settings/dsettingsoption.h" + +#include +#include +#include + +#include + +static QString CppTemplate = + "#include \n" + "\n" + "void GenerateSettingTranslate()\n" + "{\n" + "%1" + "}\n"; + +/* + * GVariant Type Name/Code C++ Type Name QVariant Type Name + * -------------------------------------------------------------------------- + * boolean b bool QVariant::Bool + * byte y char QVariant::Char + * int16 n int QVariant::Int + * uint16 q unsigned int QVariant::UInt + * int32 i int QVariant::Int + * uint32 u unsigned int QVariant::UInt + * int64 x long long QVariant::LongLong + * uint64 t unsigned long long QVariant::ULongLong + * double d double QVariant::Double + * string s QString QVariant::String + * string array* as QStringList QVariant::StringList + * byte array ay QByteArray QVariant::ByteArray + * dictionary a{ss} QVariantMap QVariant::Map +*/ + +QString gsettings_type_from_QVarint(const QVariant::Type qtype) +{ + switch (qtype) { + case QVariant::Bool: + return "b"; + case QVariant::Int: + return "i"; + case QVariant::UInt: + return "u"; + case QVariant::LongLong: + return "x"; + case QVariant::ULongLong: + return "t"; + case QVariant::Double: + return "d"; + case QVariant::String: + return "s"; + case QVariant::StringList: + return "as"; + case QVariant::ByteArray: + return "ay"; + case QVariant::Map: + return "a{ss}"; + default: + return ""; + } +} + +QString gsettings_value_from_QVarint(const QVariant value) +{ + switch (value.type()) { + case QVariant::Bool: + return value.toString(); + case QVariant::Int: + return value.toString(); + case QVariant::UInt: + return value.toString(); + case QVariant::LongLong: + return value.toString(); + case QVariant::ULongLong: + return value.toString(); + case QVariant::Double: + return value.toString(); + case QVariant::String: + return QString("\"%1\"").arg(value.toString()); + case QVariant::StringList: + return value.toString(); + case QVariant::ByteArray: + return value.toString(); + case QVariant::Map: + return value.toString(); + default: + return ""; + } +} + + +QJsonObject parseGSettingsMeta(const QString &jsonPath) +{ + QFile jsonFile(jsonPath); + jsonFile.open(QIODevice::ReadOnly); + auto jsonData = jsonFile.readAll(); + jsonFile.close(); + + QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonData); + return jsonDoc.object().value("gsettings").toObject(); +} + +static bool writeGSettingXML(Dtk::Core::DSettings *settings, + QJsonObject gsettingsMeta, + const QString &xmlPath) +{ + QDomDocument document; + + QDomProcessingInstruction header = document.createProcessingInstruction("xml", + "version=\"1.0\" encoding=\"utf-8\""); + document.appendChild(header); + + QDomElement schemalist = document.createElement("schemalist"); + + auto id = gsettingsMeta.value("id").toString(); + auto path = gsettingsMeta.value("path").toString(); + QDomElement schema = document.createElement("schema"); + schema.setAttribute("id", id); + schema.setAttribute("path", path); + + for (QString key : settings->keys()) { + auto codeKey = QString(key).replace(".", "-").replace("_", "-"); + auto value = settings->option(key)->value(); + auto gtype = gsettings_type_from_QVarint(value.type()); + if (gtype.isEmpty()) { + qDebug() << "skip unsupport type:" << value.type() << key; + continue; + } + + QDomElement keyXml = document.createElement("key"); + keyXml.setAttribute("name", codeKey); + keyXml.setAttribute("type", gtype); + + QString defaultData = gsettings_value_from_QVarint(value); + QDomElement defaultEle = document.createElement("default"); + QDomCharacterData data = document.createTextNode(defaultData); + defaultEle.appendChild(data); + keyXml.appendChild(defaultEle); + + schema.appendChild(keyXml); + } + + schemalist.appendChild(schema); + document.appendChild(schemalist); + + QFile file(xmlPath); + if (!file.open(QIODevice::WriteOnly)) { + return false; + } + QTextStream stream(&file); + stream << document.toString(); + file.close(); + return true; +} + +int main(int argc, char *argv[]) +{ + QCoreApplication app(argc, argv); + app.setOrganizationName("deepin"); + app.setApplicationName("dtk-settings-tools"); + app.setApplicationVersion("0.1.2"); + + QCommandLineParser parser; + parser.setApplicationDescription("Generate translation of dtksetting."); + parser.addHelpOption(); + parser.addVersionOption(); + + QCommandLineOption gsettingsArg(QStringList() << "g" << "gsettings", + QCoreApplication::tr("generate gsetting schema"), + "xml-file"); + + QCommandLineOption outputFileArg(QStringList() << "o" << "output", + QCoreApplication::tr("Output cpp file"), + "cpp-file"); + parser.addOption(gsettingsArg); + parser.addOption(outputFileArg); + parser.addPositionalArgument("json-file", QCoreApplication::tr("Json file description config")); + parser.process(app); + + if (0 == (parser.optionNames().length() + parser.positionalArguments().length())) { + parser.showHelp(0); + } + + auto jsonFile = parser.positionalArguments().value(0); + auto settings = Dtk::Core::DSettings::fromJsonFile(jsonFile); + + QMap transtaleMaps; + +// qDebug() << settings->groupKeys(); + for (QString groupKey : settings->groupKeys()) { + auto codeKey = QString(groupKey).replace(".", "_"); + auto group = settings->group(groupKey); +// qDebug() << codeKey << group->name(); + // add Name + if (!group->name().isEmpty()) { + transtaleMaps.insert("group_" + codeKey + "Name", group->name()); + } + + // TODO: only two level + for (auto childGroup : group->childGroups()) { + auto codeKey = childGroup->key().replace(".", "_"); +// qDebug() << codeKey << childGroup->name(); + // add Name + if (!childGroup->name().isEmpty()) { + transtaleMaps.insert("group_" + codeKey + "Name", childGroup->name()); + } + } + } + + for (QString key : settings->keys()) { + auto codeKey = QString(key).replace(".", "_"); + auto opt = settings->option(key); + + // add Name + if (!opt->name().isEmpty()) { + transtaleMaps.insert(codeKey + "Name", opt->name()); + } + + // add text + if (!opt->data("text").toString().isEmpty()) { + transtaleMaps.insert(codeKey + "Text", opt->data("text").toString()); + } + + // add items + if (!opt->data("items").toStringList().isEmpty()) { + auto items = opt->data("items").toStringList(); + for (int i = 0; i < items.length(); ++i) { + transtaleMaps.insert(codeKey + QString("Text%1").arg(i), items.value(i)); + } + } + } + + transtaleMaps.insert("reset_button_name", "Restore Defaults"); + + QString cppCode; + for (auto key : transtaleMaps.keys()) { + auto stringCode = QString(" auto %1 = QObject::tr(\"%2\");\n").arg(key).arg(transtaleMaps.value(key)); + cppCode.append(stringCode); + } + + + if (parser.isSet(outputFileArg)) { + QString outputCpp = CppTemplate.arg(cppCode); + QFile outputFile(parser.value(outputFileArg)); + if (!outputFile.open(QIODevice::WriteOnly)) { + qCritical() << "can not open output file!"; + exit(1); + } + outputFile.write(outputCpp.toUtf8()); + outputFile.close(); + } + + if (parser.isSet(gsettingsArg)) { + QString outputXml = parser.value(gsettingsArg); + writeGSettingXML(settings, parseGSettingsMeta(jsonFile), outputXml); + } + + return 0; +} + diff --git a/tools/settings/settings.pro b/tools/settings/settings.pro new file mode 100644 index 0000000..e973d88 --- /dev/null +++ b/tools/settings/settings.pro @@ -0,0 +1,32 @@ +QT += core xml +QT -= gui + +CONFIG += c++11 + +TARGET = dtk-settings +CONFIG += console link_pkgconfig +CONFIG -= app_bundle +PKGCONFIG += gsettings-qt + +TEMPLATE = app + +SOURCES += main.cpp + +isEmpty(PREFIX){ + PREFIX = /usr +} + +binary.files += $${OUT_PWD}/dtk-settings +binary.path = $${PREFIX}/lib/dtk2/libexec + +script.files += $${PWD}/../script/*.py +script.path = $${PREFIX}/lib/dtk2 + +INSTALLS += binary script + +win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../../src/release/ -ldtkcore +else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../../src/debug/ -ldtkcore +else:unix: LIBS += -L$$OUT_PWD/../../src/ -ldtkcore + +INCLUDEPATH += $$PWD/../../src +DEPENDPATH += $$PWD/../../src diff --git a/tools/tools.pro b/tools/tools.pro new file mode 100644 index 0000000..aeaeb47 --- /dev/null +++ b/tools/tools.pro @@ -0,0 +1,6 @@ +TEMPLATE = subdirs + +CONFIG += ordered + +SUBDIRS += \ + settings \