File indexing completed on 2024-05-05 17:15:11

0001 /*****************************************************************************************
0002                            mathenvdialog.cpp
0003 ----------------------------------------------------------------------------
0004     date                 : Dec 06 2005
0005     version              : 0.21
0006     copyright            : (C) 2005 by Holger Danielsson (holger.danielsson@t-online.de)
0007  *****************************************************************************************/
0008 
0009 /***************************************************************************
0010  *                                                                         *
0011  *   This program is free software; you can redistribute it and/or modify  *
0012  *   it under the terms of the GNU General Public License as published by  *
0013  *   the Free Software Foundation; either version 2 of the License, or     *
0014  *   (at your option) any later version.                                   *
0015  *                                                                         *
0016  ***************************************************************************/
0017 
0018 #include "mathenvironmentdialog.h"
0019 #include "codecompletion.h"
0020 #include "kiledebug.h"
0021 #include "editorextension.h"
0022 
0023 #include <QCheckBox>
0024 #include <QDialogButtonBox>
0025 #include <QFrame>
0026 #include <QGridLayout>
0027 #include <QGroupBox>
0028 #include <QLabel>
0029 #include <QLayout>
0030 #include <QLineEdit>
0031 #include <QSpinBox>
0032 #include <QStringList>
0033 #include <QVBoxLayout>
0034 
0035 #include <KComboBox>
0036 #include <KLocalizedString>
0037 #include <KConfigGroup>
0038 
0039 namespace KileDialog
0040 {
0041 
0042 MathEnvironmentDialog::MathEnvironmentDialog(QWidget *parent, KConfig *config, KileInfo *ki, KileDocument::LatexCommands *commands)
0043     : Wizard(config, parent), m_ki(ki), m_latexCommands(commands)
0044 {
0045     QWidget *page = new QWidget(this);
0046     QVBoxLayout *mainLayout = new QVBoxLayout;
0047     setLayout(mainLayout);
0048     mainLayout->addWidget(page);
0049     setWindowTitle(i18n("Math Environments"));
0050 
0051     QVBoxLayout *vbox = new QVBoxLayout();
0052     vbox->setContentsMargins(0, 0, 0, 0);
0053     page->setLayout(vbox);
0054 
0055     // environment groupbox
0056     QGroupBox *envgroup = new QGroupBox(i18n("Environment"), page);
0057     mainLayout->addWidget(envgroup);
0058 
0059     m_lbEnvironment = new QLabel(i18n("&Name:"), envgroup);
0060     m_lbStarred = new QLabel(i18n("Without n&umbering:"), envgroup);
0061     m_lbRows = new QLabel(i18n("Number of &rows:"), envgroup);
0062     m_lbCols = new QLabel(i18n("Number of c&ols:"), envgroup);
0063     m_lbSpace = new QLabel(i18n("Space command\nto &separate groups:"), envgroup);
0064     m_lbTabulator = new QLabel(i18n("Standard &tabulator:"), envgroup);
0065     m_lbDisplaymath = new QLabel(i18n("Display&math mode:"), envgroup);
0066     m_lbBullets = new QLabel(i18n("Use &bullets:"), envgroup);
0067 
0068     QFrame *frame = new QFrame(envgroup);
0069     frame->setFrameStyle(QFrame::HLine);
0070     frame->setFrameShadow(QFrame::Sunken);
0071     frame->setLineWidth(1);
0072 
0073     m_coEnvironment = new KComboBox(envgroup);
0074     m_cbStarred = new QCheckBox(envgroup);
0075     m_spRows = new QSpinBox(envgroup);
0076     m_spRows->setMinimum(1);
0077     m_spRows->setMaximum(99);
0078     m_spRows->setSingleStep(1);
0079     m_spRows->setValue(3);
0080     m_spCols = new QSpinBox(envgroup);
0081     m_spCols->setMinimum(1);
0082     m_spCols->setMaximum(49);
0083     m_spCols->setSingleStep(1);
0084     m_spCols->setValue(3);
0085     m_edSpace = new QLineEdit(envgroup);
0086     m_coTabulator = new KComboBox(envgroup);
0087     m_coDisplaymath = new KComboBox(envgroup);
0088     m_cbBullets = new QCheckBox(envgroup);
0089 
0090     QGridLayout *envlayout = new QGridLayout();
0091     envgroup->setLayout(envlayout);
0092     envlayout->setAlignment(Qt::AlignTop);
0093     envlayout->addWidget(m_lbEnvironment, 0, 0);
0094     envlayout->addWidget(m_lbStarred, 1, 0);
0095     envlayout->addWidget(m_lbRows, 2, 0);
0096     envlayout->addWidget(m_lbCols, 3, 0);
0097     envlayout->addWidget(m_lbTabulator, 5, 0);
0098     envlayout->addWidget(m_lbDisplaymath, 6, 0);
0099     envlayout->addWidget(m_coEnvironment, 0, 1);
0100     envlayout->addWidget(m_cbStarred, 1, 1);
0101     envlayout->addWidget(m_spRows, 2, 1);
0102     envlayout->addWidget(m_spCols, 3, 1);
0103     envlayout->addWidget(m_coTabulator, 5, 1);
0104     envlayout->addWidget(m_coDisplaymath, 6, 1);
0105     envlayout->addWidget(m_lbSpace, 3, 3);
0106     envlayout->addWidget(m_lbBullets, 5, 3);
0107     envlayout->addWidget(m_edSpace, 3, 4);
0108     envlayout->addWidget(m_cbBullets, 5, 4);
0109     envlayout->addWidget(frame, 4, 0, 1, 5);
0110     envlayout->setRowMinimumHeight(4, 30);
0111     envlayout->setColumnMinimumWidth(2, 20);
0112     envlayout->setColumnStretch(4, 1);
0113 
0114     // add widgets
0115     vbox->addWidget(envgroup);
0116     vbox->addStretch(1);
0117 
0118     m_lbEnvironment->setBuddy(m_coEnvironment);
0119     m_lbStarred->setBuddy(m_cbStarred);
0120     m_lbRows->setBuddy(m_spRows);
0121     m_lbCols->setBuddy(m_spCols);
0122     m_lbSpace->setBuddy(m_edSpace);
0123     m_lbTabulator->setBuddy(m_coTabulator);
0124     m_lbDisplaymath->setBuddy(m_coDisplaymath);
0125     m_lbBullets->setBuddy(m_cbBullets);
0126 
0127     // initialize dialog
0128     m_coDisplaymath->addItem(QString());
0129     m_coDisplaymath->addItem("displaymath");
0130     m_coDisplaymath->addItem("\\[");
0131     m_coDisplaymath->addItem("equation");
0132     m_coDisplaymath->addItem("equation*");
0133 
0134     // install environments
0135     initEnvironments();
0136     int alignIndex = m_coEnvironment->findText("align");
0137     if(alignIndex >= 0) {
0138         m_coEnvironment->setCurrentIndex(alignIndex);
0139     }
0140     slotEnvironmentChanged(m_coEnvironment->currentIndex());
0141 
0142     // signals and slots
0143     connect(m_coEnvironment, SIGNAL(activated(int)), this, SLOT(slotEnvironmentChanged(int)));
0144     connect(m_spCols, SIGNAL(valueChanged(int)), this, SLOT(slotSpinboxValueChanged(int)));
0145 
0146     m_coEnvironment->setWhatsThis(i18n("Choose an environment."));
0147     m_cbStarred->setWhatsThis(i18n("Use the starred version of this environment."));
0148     m_spRows->setWhatsThis(i18n("Choose the number of table rows."));
0149     m_spCols->setWhatsThis(i18n("Choose the number of table columns or alignment groups."));
0150     m_edSpace->setWhatsThis(i18n("Define an extra LaTeX command to separate alignment groups."));
0151     m_coTabulator->setWhatsThis(i18n("Choose one of some predefined tabulators."));
0152     m_coDisplaymath->setWhatsThis(i18n("Some environments are only valid in math mode. You can surround them with one of these display math modes."));
0153     m_cbBullets->setWhatsThis(i18n("Insert bullets in each cell. Alt+Ctrl+Right and Alt+Ctrl+Left will move very quick from one cell to another."));
0154 
0155     mainLayout->addWidget(buttonBox());
0156     connect(buttonBox(), &QDialogButtonBox::accepted, this, &QDialog::accept);
0157     connect(buttonBox(), &QDialogButtonBox::rejected, this, &QDialog::reject);
0158     connect(this, &QDialog::accepted, this, &MathEnvironmentDialog::slotAccepted);
0159 }
0160 
0161 void MathEnvironmentDialog::initEnvironments()
0162 {
0163     // read all math environments and insert them into the combobox
0164     QStringList list;
0165     QStringList::ConstIterator it;
0166     m_latexCommands->commandList(list, (uint)(KileDocument::CmdAttrAmsmath | KileDocument::CmdAttrMath), false);
0167     for (it = list.constBegin(); it != list.constEnd(); ++it) {
0168         m_coEnvironment->addItem(*it);
0169     }
0170 }
0171 
0172 bool MathEnvironmentDialog::isGroupsParameterEnv()
0173 {
0174     return (m_parameter == "{n}");
0175 }
0176 
0177 bool MathEnvironmentDialog::isParameterEnv()
0178 {
0179     return (m_parameter.indexOf("{") >= 0);
0180 }
0181 
0182 ////////////////////////////// determine the whole tag //////////////////////////////
0183 
0184 void MathEnvironmentDialog::slotEnvironmentChanged(int index)
0185 {
0186     KILE_DEBUG_MAIN << "environment changed: " << m_coEnvironment->itemText(index) << Qt::endl;
0187     m_envname = m_coEnvironment->itemText(index);
0188 
0189     // look for environment parameter in dictionary
0190     KileDocument::LatexCmdAttributes attr;
0191     if (m_latexCommands->commandAttributes(m_envname, attr)) {
0192         m_starred = attr.starred;
0193         m_mathmode = attr.mathmode;
0194         m_columns = (attr.tabulator == "&");
0195         m_groups  = (attr.tabulator == "&=");
0196         m_fixedcolumns  = (attr.tabulator == "&=&");
0197         m_tabulator = attr.tabulator;
0198         m_parameter = attr.parameter;
0199     }
0200 
0201     // set starred version
0202     m_cbStarred->setChecked(false);
0203     m_lbStarred->setEnabled(m_starred);
0204     m_cbStarred->setEnabled(m_starred);
0205 
0206     // determine column/group entries
0207     QString labeltext = i18n("Number of cols:");
0208     bool spinstate = false;
0209     int minvalue = 1;
0210     int maxvalue = 1;
0211     int value = 1;
0212 
0213     if (m_columns) {
0214         spinstate = true;
0215         if (m_envname != "cases") {           // 1,49,3
0216             maxvalue = 49;
0217             value = 3;
0218         }
0219         else {
0220             minvalue = 2;                     // 2,2,2
0221             maxvalue = 2;
0222             value = 2;
0223         }
0224     }
0225     else {
0226         if (m_groups) {
0227             spinstate = true;
0228             labeltext = i18n("Number of groups:");
0229             maxvalue = 19;                       // 1,19,1
0230         }
0231         else {
0232             if (m_fixedcolumns) {
0233                 spinstate = true;
0234                 minvalue = 3;                        // 3,3,3
0235                 maxvalue = 3;
0236                 value = 3;
0237             }
0238             else {
0239                 if (m_envname == "split") {
0240                     spinstate = true;
0241                     maxvalue = 2;                        // 1,2,1
0242                 }
0243             }
0244         }
0245     }
0246 
0247     // set column/group entries
0248     m_lbCols->setText(labeltext);
0249     m_spCols->setMinimum(minvalue);
0250     m_spCols->setMaximum(maxvalue);
0251     m_spCols->setValue(value);
0252 
0253     m_lbCols->setEnabled(spinstate);
0254     m_spCols->setEnabled(spinstate);
0255     slotSpinboxValueChanged(m_spCols->value());
0256 
0257     // set tabulator entries
0258     m_coTabulator->clear();
0259     QStringList tablist;
0260     if(m_tabulator == "&=&") {
0261         tablist << "&=&" << "& &" << "&<&" << "&<=&" << "&>&" << "&>=&"
0262                 << "&\\ne&" << "&\\approx&" << "&\\equiv&" << "&\\conq&";
0263     }
0264     else {
0265         if(m_tabulator == "&=") {
0266             tablist << "&=" << "& " << "&<" << "&<=" << "&>" << "&>="
0267                     << "&\\ne" << "&\\approx" << "&\\equiv" << "&\\conq";
0268         }
0269         else {
0270             if(!m_tabulator.isEmpty()) {
0271                 tablist << "&";
0272             }
0273         }
0274     }
0275     bool tabstate = (tablist.count() > 0);
0276     m_lbTabulator->setEnabled(tabstate);
0277     m_coTabulator->setEnabled(tabstate);
0278     if(tabstate) {
0279         m_coTabulator->addItems(tablist);
0280     }
0281 
0282     // set displaymathmode entries
0283     m_lbDisplaymath->setEnabled(m_mathmode);
0284     m_coDisplaymath->setEnabled(m_mathmode);
0285 }
0286 
0287 void MathEnvironmentDialog::slotSpinboxValueChanged(int index)
0288 {
0289     bool state = (index > 1 && m_groups && isGroupsParameterEnv());
0290     m_lbSpace->setEnabled(state);
0291     m_edSpace->setEnabled(state);
0292 }
0293 
0294 void MathEnvironmentDialog::slotAccepted()
0295 {
0296     // environment
0297     QString envname = (m_cbStarred->isChecked()) ? m_envname + '*' : m_envname;
0298     QString indent = m_ki->editorExtension()->autoIndentEnvironment();
0299 
0300     // use bullets?
0301     QString bullet = (m_cbBullets->isChecked()) ? s_bullet : QString();
0302 
0303     // normal tabulator
0304     QString tab = m_coTabulator->currentText();
0305     tab.replace("<=", "\\le");
0306     tab.replace(">=", "\\ge");
0307     QString tabulator = bullet + ' ' + tab + ' ';
0308 
0309     // number of rows
0310     int numrows = m_spRows->value();
0311 
0312     // get number of groups/columns and tabulator to separate these
0313     QString grouptabulator;
0314     int numgroups;
0315     bool aligngroups;
0316     if (m_groups) {
0317         aligngroups = true;
0318         numgroups = (m_tabulator != "&") ? m_spCols->value() : 1;
0319         if (m_edSpace->isEnabled()) {
0320             grouptabulator = "  &" + m_edSpace->text() + "  ";
0321         }
0322         else {
0323             grouptabulator = "  &  ";
0324         }
0325     }
0326     else {
0327         aligngroups = false;
0328         if(!m_fixedcolumns) {
0329             numgroups = (m_columns) ? m_spCols->value() - 1 : 0;
0330         }
0331         else {
0332             numgroups = 1;
0333         }
0334     }
0335 
0336     // get displaymath mode
0337     QString displaymathbegin;
0338     QString displaymathend;
0339     if(m_coDisplaymath->isEnabled()) {
0340         QString mathmode = m_coDisplaymath->currentText();
0341         if(!mathmode.isEmpty()) {
0342             if(mathmode == "\\[") {
0343                 displaymathbegin = "\\[\n";
0344                 displaymathend   = "\\]\n";
0345             }
0346             else {
0347                 displaymathbegin = QString("\\begin{%1}\n").arg(mathmode);
0348                 displaymathend   = QString("\\end{%1}\n").arg(mathmode);
0349             }
0350         }
0351     }
0352 
0353     // build tag
0354     m_td.tagBegin = displaymathbegin;
0355 
0356     QString parameter;
0357     if (isGroupsParameterEnv()) {
0358         parameter = QString("{%2}").arg(numgroups);
0359     }
0360     else {
0361         if(isParameterEnv()) {
0362             parameter = '{' + bullet + '}';
0363         }
0364     }
0365 
0366     // open environment
0367     m_td.tagBegin += QString("\\begin{%1}").arg(envname) + parameter + '\n';
0368 
0369     for(int row = 0; row < numrows; ++row) {
0370         m_td.tagBegin += indent;
0371         for(int col = 0; col < numgroups; ++col) {
0372             m_td.tagBegin += tabulator;
0373             // is there more than one group or column?
0374             if(aligngroups && col < numgroups - 1) {
0375                 m_td.tagBegin += bullet + grouptabulator;
0376             }
0377         }
0378         // last row without CR
0379         if(row < numrows - 1) {
0380             m_td.tagBegin += bullet + " \\\\\n";
0381         }
0382         else {
0383             m_td.tagBegin += bullet;
0384         }
0385     }
0386 
0387     // close environment
0388     m_td.tagEnd = QString("\n\\end{%1}\n").arg(envname);
0389     m_td.tagEnd += displaymathend;
0390 
0391     m_td.dy = (displaymathbegin.isEmpty()) ? 1 : 2;
0392     m_td.dx = indent.length();
0393 
0394 }
0395 
0396 }
0397