00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "SeExprEdBrowser.h"
00016 #include "SeExprEdGrapher2d.h"
00017 #include "SeExprEdDialog.h"
00018 #include "SeExprEdControlCollection.h"
00019
00020 #include <QtCore/QDir>
00021 #include <QtGui/QApplication>
00022 #include <QtGui/QLabel>
00023 #include <iostream>
00024 #include <fstream>
00025
00026 #ifdef SEEXPR_USE_PF
00027 # include <pathfinder/pathfinder.h>
00028 #endif
00029
00030 #define P3D_CONFIG_ENVVAR "P3D_CONFIG_PATH"
00031
00032
00033 SeExprEdDialog::SeExprEdDialog(QWidget* parent)
00034 :QDialog(parent), _currentEditorIdx(0)
00035 {
00036 this->setMinimumWidth(600);
00037 QVBoxLayout* rootLayout=new QVBoxLayout(0);
00038 rootLayout->setMargin(2);
00039 this->setLayout(rootLayout);
00040
00041 showEditorTimer = new QTimer();
00042 connect(showEditorTimer, SIGNAL(timeout()), SLOT(_showEditor()));
00043
00044 QSplitter* vsplitter=new QSplitter( Qt::Vertical, this );
00045 rootLayout->addWidget(vsplitter);
00046
00047 QTabWidget* topTabWidget=new QTabWidget();
00048 vsplitter->addWidget(topTabWidget);
00049
00050 QWidget* previewLibraryWidget=new QWidget();
00051 QHBoxLayout* previewLibraryLayout=new QHBoxLayout();
00052 previewLibraryWidget->setLayout(previewLibraryLayout);
00053 topTabWidget->addTab(previewLibraryWidget,"Preview / Library");
00054
00055 QWidget* bottomWidget=new QWidget();
00056 vsplitter->addWidget(bottomWidget);
00057 QVBoxLayout* bottomLayout=new QVBoxLayout();
00058 bottomLayout->setMargin(1);
00059 bottomWidget->setLayout(bottomLayout);
00060
00061
00062 QWidget* leftWidget=new QWidget();
00063 leftWidget->setFixedWidth(450);
00064 QVBoxLayout* leftLayout=new QVBoxLayout();
00065 leftLayout->setMargin(0);
00066 leftWidget->setLayout(leftLayout);
00067 QHBoxLayout* previewLayout=new QHBoxLayout();
00068 grapher=new SeExprEdGrapherWidget(this, 200, 200);
00069 previewLayout->addWidget(grapher,0);
00070 previewCommentLabel=new QLabel();
00071 previewLayout->addWidget(previewCommentLabel,1,Qt::AlignLeft | Qt::AlignTop);
00072 leftLayout->addLayout(previewLayout);
00073 previewLibraryLayout->addWidget(leftWidget);
00074
00075
00076
00077 QHBoxLayout* buttonBarLayout = new QHBoxLayout();
00078
00079 buttonBarLayout->setMargin(1);
00080 previewButton=new QPushButton("Preview");
00081 buttonBarLayout->addWidget(previewButton);
00082 saveButton = new QPushButton("Save");
00083 buttonBarLayout->addWidget(saveButton);
00084 saveAsButton = new QPushButton("Save As");
00085 buttonBarLayout->addWidget(saveAsButton);
00086 saveLocalButton = new QPushButton("Save Local");
00087 saveLocalButton->setEnabled(false);
00088 buttonBarLayout->addWidget(saveLocalButton);
00089 clearButton = new QPushButton("Clear");
00090 buttonBarLayout->addWidget(clearButton);
00091 bottomLayout->addLayout(buttonBarLayout);
00092
00093 controls = new SeExprEdControlCollection();
00094
00095
00096 QScrollArea* scrollArea=new QScrollArea();
00097 scrollArea->setWidget(controls);
00098
00099 scrollArea->setFocusPolicy(Qt::NoFocus);
00100 scrollArea->setMinimumHeight(100);
00101 scrollArea->setFixedWidth(450);
00102 scrollArea->setWidgetResizable(true);
00103 leftLayout->addWidget(scrollArea,1);
00104
00105
00106 editor=new SeExprEditor(this,controls);
00107 connect(editor,SIGNAL(apply()),SLOT(applyExpression()));
00108 connect(editor,SIGNAL(preview()),SLOT(applyExpression()));
00109 connect(grapher,SIGNAL(preview()),SLOT(applyExpression()));
00110 bottomLayout->addWidget(editor);
00111
00112
00113 browser=new SeExprEdBrowser(0,editor);
00114 previewLibraryLayout->addWidget(browser);
00115
00116
00117 QHBoxLayout* buttonLayout = new QHBoxLayout(0);
00118 buttonLayout->addItem(new QSpacerItem(0,0, QSizePolicy::MinimumExpanding,
00119 QSizePolicy::Minimum));
00120 applyButton=new QPushButton("Apply");
00121 buttonLayout->addWidget(applyButton);
00122 acceptButton=new QPushButton("Accept");
00123 buttonLayout->addWidget(acceptButton);
00124 cancelButton = new QPushButton("Cancel");
00125 buttonLayout->addWidget(cancelButton);
00126 connect(applyButton, SIGNAL(clicked()), this, SLOT(verifiedApply()));
00127 connect(acceptButton, SIGNAL(clicked()), this, SLOT(verifiedAccept()));
00128 connect(cancelButton, SIGNAL(clicked()), this, SLOT(reject()));
00129 rootLayout->addLayout(buttonLayout);
00130
00131 setupHelp(topTabWidget);
00132
00133
00134 connect(previewButton,SIGNAL(clicked()),SLOT(applyExpression()));
00135 connect(clearButton, SIGNAL(clicked()), SLOT(clearExpression()));
00136 connect(saveButton, SIGNAL(clicked()), browser,SLOT(saveExpression()));
00137 connect(saveAsButton, SIGNAL(clicked()), browser,SLOT(saveExpressionAs()));
00138 connect(saveLocalButton, SIGNAL(clicked()), browser,SLOT(saveLocalExpressionAs()));
00139 }
00140
00141 void SeExprEdDialog::showEditor(int idx)
00142 {
00143 _currentEditorIdx = idx;
00144 showEditorTimer->setSingleShot(true);
00145 showEditorTimer->start();
00146 }
00147
00148 void SeExprEdDialog::_showEditor()
00149 {
00150 controls->showEditor(_currentEditorIdx);
00151 }
00152
00153 int SeExprEdDialog::exec()
00154 {
00155
00156 browser->getExpressionDirs();
00157 browser->expandAll();
00158 return QDialog::exec();
00159 }
00160
00161 void SeExprEdDialog::keyPressEvent(QKeyEvent* event)
00162 {
00163 if(event->key()==Qt::Key_Escape) return;
00164 return QDialog::keyPressEvent(event);
00165 }
00166
00167 void SeExprEdDialog::verifiedApply()
00168 {
00169 applyExpression();
00170 if(grapher->expr.isValid())
00171 {
00172 emit expressionApplied();
00173 }
00174 else
00175 {
00176 QMessageBox msgBox;
00177 msgBox.setText("Your expression had possible errors.");
00178 msgBox.setInformativeText("Do you want to accept your expression anyways?");
00179 QPushButton* okButton = msgBox.addButton("OK", QMessageBox::RejectRole);
00180 msgBox.addButton("Cancel", QMessageBox::AcceptRole);
00181 int ret = msgBox.exec();
00182 Q_UNUSED(ret);
00183 if(msgBox.clickedButton() == okButton)
00184 emit expressionApplied();
00185 }
00186 }
00187
00188 void SeExprEdDialog::verifiedAccept()
00189 {
00190 applyExpression();
00191 if(grapher->expr.isValid()){
00192 accept();
00193 }else{
00194 QMessageBox msgBox;
00195 msgBox.setText("Your expression had possible errors.");
00196 msgBox.setInformativeText("Do you want to accept your expression anyways?");
00197 QPushButton* okButton=msgBox.addButton("OK",QMessageBox::RejectRole);
00198 msgBox.addButton("Cancel",QMessageBox::AcceptRole);
00199 int ret = msgBox.exec();
00200 Q_UNUSED(ret);
00201 if(msgBox.clickedButton()==okButton) accept();
00202 }
00203 }
00204
00205 void SeExprEdDialog::setupHelp(QTabWidget* tab)
00206 {
00207 QWidget* browserspace = new QWidget(tab);
00208 helpBrowser = new QTextBrowser(browserspace);
00209 tab->addTab(browserspace, "Help");
00210 #ifdef SEEXPR_USE_PF
00211
00212 char *path = pf_find_first("share/doc/SeExpr/SeExpressions.html");
00213 #else
00214 char *path = (char *)"/usr/local/share/doc/SeExpr/SeExpressions.html";
00215 #endif
00216 if (path) {
00217 QString sheet="body {background-color: #eeeeee; color: #000000;} \na {color: #3333ff; text-decoration: none;}\n";
00218 helpBrowser->document()->setDefaultStyleSheet(sheet);
00219 helpBrowser->setSource(QString(path));
00220 #ifdef SEEXPR_USE_PF
00221 free(path);
00222 #endif
00223 }
00224
00225 QPushButton* backPb = new QPushButton("Back");
00226
00227 backPb->setEnabled(false);
00228 QPushButton* forwardPb = new QPushButton("Forward");
00229
00230 forwardPb->setEnabled(false);
00231
00232 QVBoxLayout * helpLayout = new QVBoxLayout(browserspace);
00233 QHBoxLayout * helpPbLayout = new QHBoxLayout;
00234 helpLayout->addLayout(helpPbLayout);
00235 helpPbLayout->addWidget(backPb);
00236 helpPbLayout->addWidget(forwardPb);
00237
00238
00239 QHBoxLayout* findBar=new QHBoxLayout();
00240 helpPbLayout->addWidget(new QLabel("Find"), false);
00241 helpFindBox=new QLineEdit;
00242 helpPbLayout->addWidget(helpFindBox, false);
00243 connect(helpFindBox,SIGNAL(returnPressed()),this,SLOT(findNextInHelp()));
00244 QPushButton* nextButton=new QPushButton("Find Next");
00245 QPushButton* prevButton=new QPushButton("Find Prev");
00246 helpPbLayout->addWidget(nextButton, false);
00247 helpPbLayout->addWidget(prevButton, false);
00248 connect(nextButton,SIGNAL(clicked()),this,SLOT(findNextInHelp()));
00249 connect(prevButton,SIGNAL(clicked()),this,SLOT(findPrevInHelp()));
00250 helpPbLayout->addLayout(findBar, false);
00251 helpLayout->addWidget(helpBrowser, true);
00252 helpBrowser->setMinimumHeight(120);
00253
00254
00255 connect(backPb, SIGNAL(clicked()), helpBrowser, SLOT(backward()));
00256 connect(forwardPb, SIGNAL(clicked()), helpBrowser, SLOT(forward()));
00257 connect(helpBrowser, SIGNAL(backwardAvailable(bool)), backPb, SLOT(setEnabled(bool)));
00258 connect(helpBrowser, SIGNAL(forwardAvailable(bool)), forwardPb, SLOT(setEnabled(bool)));
00259
00260 }
00261
00262 void SeExprEdDialog::findHelper(QTextDocument::FindFlags flags){
00263 QTextDocument* doc=helpBrowser->document();
00264 if(prevFind!=helpFindBox->text()){
00265 prevFind=helpFindBox->text();
00266 helpBrowser->setTextCursor(QTextCursor(doc));
00267 }
00268 QTextCursor blah=doc->find(helpFindBox->text(),helpBrowser->textCursor(),flags);
00269 helpBrowser->setTextCursor(blah);
00270 }
00271
00272 void SeExprEdDialog::findNextInHelp()
00273 {
00274 findHelper(0);
00275 }
00276
00277 void SeExprEdDialog::findPrevInHelp(){
00278 findHelper(QTextDocument::FindBackward);
00279 }
00280
00281 void SeExprEdDialog::applyExpression()
00282 {
00283 editor->clearErrors();
00284
00285 grapher->expr.setExpr(editor->getExpr());
00286 grapher->update();
00287
00288
00289 bool empty=true;
00290 if(grapher->expr.varmap.size()>0){
00291 std::stringstream s;
00292 s<<"<b>Variables not supported in preview (assumed zero):</b><br>";
00293 int count=0;
00294 for(SeExprEdExpression::VARMAP::iterator i=grapher->expr.varmap.begin();
00295 i!=grapher->expr.varmap.end();++i){
00296 count++;
00297 s<<"$"<<i->first<<" ";
00298 if(count%4==0) s<<"<br>";
00299 }
00300 previewCommentLabel->setText(s.str().c_str());
00301 empty=false;
00302 }else previewCommentLabel->setText("");
00303
00304 if(grapher->expr.funcmap.size()>0){
00305 std::stringstream s;
00306 s<<"<b>Functions not supported in preview (assumed zero):</b><br>";
00307 int count=0;
00308 for(SeExprEdExpression::FUNCMAP::iterator i=grapher->expr.funcmap.begin();
00309 i!=grapher->expr.funcmap.end();++i){
00310 count++;
00311 s<<""<<i->first<<"() ";
00312 if(count%4==0) s<<"<br>";
00313 }
00314 previewCommentLabel->setText(s.str().c_str());
00315 empty=false;
00316 }
00317 if(empty) previewCommentLabel->setText("");
00318
00319
00320 bool valid=grapher->expr.isValid();
00321 if(!valid){
00322 const std::vector<SeExpression::Error> & errors=grapher->expr.getErrors();
00323 for(unsigned int i=0;i<errors.size();i++){
00324 editor->addError(errors[i].startPos,errors[i].endPos,errors[i].error);
00325 }
00326 editor->nextError();
00327 }
00328 }
00329
00330 void SeExprEdDialog::clearExpression()
00331 {
00332 browser->clearSelection();
00333 editor->setExpr("",false);
00334 grapher->expr.setExpr("");
00335 grapher->update();
00336 }
00337
00338