~ubuntu-branches/debian/sid/texstudio/sid

« back to all changes in this revision

Viewing changes to smallUsefulFunctions.cpp

  • Committer: Package Import Robot
  • Author(s): Tom Jampen
  • Date: 2014-08-18 06:45:11 UTC
  • mfrom: (1.1.7)
  • Revision ID: package-import@ubuntu.com-20140818064511-bqd8ler67yofnt6q
Tags: 2.8.2+debian-1
* Merging upstream version 2.8.2+debian.
* Regenerating 01-use-libhunspell.patch.
* Updating 02-fix-desktop.patch.
* Regenerating 03-disable-auto-update.patch.
* Regenerating 04-no-qt-translations.patch.
* Regenerating 05-use-libsynctex.patch.
* Updating year in copyright file.
* Removing texstudio.svg from install file, fixed upstream.
* Rebuilding upstream tarball without:
  - conflicting debian directory
  - unused hunspell directory
  - unused include_win32 directory
  - unused include_win32_qt5 directory
  - unused qt translations
  - unused dictionary and thesaurus files
  - unused TexTablet directory
  - unused poppler-data directory

Show diffs side-by-side

added added

removed removed

Lines of Context:
857
857
}
858
858
 
859
859
void LatexParser::resolveCommandOptions(const QString &line, int column, QStringList &values, QList<int> *starts){
860
 
        const QString BracketsOpen("[{");
861
 
        const QString BracketsClose("]}");
 
860
    const QString BracketsOpen("[{(");
 
861
    const QString BracketsClose("]})");
862
862
        int start=column;
863
863
    int stop=-1;
864
864
        int type;
935
935
}
936
936
 
937
937
int LatexParser::findContext(QString &line,int &column) const{
 
938
    /* return a number for a context
 
939
     * 0 unknown
 
940
     * 1 command
 
941
     * 2 option \command[option]{arg}
 
942
     * 3 argument \command{arg}
 
943
     * 4 argument 2   \command{arg}{arg2}
 
944
     * etc
 
945
     */
938
946
        if(line.isEmpty())
939
947
                return 0;
940
 
    QString eow="\\[]{} $";
 
948
    QString eow="\\[]{}$";
941
949
        int i=column;
942
950
        if(i>=line.length())
943
951
                i=line.length();
965
973
        int ret=0;
966
974
        if(start_ref>start_opt){
967
975
                // assuming we are in command argument
968
 
                ret=2;
 
976
        ret=3;
969
977
                i=start_ref-1;
970
978
        }else{
971
979
                if(start_opt>-1){
972
980
                        //assuming we are in command option
973
 
                        ret=3;
 
981
            ret=2;
974
982
                        i=start_opt-1;
975
983
                }
976
984
        }
981
989
        QString openBrackets="[{";
982
990
        QString closeBrackets="]}";
983
991
        eow=getCommonEOW();
 
992
    eow.remove(' ');
984
993
        int stop=i;
985
994
        while (i>-1) {
986
995
                ch=line.at(i);
995
1004
                }
996
1005
                if(closeBrackets.contains(ch)){
997
1006
                        n++;
 
1007
            if(ch=='}')
 
1008
                ++ret;  //going through another braces pair, [] is not checked
998
1009
                        i--;
999
1010
                        continue;
1000
1011
                }
1001
1012
                if(n==0 && eow.contains(ch)){
1002
1013
                        if(ch=='\\'){
1003
1014
                                //TODO: check if not \\ (newline) was found
1004
 
                                line=line.mid(i,stop-i+1);
 
1015
                line=line.mid(i,stop-i+1).simplified();
1005
1016
                                column=i;
1006
1017
                                return ret;
1007
1018
                        }else{ // this is a overly strict interpretation of command syntax
1023
1034
        value="";
1024
1035
        if(!vals.isEmpty()){
1025
1036
                value=vals.takeFirst();
1026
 
        if(value.startsWith('[') && temp<3){
 
1037
        if(value.startsWith('[') && temp!=2){
1027
1038
                        if(!vals.isEmpty()){
1028
1039
                                value=vals.takeFirst();
1029
1040
                        }
1032
1043
                        value.remove(0,1);
1033
1044
        if(value.endsWith('}')||value.endsWith(']'))
1034
1045
                        value.chop(1);
1035
 
        }
 
1046
    }
1036
1047
        switch (temp) {
1037
1048
        case 0: return Unknown;
1038
1049
        case 1: return Command;
1039
 
        case 2:
 
1050
    case 3:
 
1051
        if(specialTreatmentCommands.contains(command)){
 
1052
            QSet<QPair<QString,int> > helper=specialTreatmentCommands.value(command);
 
1053
            QPair<QString,int> elem;
 
1054
            foreach(elem,helper){
 
1055
                if(elem.second==1)
 
1056
                    return ArgEx;
 
1057
            }
 
1058
        }
 
1059
        // check key/val
 
1060
        {
 
1061
            QStringList keys=possibleCommands.keys();
 
1062
            bool handled=false;
 
1063
            QString elem;
 
1064
            QStringList checkOptions;
 
1065
            checkOptions <<  "key%1"+command << "key%1"+command+"#c";
 
1066
 
 
1067
            foreach(elem,checkOptions){
 
1068
                if(keys.contains(elem)){
 
1069
                    handled=true;
 
1070
                    command=elem.mid(4);
 
1071
                    break;
 
1072
                }
 
1073
            }
 
1074
 
 
1075
            if(handled){
 
1076
                // check that cursor is within keyval
 
1077
                bool isKey=false;
 
1078
                for(int i=col;col>0;col--){
 
1079
                    if(line.at(i-1).isLetter())
 
1080
                        continue;
 
1081
                    if(line.at(i-1)=='{' || line.at(i-1)==',')
 
1082
                        isKey=true;
 
1083
                    break;
 
1084
                }
 
1085
                if(isKey)
 
1086
                    return Keyval;
 
1087
                else
 
1088
                    return KeyvalValue;
 
1089
            }
 
1090
        }
 
1091
        // normal context
1040
1092
                if (environmentCommands.contains(command))
1041
1093
                        return Environment;
1042
1094
        else if (possibleCommands["%label"].contains(command))
1052
1104
        else if (possibleCommands["%graphics"].contains(command))
1053
1105
            return Graphics;
1054
1106
                else return Option;
1055
 
    case 3:
 
1107
    case 2:
1056
1108
        // find possible commands for keyval completion
1057
1109
        {
1058
 
            /*QString elem;
1059
 
            foreach(elem,possibleCommands.keys()){
1060
 
                if(elem.startsWith("key%") && (elem.mid(4)==command || elem.mid(4)==command+"#c"))
1061
 
                    break;
1062
 
                elem.clear();
1063
 
            }*/
 
1110
            if(specialTreatmentCommands.contains(command)){
 
1111
                QSet<QPair<QString,int> > helper=specialTreatmentCommands.value(command);
 
1112
                QPair<QString,int> elem;
 
1113
                foreach(elem,helper){
 
1114
                    if(elem.second==0)
 
1115
                        return OptionEx;
 
1116
                }
 
1117
            }
1064
1118
            QStringList keys=possibleCommands.keys();
1065
1119
            QString arg;
1066
1120
            if(!vals.isEmpty()){
1225
1279
        return s;
1226
1280
}
1227
1281
 
 
1282
QString removePathDelim(const QString &s) {
 
1283
        // we use the explicit chars intentionally and not QDir::separator()
 
1284
        // because it shall also work for / on windows (many paths are internally
 
1285
        // represented with / as delimiter
 
1286
        if (s.endsWith('/') || s.endsWith('\\')) {
 
1287
                return s.left(s.length()-1);
 
1288
        }
 
1289
        return s;
 
1290
}
1228
1291
 
1229
1292
QTextCodec* QTextCodecForTeXShopName(const QByteArray& enc){
1230
1293
        //copied and modified from texworks
1526
1589
                    environmentAliases.insert(key,value);
1527
1590
            }
1528
1591
        }
 
1592
    specialTreatmentCommands.unite(elem.specialTreatmentCommands);
 
1593
    specialDefCommands.unite(elem.specialDefCommands);
1529
1594
}
1530
1595
 
1531
1596
void LatexParser::clear(){
1703
1768
        this->wordStartIndex = 0;
1704
1769
}
1705
1770
 
1706
 
LatexPackage loadCwlFile(const QString fileName,LatexCompleterConfig *config) {
 
1771
LatexPackage loadCwlFile(const QString fileName,LatexCompleterConfig *config,QStringList conditions) {
1707
1772
        QStringList words;
1708
1773
        QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
1709
1774
        LatexPackage package;
1714
1779
        QString fn=findResourceFile("completion/"+fileName,false,addPaths);
1715
1780
        
1716
1781
        QFile tagsfile(fn);
 
1782
    bool skipSection=false;
1717
1783
        if (!fn.isEmpty() && tagsfile.open(QFile::ReadOnly)) {
1718
1784
            QString line;
1719
1785
            QTextStream stream(&tagsfile);
1720
1786
                stream.setCodec("UTF-8");
1721
1787
            QRegExp rxCom("^(\\\\\\w+\\*?)(\\[.+\\])*\\{(.*)\\}");
1722
1788
            QRegExp rxCom2("^(\\\\\\w+\\*?)\\[(.+)\\]");
 
1789
        QRegExp rxCom3("^(\\\\\\w+\\*?)");
1723
1790
            rxCom.setMinimal(true);
1724
1791
            QStringList keywords;
1725
1792
            keywords << "text" << "title";
 
1793
        QStringList specialTreatment;
 
1794
        specialTreatment << "color";
1726
1795
        QString keyvals;
1727
1796
            while (!stream.atEnd()) {
1728
1797
                line = stream.readLine().trimmed();
 
1798
        if(line.startsWith("#endif")){
 
1799
            // end of conditional section
 
1800
            skipSection=false;
 
1801
            continue;
 
1802
        }
 
1803
        if(line.startsWith("#ifOption:")){
 
1804
            QString condition=line.mid(10);
 
1805
            skipSection=!conditions.contains(condition);
 
1806
            continue;
 
1807
        }
 
1808
        if(skipSection) // skip conditional sections (if condition is not met)
 
1809
            continue;
 
1810
 
 
1811
 
1729
1812
                if(line.startsWith("#include:")){
1730
1813
                    //include additional cwl file
1731
1814
                    QString fn=line.mid(9);
1744
1827
            keyvals.clear();
1745
1828
            continue;
1746
1829
        }
 
1830
 
1747
1831
        if(!keyvals.isEmpty()){
1748
1832
            // read keyval (name stored in "keyvals")
1749
1833
            package.possibleCommands["key%"+keyvals] << line;
1760
1844
                    int sep=line.indexOf('#');
1761
1845
                    QString valid;
1762
1846
                    QStringList env;
 
1847
            QString definition;
1763
1848
                    bool uncommon=false;
1764
1849
                    bool hideFromCompletion=false;
1765
1850
                    if(sep>-1){
1769
1854
                                        valid=valid.mid(1);
1770
1855
                                        uncommon=true;
1771
1856
                                }
 
1857
                // second time split for specialDef
 
1858
                int sep=valid.indexOf('#');
 
1859
                if(sep>-1){
 
1860
                    definition=valid.mid(sep+1);
 
1861
                    valid=valid.left(sep);
 
1862
                }
 
1863
                // normal valid
1772
1864
                                if(valid.startsWith("/")){
1773
1865
                                        env=valid.mid(1).split(',');
1774
1866
                                        valid="e";
1789
1881
            if(keywords.contains(rxCom.cap(3))){
1790
1882
                package.optionCommands << rxCom.cap(1);
1791
1883
            }
 
1884
            if(specialTreatment.contains(rxCom.cap(3))){
 
1885
                package.specialTreatmentCommands[rxCom.cap(1)].insert(qMakePair(rxCom.cap(3),1));
 
1886
            }
1792
1887
            rxCom2.indexIn(line); // for commands which don't have a braces part e.g. \item[text]
 
1888
            int res3=rxCom3.indexIn(line); // for commands which don't have a options either e.g. \node (asas)
1793
1889
            if(keywords.contains(rxCom2.cap(2))){
1794
1890
                package.optionCommands << rxCom2.cap(1);
1795
1891
            }
1817
1913
                }
1818
1914
                valid.remove('r');
1819
1915
            }
 
1916
            if(valid.contains('s')){ // special def
 
1917
                if(res>-1){
 
1918
                    package.specialDefCommands.insert(rxCom.cap(1),definition);
 
1919
                }else{
 
1920
                    if(res3>-1)
 
1921
                        package.specialDefCommands.insert(rxCom3.cap(1),definition);
 
1922
                }
 
1923
                if(definition.startsWith('%')){
 
1924
                    config->specialCompletionKeys.insert(definition);
 
1925
                }else{
 
1926
                    if(definition.length()>2){
 
1927
                        QString helper=definition.mid(1,definition.length()-2);
 
1928
                        if(helper.startsWith('%'))
 
1929
                            config->specialCompletionKeys.insert(helper);
 
1930
                    }
 
1931
                }
 
1932
                valid.remove('s');
 
1933
            }
1820
1934
            if(valid.contains('c')){ // cite command
1821
1935
                if(res>-1){
1822
1936
                    package.possibleCommands["%cite"] << rxCom.cap(1);
1891
2005
                                }
1892
2006
                                valid.remove('D');
1893
2007
                        }
 
2008
            if(valid.contains('B')){ // color
 
2009
                package.possibleCommands["%color"] << line;
 
2010
                hideFromCompletion=true;
 
2011
            }
1894
2012
                    // normal commands for syntax checking
1895
2013
                    // will be extended to distinguish between normal and math commands
1896
 
                    if(valid.isEmpty() || valid.contains('n')){
1897
 
                        if(res>-1){
1898
 
                            if(rxCom.cap(1)=="\\begin" || rxCom.cap(1)=="\\end"){
1899
 
                                package.possibleCommands["normal"] << rxCom.cap(1)+"{"+rxCom.cap(3)+"}";
1900
 
                            } else {
1901
 
                                package.possibleCommands["normal"] << rxCom.cap(1);
1902
 
                            }
1903
 
                        } else {
1904
 
                            package.possibleCommands["normal"] << line.simplified();
1905
 
                        }
1906
 
                    }
 
2014
            if(valid.isEmpty() || valid.contains('n')){
 
2015
                if(res>-1){
 
2016
                    if(rxCom.cap(1)=="\\begin" || rxCom.cap(1)=="\\end"){
 
2017
                        package.possibleCommands["normal"] << rxCom.cap(1)+"{"+rxCom.cap(3)+"}";
 
2018
                    } else {
 
2019
                        package.possibleCommands["normal"] << rxCom.cap(1);
 
2020
                    }
 
2021
                } else {
 
2022
                    package.possibleCommands["normal"] << line.simplified();
 
2023
                }
 
2024
            }
1907
2025
                    if(valid.contains('m')){ // math commands
1908
2026
                        if(res>-1){
1909
2027
                            if(rxCom.cap(1)=="\\begin" || rxCom.cap(1)=="\\end"){
2021
2139
        }else{
2022
2140
            //qDebug() << "Completion file not found:" << fileName;
2023
2141
            package.packageName="<notFound>";
 
2142
                package.notFound = true;
2024
2143
        }
2025
2144
        
2026
2145
        QApplication::restoreOverrideCursor();
2028
2147
        return package;
2029
2148
    }
2030
2149
 
2031
 
LatexPackage::LatexPackage(){
 
2150
LatexPackage::LatexPackage() : notFound(false) {
2032
2151
        completionWords.clear();
2033
2152
        packageName.clear();
2034
2153
}
2035
2154
 
 
2155
QString LatexPackage::makeKey(const QString &cwlFilename, const QString &options) {
 
2156
        return QString("%1#%2").arg(options).arg(cwlFilename);
 
2157
}
 
2158
 
 
2159
QString LatexPackage::keyToCwlFilename(const QString &key) {
 
2160
        int i = key.indexOf('#');
 
2161
        if (i<0) return key;
 
2162
        else return key.mid(i+1);
 
2163
}
 
2164
 
 
2165
QString LatexPackage::keyToPackageName(const QString &key) {
 
2166
        // Workaround since there is currently no reliable way to determine the packageName from LatexPackage directly (the attribute with the same name contains the key and sometimes nothing).
 
2167
        QString name = LatexPackage::keyToCwlFilename(key);
 
2168
        if (name.endsWith(".cwl"))
 
2169
                name.remove(name.length()-4, 4);
 
2170
        if (name.startsWith("class-"))
 
2171
                name.remove(0, 6);
 
2172
        return name;
 
2173
}
 
2174
 
 
2175
QString LatexPackage::keyToOptions(const QString &key) {
 
2176
        int i = key.indexOf('#');
 
2177
        if (i<0) return QString();
 
2178
        else return key.left(i);
 
2179
}
 
2180
 
2036
2181
void LatexPackage::unite(LatexPackage &add){
2037
2182
        completionWords.append(add.completionWords);
2038
2183
        optionCommands.unite(add.optionCommands);
2039
2184
        environmentAliases.unite(add.environmentAliases);
 
2185
    specialTreatmentCommands.unite(add.specialTreatmentCommands);
 
2186
    specialDefCommands.unite(add.specialDefCommands);
2040
2187
        //possibleCommands.unite(add.possibleCommands);
2041
2188
        foreach(const QString& elem,add.possibleCommands.keys()){
2042
2189
                QSet<QString> set2=add.possibleCommands[elem];
2047
2194
}
2048
2195
 
2049
2196
 
2050
 
QString getImageAsText(const QPixmap &AImage) {
 
2197
QString getImageAsText(const QPixmap &AImage,const int w) {
2051
2198
    QByteArray ba;
2052
2199
    QBuffer buffer(&ba);
2053
2200
    buffer.open(QIODevice::WriteOnly);
2054
2201
    AImage.save(&buffer, "PNG");
2055
 
    return QString("<img src=\"data:image/png;base64,%1\">").arg(QString(buffer.data().toBase64()));
 
2202
    QString text=w<0 ? QString("<img src=\"data:image/png;base64,%1\">").arg(QString(buffer.data().toBase64())): QString("<img src=\"data:image/png;base64,%1\" width=%2 >").arg(QString(buffer.data().toBase64())).arg(w);
 
2203
    return text;
2056
2204
}
2057
2205
 
2058
2206
void showTooltipLimited(QPoint tt,QString topic,int width){