QvisExpressionsWindow.C 58.6 KB
Newer Older
hrchilds's avatar
hrchilds committed
1 2
/*****************************************************************************
*
brugger's avatar
 
brugger committed
3
* Copyright (c) 2000 - 2010, Lawrence Livermore National Security, LLC
hrchilds's avatar
hrchilds committed
4
* Produced at the Lawrence Livermore National Laboratory
brugger's avatar
 
brugger committed
5
* LLNL-CODE-400124
hrchilds's avatar
hrchilds committed
6 7
* All rights reserved.
*
brugger's avatar
 
brugger committed
8
* This file is  part of VisIt. For  details, see https://visit.llnl.gov/.  The
hrchilds's avatar
hrchilds committed
9 10 11 12 13 14 15 16 17 18
* full copyright notice is contained in the file COPYRIGHT located at the root
* of the VisIt distribution or at http://www.llnl.gov/visit/copyright.html.
*
* Redistribution  and  use  in  source  and  binary  forms,  with  or  without
* modification, are permitted provided that the following conditions are met:
*
*  - Redistributions of  source code must  retain the above  copyright notice,
*    this list of conditions and the disclaimer below.
*  - Redistributions in binary form must reproduce the above copyright notice,
*    this  list of  conditions  and  the  disclaimer (as noted below)  in  the
brugger's avatar
 
brugger committed
19 20 21
*    documentation and/or other materials provided with the distribution.
*  - Neither the name of  the LLNS/LLNL nor the names of  its contributors may
*    be used to endorse or promote products derived from this software without
hrchilds's avatar
hrchilds committed
22 23 24 25 26
*    specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT  HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR  IMPLIED WARRANTIES, INCLUDING,  BUT NOT  LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND  FITNESS FOR A PARTICULAR  PURPOSE
brugger's avatar
 
brugger committed
27 28 29
* ARE  DISCLAIMED. IN  NO EVENT  SHALL LAWRENCE  LIVERMORE NATIONAL  SECURITY,
* LLC, THE  U.S.  DEPARTMENT OF  ENERGY  OR  CONTRIBUTORS BE  LIABLE  FOR  ANY
* DIRECT,  INDIRECT,   INCIDENTAL,   SPECIAL,   EXEMPLARY,  OR   CONSEQUENTIAL
hrchilds's avatar
hrchilds committed
30 31 32 33 34 35 36 37 38
* DAMAGES (INCLUDING, BUT NOT  LIMITED TO, PROCUREMENT OF  SUBSTITUTE GOODS OR
* SERVICES; LOSS OF  USE, DATA, OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER
* CAUSED  AND  ON  ANY  THEORY  OF  LIABILITY,  WHETHER  IN  CONTRACT,  STRICT
* LIABILITY, OR TORT  (INCLUDING NEGLIGENCE OR OTHERWISE)  ARISING IN ANY  WAY
* OUT OF THE  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
*****************************************************************************/

hrchilds's avatar
hrchilds committed
39
#include <QvisExpressionsWindow.h>
hrchilds's avatar
hrchilds committed
40

hrchilds's avatar
hrchilds committed
41 42
#include <Expression.h>
#include <ExpressionList.h>
hrchilds's avatar
hrchilds committed
43 44
#include <ViewerProxy.h>

whitlocb's avatar
whitlocb committed
45 46 47 48 49 50 51 52 53 54 55 56
#include <QApplication>
#include <QCheckBox>
#include <QComboBox>
#include <QGroupBox>
#include <QLabel>
#include <QLayout>
#include <QLineEdit>
#include <QListWidget>
#include <QTextEdit>
#include <QMenu>
#include <QPushButton>
#include <QSplitter>
hrchilds's avatar
hrchilds committed
57

hrchilds's avatar
hrchilds committed
58
#include <QNarrowLineEdit.h>
hrchilds's avatar
hrchilds committed
59
#include <QvisVariableButton.h>
cyrush's avatar
cyrush committed
60
#include <QvisPythonFilterEditor.h>
hrchilds's avatar
hrchilds committed
61

hrchilds's avatar
hrchilds committed
62 63 64
#define STDMIN(A,B) (((A)<(B)) ? (A) : (B))
#define STDMAX(A,B) (((A)<(B)) ? (B) : (A))

hrchilds's avatar
hrchilds committed
65 66 67 68 69
// ****************************************************************************
//  Expression Lists
//
//  Purpose:
//    Categorized expression lists data.  These structures are self-contained
70
//    and to be parsed correctly require only the terminating nulls.
hrchilds's avatar
hrchilds committed
71 72 73 74
//
//  Programmer:  Jeremy Meredith
//  Creation:    October 23, 2004
//
hrchilds's avatar
hrchilds committed
75 76 77 78 79
//  Modifications:
//
//    Hank Childs, Sun Jan  2 15:32:00 PST 2005
//    Added curl, divergence, Laplacian, materror.
//
hrchilds's avatar
hrchilds committed
80 81 82
//    Hank Childs, Thu Jan 20 15:51:16 PST 2005
//    Added side volume, resrad.
//
hrchilds's avatar
hrchilds committed
83 84 85 86 87
//    Hank Childs, Thu Jun 30 15:00:42 PDT 2005
//    Added polar_radius, polar_theta, polar_phi, cylindrical_radius,
//    cylindrical_theta, cylindrical, mod, round, ceil, floor, zoneid,
//    nodeid, global_zoneid, and global_nodeid.
//
hrchilds's avatar
hrchilds committed
88 89 90
//    Hank Childs, Tue Aug 16 09:05:03 PDT 2005
//    Added image processing category.
//
hrchilds's avatar
hrchilds committed
91 92 93
//    Hank Childs, Wed Sep 21 17:31:59 PDT 2005
//    Added external_node, surface normal, min/max edge length/side volume.
//
hrchilds's avatar
hrchilds committed
94 95 96
//    Hank Childs, Sun Jan 22 12:47:29 PST 2006
//    Renamed comparison to relational.  Added new category for comparison.
//
hrchilds's avatar
hrchilds committed
97 98 99
//    Hank Childs, Tue Feb 14 14:06:20 PST 2006
//    Added ijk_gradient.
//
hrchilds's avatar
hrchilds committed
100 101 102
//    Hank Childs, Sun Mar  5 16:03:38 PST 2006
//    Added time.
//
hrchilds's avatar
hrchilds committed
103 104 105
//    Hank Childs, Mon Mar 13 16:48:23 PST 2006
//    Added minimum and maximum.
//
hrchilds's avatar
hrchilds committed
106 107 108 109
//    Hank Childs, Thu May 11 12:45:39 PDT 2006
//    Added mean_curvature, gauss_curvature, compose vector, and compose 
//    tensor.
//
hrchilds's avatar
hrchilds committed
110 111 112
//    Hank Childs, Fri Oct  6 15:47:04 PDT 2006
//    Added abel_inversion.
//
hrchilds's avatar
hrchilds committed
113 114 115
//    Mark C. Miller, Wed Nov 15 12:47:05 PST 2006
//    Added zonetype expression
//
hrchilds's avatar
hrchilds committed
116 117 118
//    Hank Childs, Fri Dec 22 10:27:45 PST 2006
//    Added symm_point.
//
hrchilds's avatar
hrchilds committed
119 120 121
//    Hank Childs, Fri Jan 12 13:20:33 PST 2007
//    Added array_compose_with_bins
//
hrchilds's avatar
hrchilds committed
122 123 124
//    Cyrus Harrison, Tue Feb 20 12:02:00 PST 2007
//    Added conn_components
//
125 126 127
//    Cyrus Harrison, Fri Jun  1 14:49:49 PDT 2007
//    Added contraction and viscous_stress
//
128 129 130
//    Jeremy Meredith, Thu Aug 30 16:02:58 EDT 2007
//    Added hsvcolor.
//
131 132 133
//    Gunther H. Weber, Thu Jan 10 12:00:23 PST 2008
//    Added colorlookup.
//
134 135 136
//    Cyrus Harrison, Thu Jan 31 09:45:30 PST 2008
//    Added value_for_material
//
hrchilds's avatar
hrchilds committed
137 138 139
//    Hank Childs, Thu Feb 21 15:50:36 PST 2008
//    Added transpose.
//
140 141 142
//    Brad Whitlock, Tue Apr  8 12:17:11 PDT 2008
//    Added support for internalization of the expression category names.
//
brugger's avatar
 
brugger committed
143 144 145 146
//    Eric Brugger, Wed Aug  6 17:49:59 PDT 2008
//    Renamed smallest_angle to minimum_angle and largest_angle to
//    maximum_angle.
//
147 148 149
//    Hank Childs, Mon Dec 29 11:56:50 PST 2008
//    Added dominant_mat.
//
hrchilds's avatar
hrchilds committed
150 151 152
//    Hank Childs, Sun Feb 22 08:56:33 PST 2009
//    Added category for time iterating expressions.
//
153 154 155
//    Jeremy Meredith, Mon Mar 16 14:40:13 EDT 2009
//    Added timestep and cycle.
//
156 157 158
//    Kathleen Bonnell, Mon Apr 27 17:35:25 PDT 2009
//    Added sinh, cosh, tanh to expr_trig.
//
159 160 161
//    Hank Childs, Mon Jun 28 06:49:16 PDT 2010
//    Add [min|max][x|y|z]_coord.
//
pugmire's avatar
pugmire committed
162 163 164
//    Dave Pugmire, Fri Jul  2 14:22:34 EDT 2010
//    Add resample expression.
//
165 166 167
//    Cyrus Harrison, Wed Jul  7 09:34:00 PDT 2010
//    Added 'zonal_constant' and 'nodal_constant'
//
168 169 170 171 172
//    Hank Childs, Thu Jul  8 08:12:26 PDT 2010
//    Retire [min|max][x|y|z] coord, replaced with min_coord and max_coord.
//    Adding polar coordinates and I really didn't think there should be
//    12 expressions for this minor functionality.
//
hrchilds's avatar
hrchilds committed
173
// ****************************************************************************
hrchilds's avatar
hrchilds committed
174

hrchilds's avatar
hrchilds committed
175 176
struct ExprNameList
{
177
    QString      name;
hrchilds's avatar
hrchilds committed
178 179 180 181 182 183 184 185
    const char **list;
};

const char *expr_meshquality[] = {
    "aspect",
    "aspect_gamma",
    "condition",
    "degree",
186 187 188
    "diagonal_ratio",
    "min_diagonal",
    "max_diagonal",
hrchilds's avatar
hrchilds committed
189 190
    "dimension",
    "jacobian",
hrchilds's avatar
hrchilds committed
191 192
    "max_edge_length",
    "max_side_volume",
brugger's avatar
 
brugger committed
193
    "maximum_angle",
hrchilds's avatar
hrchilds committed
194 195
    "min_edge_length",
    "min_side_volume",
brugger's avatar
 
brugger committed
196
    "minimum_angle",
hrchilds's avatar
hrchilds committed
197 198 199 200 201 202 203 204 205 206 207 208
    "neighbor",
    "node_degree",
    "oddy",
    "relative_size",
    "scaled_jacobian",
    "shape",
    "shape_and_size",
    "shear",
    "skew",
    "stretch",
    "taper",
    "warpage",
209 210
    "face_planarity",
    "relative_face_planarity",
hrchilds's avatar
hrchilds committed
211 212 213 214 215
    NULL
};

const char *expr_math[] = {
    "abs",
hrchilds's avatar
hrchilds committed
216 217
    "ceil",
    "floor",
218
    "exp",
hrchilds's avatar
hrchilds committed
219 220
    "ln",
    "log10",
hrchilds's avatar
hrchilds committed
221 222
    "max",
    "min",
hrchilds's avatar
hrchilds committed
223 224
    "mod",
    "round",
hrchilds's avatar
hrchilds committed
225 226
    "sqr",
    "sqrt",
227
    "random",
hrchilds's avatar
hrchilds committed
228 229 230 231 232
    "+",
    "-",
    "*",
    "/",
    "^",
233
    "&",
hrchilds's avatar
hrchilds committed
234 235 236
    NULL
};

hrchilds's avatar
hrchilds committed
237
const char *expr_relational[] = {
hrchilds's avatar
hrchilds committed
238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263
    "eq",
    "ge",
    "gt",
    "le",
    "lt",
    "ne",
    NULL
};

const char *expr_conditional[] = {
    "if",
    NULL
};

const char *expr_logical[] = {
    "and",
    "not",
    "or",
    NULL
};

const char *expr_trig[] = {
    "acos",
    "asin",
    "atan",
    "cos",
264
    "cosh",
hrchilds's avatar
hrchilds committed
265 266 267
    "deg2rad",
    "rad2deg",
    "sin",
268
    "sinh",
hrchilds's avatar
hrchilds committed
269
    "tan",
270
    "tanh",
hrchilds's avatar
hrchilds committed
271 272 273 274
    NULL
};

const char *expr_vector[] = {
hrchilds's avatar
hrchilds committed
275 276
    "color",
    "color4",
277
    "colorlookup",
hrchilds's avatar
hrchilds committed
278 279
    "cross",
    "dot",
280
    "hsvcolor",
hrchilds's avatar
hrchilds committed
281
    "magnitude",
hrchilds's avatar
hrchilds committed
282
    "normalize",
hrchilds's avatar
hrchilds committed
283 284 285 286
    NULL
};

const char *expr_tensor[] = {
287
    "contraction",
hrchilds's avatar
hrchilds committed
288 289 290 291 292 293 294 295 296
    "determinant",
    "effective_tensor",
    "eigenvalue",
    "eigenvector",
    "inverse",
    "principal_deviatoric_tensor",
    "principal_tensor",
    "tensor_maximum_shear",
    "trace",
hrchilds's avatar
hrchilds committed
297
    "transpose",
298
    "viscous_stress",
hrchilds's avatar
hrchilds committed
299 300 301
    NULL
};

hrchilds's avatar
hrchilds committed
302 303
const char *expr_array[] = {
    "array_compose",
hrchilds's avatar
hrchilds committed
304
    "array_compose_with_bins",
hrchilds's avatar
hrchilds committed
305 306 307 308
    "array_decompose",
    NULL
};

hrchilds's avatar
hrchilds committed
309
const char *expr_materials[] = {
310
    "dominant_mat",
hrchilds's avatar
hrchilds committed
311
    "materror",
hrchilds's avatar
hrchilds committed
312 313 314
    "matvf",
    "nmats",
    "specmf",
315
    "value_for_material",
hrchilds's avatar
hrchilds committed
316 317 318 319 320 321
    NULL
};

const char *expr_mesh[] = {
    "area",
    "coord",
hrchilds's avatar
hrchilds committed
322 323 324
    "cylindrical",
    "cylindrical_radius",
    "cylindrical_theta",
hrchilds's avatar
hrchilds committed
325
    "external_node",
hrchilds's avatar
hrchilds committed
326 327
    "global_nodeid",
    "global_zoneid",
328 329
    "max_coord",
    "min_coord",
hrchilds's avatar
hrchilds committed
330
    "nodeid",
hrchilds's avatar
hrchilds committed
331
    "polar",
hrchilds's avatar
hrchilds committed
332 333 334
    "polar_radius",
    "polar_theta",
    "polar_phi",
hrchilds's avatar
hrchilds committed
335 336 337
    "revolved_surface_area",
    "revolved_volume",
    "volume",
hrchilds's avatar
hrchilds committed
338
    "zoneid",
hrchilds's avatar
hrchilds committed
339
    "zonetype",
hrchilds's avatar
hrchilds committed
340 341 342 343
    NULL
};

const char *expr_misc[] = {
344
    "cell_constant",
hrchilds's avatar
hrchilds committed
345
    "conn_components",
hrchilds's avatar
hrchilds committed
346
    "curl",
347
    "cycle",
hrchilds's avatar
hrchilds committed
348
    "divergence",
349
    "enumerate",
hrchilds's avatar
hrchilds committed
350
    "gauss_curvature",
hrchilds's avatar
hrchilds committed
351
    "gradient",
hrchilds's avatar
hrchilds committed
352 353
    "ij_gradient",
    "ijk_gradient",
hrchilds's avatar
hrchilds committed
354
    "Laplacian",
hrchilds's avatar
hrchilds committed
355
    "mean_curvature",
356
    "nodal_constant",
357
    "point_constant",
hrchilds's avatar
hrchilds committed
358
    "recenter",
pugmire's avatar
pugmire committed
359
    "resample",
hrchilds's avatar
hrchilds committed
360
    "resrad",
hrchilds's avatar
hrchilds committed
361 362 363
    "surface_normal",
    "   point_surface_normal",
    "   cell_surface_normal",
hrchilds's avatar
hrchilds committed
364
    "time",
365
    "timestep",
366
    "zonal_constant",
hrchilds's avatar
hrchilds committed
367 368 369
    NULL
};

hrchilds's avatar
hrchilds committed
370
const char *expr_imageprocessing[] = {
hrchilds's avatar
hrchilds committed
371
    "abel_inversion",
hrchilds's avatar
hrchilds committed
372 373 374 375 376 377
    "conservative_smoothing",
    "mean_filter",
    "median_filter",
    NULL
};

hrchilds's avatar
hrchilds committed
378 379 380
const char *expr_comparison[] = {
    "conn_cmfe",
    "pos_cmfe",
hrchilds's avatar
hrchilds committed
381
    "symm_point",
hrchilds's avatar
hrchilds committed
382 383 384 385 386
    "symm_plane",
    "symm_transform",
    NULL
};

hrchilds's avatar
hrchilds committed
387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411
const char *expr_time_iteration[] = {
    "average_over_time",
    "cycle_at_minimum",
    "cycle_at_maximum",
    "first_cycle_when_condition_is_true",
    "first_time_when_condition_is_true",
    "first_time_index_when_condition_is_true",
    "last_cycle_when_condition_is_true",
    "last_time_when_condition_is_true",
    "last_time_index_when_condition_is_true",
    "min_over_time", 
    "max_over_time", 
    "sum_over_time", 
    "time_at_minimum",
    "time_at_maximum",
    "time_index_at_minimum",
    "time_index_at_maximum",
    "value_at_minimum",
    "value_at_maximum",
    "var_when_condition_is_first_true",
    "var_when_condition_is_last_true",
    NULL
};

#define NUM_EXPRESSION_CATEGORIES 15
412
ExprNameList exprlist[NUM_EXPRESSION_CATEGORIES];
hrchilds's avatar
hrchilds committed
413

hrchilds's avatar
hrchilds committed
414 415 416 417 418 419 420 421 422 423
// ****************************************************************************
// Method: QvisExpressionsWindow::QvisExpressionsWindow
//
// Purpose: 
//   This is the constructor for the QvisExpressionsWindow class.
//
// Arguments:
//   exprList_  The ExpressionList subject to observe
//   
//
hrchilds's avatar
hrchilds committed
424 425
// Programmer: Jeremy Meredith
// Creation:   October 10, 2004
hrchilds's avatar
hrchilds committed
426
//
427 428 429 430
// Modifications:
//   Brad Whitlock, Tue Apr  8 12:15:08 PDT 2008
//   Support for internationalization.
//
hrchilds's avatar
hrchilds committed
431 432 433
//   Hank Childs, Sun Feb 22 09:01:29 PST 2009
//   Add time iteration category.
//
434 435 436
//   Hank Childs, Mon Jul  5 11:20:47 PDT 2010
//   Enable Load and Save buttons.
//
hrchilds's avatar
hrchilds committed
437
// ****************************************************************************
438

hrchilds's avatar
hrchilds committed
439
QvisExpressionsWindow::QvisExpressionsWindow(
440 441
    ExpressionList *exprList_, const QString &caption,
    const QString &shortName, QvisNotepadArea *notepad) :
hrchilds's avatar
hrchilds committed
442
    QvisPostableWindowObserver(exprList_, caption, shortName, notepad,
443 444 445
                               QvisPostableWindowObserver::ApplyButton |
                               QvisPostableWindowObserver::LoadButton |
                               QvisPostableWindowObserver::SaveButton,
hrchilds's avatar
hrchilds committed
446 447
                               false)
{
448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477
    // Populate the expression categories. If you add a new one, increment
    // the NUM_EXPRESSION_CATEGORIES macro.
    exprlist[0].name = tr("Math");
    exprlist[0].list = expr_math;
    exprlist[1].name = tr("Vector");
    exprlist[1].list = expr_vector;
    exprlist[2].name = tr("Tensor");
    exprlist[2].list = expr_tensor;
    exprlist[3].name = tr("Array");
    exprlist[3].list = expr_array;
    exprlist[4].name = tr("Material");
    exprlist[4].list = expr_materials;
    exprlist[5].name = tr("Mesh");
    exprlist[5].list = expr_mesh;
    exprlist[6].name = tr("Mesh Quality");
    exprlist[6].list = expr_meshquality;
    exprlist[7].name = tr("Comparison");
    exprlist[7].list = expr_comparison;
    exprlist[8].name = tr("Image Processing");
    exprlist[8].list = expr_imageprocessing;
    exprlist[9].name = tr("Miscellaneous");
    exprlist[9].list = expr_misc;
    exprlist[10].name = tr("Trigonometry");
    exprlist[10].list = expr_trig;
    exprlist[11].name = tr("Relational");
    exprlist[11].list = expr_relational;
    exprlist[12].name = tr("Conditional");
    exprlist[12].list = expr_conditional;
    exprlist[13].name = tr("Logical");
    exprlist[13].list = expr_logical;
hrchilds's avatar
hrchilds committed
478 479
    exprlist[14].name = tr("Time Iteration");
    exprlist[14].list = expr_time_iteration;
480

hrchilds's avatar
hrchilds committed
481 482 483 484 485 486 487 488 489
    exprList = exprList_;
}

// ****************************************************************************
// Method: QvisExpressionsWindow::~QvisExpressionsWindow
//
// Purpose: 
//   Destructor for the QvisExpressionsWindow class.
//
hrchilds's avatar
hrchilds committed
490 491
// Programmer: Jeremy Meredith
// Creation:   October 10, 2004
hrchilds's avatar
hrchilds committed
492 493 494 495 496 497 498 499 500 501 502 503 504 505 506
//
// Modifications:
//   
// ****************************************************************************
QvisExpressionsWindow::~QvisExpressionsWindow()
{
    exprList = NULL;
}

// ****************************************************************************
// Method: QvisExpressionsWindow::CreateWindowContents
//
// Purpose: 
//   Creates the widgets for the window.
//
hrchilds's avatar
hrchilds committed
507 508 509 510 511
// Programmer: Jeremy Meredith
// Creation:   October 10, 2004
//
// Note: as of writing, unsure if I want to use the splitter or not.
//       We should pick one of the two methods eventually.
hrchilds's avatar
hrchilds committed
512 513
//
// Modifications:
hrchilds's avatar
hrchilds committed
514 515 516 517 518 519 520 521
//    Jeremy Meredith, Sat Oct 23 11:50:35 PDT 2004
//    Changed the layout a bit: use group boxes with titles for the two
//    panes, change to use splitters, change the resize proportions,
//    move the "hidden" toggle to the bottom and change its sense,
//    move "insert function" to the right side and group expressions into
//    categorized submenus, reword some other labels to make them more
//    descriptive.
//
hrchilds's avatar
hrchilds committed
522 523 524
//    Brad Whitlock, Thu Dec 9 10:50:12 PDT 2004
//    I added a variable button that lets us insert variables.
//
hrchilds's avatar
hrchilds committed
525 526 527
//    Hank Childs, Thu Jul 21 11:12:43 PDT 2005
//    Add support for array mesh variables.
//
hrchilds's avatar
hrchilds committed
528 529 530
//    Kathleen Bonnell, Thu Aug  3 08:42:33 PDT 2006 
//    Changed numtypes to 7 to support CurveMeshVar.
//
531 532 533
//    Brad Whitlock, Tue Apr  8 09:27:26 PDT 2008
//    Support for internationalization.
//
534 535
//    Mark C. Miller, Mon Apr 14 15:41:21 PDT 2008
//    Added '&' bitwise binary and operation
536
//
whitlocb's avatar
whitlocb committed
537 538 539
//    Cyrus Harrison, Wed Jun 11 13:49:19 PDT 2008
//    Initial Qt4 Port.
//
540 541 542 543
//    Jeremy Meredith, Thu Aug  7 15:37:17 EDT 2008
//    changed an erroneous pointer-based string comparison to a true
//    string based comparison.
//
hrchilds's avatar
hrchilds committed
544
// ****************************************************************************
hrchilds's avatar
hrchilds committed
545

hrchilds's avatar
hrchilds committed
546 547 548
void
QvisExpressionsWindow::CreateWindowContents()
{
whitlocb's avatar
whitlocb committed
549

hrchilds's avatar
hrchilds committed
550 551 552
    QSplitter *mainSplitter = new QSplitter(central);
    topLayout->addWidget(mainSplitter);
    topLayout->setStretchFactor(mainSplitter, 100);
cyrush's avatar
cyrush committed
553

whitlocb's avatar
whitlocb committed
554 555
    QGroupBox *f1 = new QGroupBox(tr("Expression List"));
    QGridLayout *listLayout = new QGridLayout(f1);
hrchilds's avatar
hrchilds committed
556

whitlocb's avatar
whitlocb committed
557 558
    exprListBox = new QListWidget(f1);
    listLayout->addWidget(exprListBox, 1,0, 1,2);
hrchilds's avatar
hrchilds committed
559

whitlocb's avatar
whitlocb committed
560
    newButton = new QPushButton(tr("New"), f1);
hrchilds's avatar
hrchilds committed
561
    listLayout->addWidget(newButton, 2,0);
hrchilds's avatar
hrchilds committed
562

whitlocb's avatar
whitlocb committed
563
    delButton = new QPushButton(tr("Delete"), f1);
hrchilds's avatar
hrchilds committed
564
    listLayout->addWidget(delButton, 2,1);
hrchilds's avatar
hrchilds committed
565

whitlocb's avatar
whitlocb committed
566 567 568 569
    displayAllVars = new QCheckBox(tr("Display expressions from database"), f1);
    listLayout->addWidget(displayAllVars, 3,0, 1,2);

    mainSplitter->addWidget(f1);
cyrush's avatar
cyrush committed
570

whitlocb's avatar
whitlocb committed
571
    QGroupBox *f2 = new QGroupBox(tr("Definition"));
cyrush's avatar
cyrush committed
572
    QGridLayout *definitionLayout = new QGridLayout(f2);
hrchilds's avatar
hrchilds committed
573

cyrush's avatar
cyrush committed
574
    int row = 0;
hrchilds's avatar
hrchilds committed
575

whitlocb's avatar
whitlocb committed
576 577
    nameEditLabel = new QLabel(tr("Name"), f2);
    nameEdit = new QNarrowLineEdit(f2);
cyrush's avatar
cyrush committed
578 579
    definitionLayout->addWidget(nameEditLabel, row,0, 1,1);
    definitionLayout->addWidget(nameEdit, row,1, 1,3);
hrchilds's avatar
hrchilds committed
580 581
    row++;

whitlocb's avatar
whitlocb committed
582 583
    typeLabel = new QLabel(tr("Type"), f2);
    typeList = new QComboBox(f2);
584
    // Extracted from Expression::GetTypeString so we can internationalize.
whitlocb's avatar
whitlocb committed
585 586 587 588 589 590 591
    typeList->addItem(tr("Scalar Mesh Variable"));
    typeList->addItem(tr("Vector Mesh Variable"));
    typeList->addItem(tr("Tensor Mesh Variable"));
    typeList->addItem(tr("Symmetric Tensor Mesh Variable"));
    typeList->addItem(tr("Array Mesh Variable"));
    typeList->addItem(tr("Curve Mesh Variable"));

cyrush's avatar
cyrush committed
592 593
    definitionLayout->addWidget(typeLabel, row,0, 1,1);
    definitionLayout->addWidget(typeList, row,1, 1,3);
hrchilds's avatar
hrchilds committed
594 595
    row++;

cyrush's avatar
cyrush committed
596 597
    notHidden = new QCheckBox(tr("Show variable in plot menus"), f2);
    definitionLayout->addWidget(notHidden, row,1, 1,3);
hrchilds's avatar
hrchilds committed
598 599
    row++;

cyrush's avatar
cyrush committed
600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658
    editorTabs = new QTabWidget(f2);

    // tab 1 -> standard editor
    CreateStandardEditor();
    editorTabs->addTab(stdEditorWidget, "Standard Editor");
    // tab 2 -> python filter editor
    CreatePythonFilterEditor();
    editorTabs->addTab(pyEditorWidget, "Python Expression Editor");


    definitionLayout->addWidget(editorTabs,row,0,1,4);

    mainSplitter->addWidget(f2);

    // connect signals

    connect(exprListBox, SIGNAL(itemSelectionChanged()),
            this, SLOT(UpdateWindowSingleItem()));
    connect(nameEdit, SIGNAL(textChanged(const QString&)),
            this, SLOT(nameTextChanged(const QString&)));

    connect(newButton, SIGNAL(pressed()),
            this, SLOT(addExpression()));
    connect(delButton, SIGNAL(pressed()),
            this, SLOT(delExpression()));
    connect(typeList, SIGNAL(activated(int)),
            this, SLOT(typeChanged(int)));
    connect(displayAllVars, SIGNAL(clicked()),
            this, SLOT(displayAllVarsChanged()));
    connect(notHidden, SIGNAL(clicked()),
            this, SLOT(notHiddenChanged()));

}

// ****************************************************************************
// Method: QvisExpressionsWindow::CreateStandardEditor()
//
// Purpose:
//   Creates widgets used to construct standard visit expressions.
//   (pulled mostly from previous CreateWindowContents() method.)
//
//
// Programmer: Cyrus Harrison
// Creation:   Thu Feb 11 10:33:20 PST 2010
//
// Modifications:
//
// ****************************************************************************

void
QvisExpressionsWindow::CreateStandardEditor()
{
    stdEditorWidget = new QWidget();

    QGridLayout *layout = new QGridLayout(stdEditorWidget);
    int row = 0;

    stdDefinitionEditLabel = new QLabel(tr("Definition"), stdEditorWidget);
    layout->addWidget(stdDefinitionEditLabel, row, 0);
hrchilds's avatar
hrchilds committed
659 660
    row++;

cyrush's avatar
cyrush committed
661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734
    stdDefinitionEdit = new QTextEdit(stdEditorWidget);
    layout->addWidget(stdDefinitionEdit, row,0,1,4);
    row++;


    stdInsertFunctionButton = new QPushButton(tr("Insert Function..."));
    stdInsertFunctionMenu = new QMenu(stdEditorWidget);
    for (int i=0; i < NUM_EXPRESSION_CATEGORIES; i++)
    {
        QMenu *submnu = stdInsertFunctionMenu->addMenu(exprlist[i].name);
        for (int j=0; exprlist[i].list[j]; j++)
        {
            if (std::string(exprlist[i].list[j])=="&")
                submnu->addAction("&&");
            else
                submnu->addAction(exprlist[i].list[j]);
        }
        connect(submnu, SIGNAL(triggered(QAction *)),
                this, SLOT(stdInsertFunction(QAction *)));
    }
    stdInsertFunctionButton->setMenu(stdInsertFunctionMenu);
    layout->addWidget(stdInsertFunctionButton, row, 2);

    // Create a variable button so we can insert variables for the
    // active source.
    stdInsertVariableButton = new QvisVariableButton(false, false, false, -1,stdEditorWidget);
    stdInsertVariableButton->setChangeTextOnVariableChange(false);
    stdInsertVariableButton->setText(tr("Insert Variable..."));
    connect(stdInsertVariableButton, SIGNAL(activated(const QString &)),
            this, SLOT(stdInsertVariable(const QString &)));
    layout->addWidget(stdInsertVariableButton, row, 3);

    connect(stdDefinitionEdit, SIGNAL(textChanged()),
            this, SLOT(stdDefinitionTextChanged()));

}

// ****************************************************************************
// Method: QvisExpressionsWindow::CreatePythonFilterEditor()
//
// Purpose:
//   Creates widgets that compose the python expression filter editor.
//
//
// Programmer: Cyrus Harrison
// Creation:   2010 Thu Feb 11 10:47:51 PST 2010
//
// Modifications:
//
// ****************************************************************************

void
QvisExpressionsWindow::CreatePythonFilterEditor()
{
    pyEditorWidget = new QWidget();

    QGridLayout *layout = new QGridLayout(pyEditorWidget);
    int row = 0;

    pyArgsEditLabel = new QLabel(tr("Arguments"), pyEditorWidget);
    layout->addWidget(pyArgsEditLabel, row, 0);
    row++;

    pyArgsEdit = new QLineEdit(pyEditorWidget);
    layout->addWidget(pyArgsEdit, row,0,1,4);
    row++;


    connect(pyArgsEdit, SIGNAL(textChanged (const QString &)),
            this, SLOT(pyArgsTextChanged()));


    pyInsertFunctionButton = new QPushButton(tr("Insert Function..."));
    pyInsertFunctionMenu = new QMenu(pyEditorWidget);
hrchilds's avatar
hrchilds committed
735

736
    for (int i=0; i < NUM_EXPRESSION_CATEGORIES; i++)
hrchilds's avatar
hrchilds committed
737
    {
cyrush's avatar
cyrush committed
738
        QMenu *submnu = pyInsertFunctionMenu->addMenu(exprlist[i].name);
hrchilds's avatar
hrchilds committed
739 740
        for (int j=0; exprlist[i].list[j]; j++)
        {
741
            if (std::string(exprlist[i].list[j])=="&")
whitlocb's avatar
whitlocb committed
742
                submnu->addAction("&&");
743
            else
whitlocb's avatar
whitlocb committed
744
                submnu->addAction(exprlist[i].list[j]);
hrchilds's avatar
hrchilds committed
745
        }
cyrush's avatar
cyrush committed
746

whitlocb's avatar
whitlocb committed
747
        connect(submnu, SIGNAL(triggered(QAction *)),
cyrush's avatar
cyrush committed
748
                this, SLOT(pyInsertFunction(QAction *)));
hrchilds's avatar
hrchilds committed
749
    }
hrchilds's avatar
hrchilds committed
750 751 752

    // Create a variable button so we can insert variables for the
    // active source.
cyrush's avatar
cyrush committed
753 754 755 756 757 758 759 760 761 762 763
    pyInsertVariableButton = new QvisVariableButton(false, false, false, -1,pyEditorWidget);
    pyInsertVariableButton->setChangeTextOnVariableChange(false);
    pyInsertVariableButton->setText(tr("Insert Variable..."));

    connect(pyInsertVariableButton, SIGNAL(activated(const QString &)),
            this, SLOT(pyInsertVariable(const QString &)));

    layout->addWidget(pyInsertVariableButton, row, 3);

    pyInsertFunctionButton->setMenu(pyInsertFunctionMenu);
    layout->addWidget(pyInsertFunctionButton, row, 2);
hrchilds's avatar
hrchilds committed
764
    row++;
hrchilds's avatar
hrchilds committed
765

cyrush's avatar
cyrush committed
766 767 768 769 770 771 772 773 774 775 776 777 778
    pyFilterEditLabel = new QLabel(tr("Python Expression Script"), pyEditorWidget);

    pyFilterEdit = new QvisPythonFilterEditor();
    layout->addWidget(pyFilterEditLabel, row, 0);
    row++;
    layout->addWidget(pyFilterEdit,row,0,1,4);

    connect(pyFilterEdit, SIGNAL(sourceTextChanged()),
            this, SLOT(pyFilterSourceChanged()));

    connect(pyFilterEdit, SIGNAL(templateSelected(const QString &)),
            this, SLOT(pyTemplateSelected(const QString &)));

hrchilds's avatar
hrchilds committed
779 780
}

cyrush's avatar
cyrush committed
781

hrchilds's avatar
hrchilds committed
782 783 784 785 786 787 788 789 790 791
// ****************************************************************************
// Method: QvisExpressionsWindow::UpdateWindow
//
// Purpose: 
//   This method is called when the window's subject is changed. The
//   subject tells this window what attributes changed and we put the
//   new values into those widgets.
//
// Arguments:
//   doAll : If this flag is true, update all the widgets regardless
hrchilds's avatar
hrchilds committed
792
//           of whether or not they are selected.  Currently ignored.
hrchilds's avatar
hrchilds committed
793
//
hrchilds's avatar
hrchilds committed
794 795 796 797
// Programmer: Jeremy Meredith
// Creation:   October 10, 2004
//
// Modifications:
hrchilds's avatar
hrchilds committed
798 799 800 801
//    Jeremy Meredith, Mon Oct 25 12:52:45 PDT 2004
//    Always access the expression list by index, just in case there
//    are two expressions with the same name.  Keep in mind we need
//    a map from the list-position index to expressionlist index.
hrchilds's avatar
hrchilds committed
802
//
803 804 805
//    Jeremy Meredith, Tue Feb 19 14:20:57 EST 2008
//    Don't display expressions that were created by operators.
//
whitlocb's avatar
whitlocb committed
806 807 808
//    Cyrus Harrison, Wed Jun 11 13:49:19 PDT 2008
//    Initial Qt4 Port.
//
hrchilds's avatar
hrchilds committed
809 810 811 812 813 814 815
// ****************************************************************************
void
QvisExpressionsWindow::UpdateWindow(bool)
{
    BlockAllSignals(true);

    exprListBox->clear();
hrchilds's avatar
hrchilds committed
816 817
    indexMap.clear();
    int pos = 0;
hrchilds's avatar
hrchilds committed
818 819
    for (int i=0; i<exprList->GetNumExpressions(); i++)
    {
820 821
        if (exprList->GetExpressions(i).GetFromOperator())
            continue;
hrchilds's avatar
hrchilds committed
822
        if (displayAllVars->isChecked() ||
hrchilds's avatar
hrchilds committed
823
            !exprList->GetExpressions(i).GetFromDB())
hrchilds's avatar
hrchilds committed
824
        {
whitlocb's avatar
whitlocb committed
825
            exprListBox->addItem(exprList->GetExpressions(i).GetName().c_str());
hrchilds's avatar
hrchilds committed
826
            indexMap[pos++] = i;
hrchilds's avatar
hrchilds committed
827 828 829 830 831 832 833 834 835
        }
    }
    BlockAllSignals(false);

    UpdateWindowSingleItem();
}

// ****************************************************************************
//  Method:  QvisExpressionsWindow::UpdateWindowSingleItem
hrchilds's avatar
hrchilds committed
836
//
hrchilds's avatar
hrchilds committed
837 838
//  Purpose:
//    Update the pane of the window where a single expression is being edited.
hrchilds's avatar
hrchilds committed
839
//
hrchilds's avatar
hrchilds committed
840 841
//  Programmer:  Jeremy Meredith
//  Creation:    October 10, 2004
hrchilds's avatar
hrchilds committed
842
//
hrchilds's avatar
hrchilds committed
843 844 845 846 847 848
//  Modifications:
//    Jeremy Meredith, Mon Oct 25 11:34:35 PDT 2004
//    Reversed the sense of the "hidden" button.
//    Always access the expression list by index, just in case there
//    are two expressions with the same name.
//
whitlocb's avatar
whitlocb committed
849 850 851
//    Cyrus Harrison, Wed Jun 11 13:49:19 PDT 2008
//    Initial Qt4 Port.
//
hrchilds's avatar
hrchilds committed
852 853
// ****************************************************************************
void
hrchilds's avatar
hrchilds committed
854
QvisExpressionsWindow::UpdateWindowSingleItem()
hrchilds's avatar
hrchilds committed
855
{
whitlocb's avatar
whitlocb committed
856
    int index = exprListBox->currentRow();
hrchilds's avatar
hrchilds committed
857
    if (index <  0)
hrchilds's avatar
hrchilds committed
858 859
    {
        nameEdit->setText("");
hrchilds's avatar
hrchilds committed
860
        notHidden->setChecked(true);
cyrush's avatar
cyrush committed
861 862 863 864

        stdDefinitionEdit->setText("");
        pyArgsEdit->setText("");
        pyFilterEdit->setSource("");
865 866
        stdExprActive = true;
        pyExprActive = true;
hrchilds's avatar
hrchilds committed
867 868
    }
    else
hrchilds's avatar
hrchilds committed
869
    {
hrchilds's avatar
hrchilds committed
870 871
        Expression &e = (*exprList)[indexMap[index]];

hrchilds's avatar
hrchilds committed
872
        nameEdit->setText(e.GetName().c_str());
cyrush's avatar
cyrush committed
873

whitlocb's avatar
whitlocb committed
874 875
        int tidx = typeList->findText(Expression::GetTypeString(e.GetType()));
        typeList->setCurrentIndex(tidx);
cyrush's avatar
cyrush committed
876 877 878 879
        notHidden->setChecked(! e.GetHidden());

        QString expr_def = QString(e.GetDefinition().c_str());

880
        UpdateStandardExpressionEditor(expr_def);
cyrush's avatar
cyrush committed
881
        UpdatePythonExpressionEditor(expr_def);
882 883
        if(expr_def.trimmed() == QString("") && pyExprActive)
            stdExprActive = true;
hrchilds's avatar
hrchilds committed
884
    }
cyrush's avatar
cyrush committed
885

hrchilds's avatar
hrchilds committed
886 887
    UpdateWindowSensitivity();
}
hrchilds's avatar
hrchilds committed
888

hrchilds's avatar
hrchilds committed
889 890 891 892 893 894 895 896 897
// ****************************************************************************
//  Method:  QvisExpressionsWindow::UpdateWindowSensitivity
//
//  Purpose:
//    Update the sensitivity of any widget needing it.
//
//  Programmer:  Jeremy Meredith
//  Creation:    October 10, 2004
//
hrchilds's avatar
hrchilds committed
898 899 900 901 902 903
//  Modifications:
//    Jeremy Meredith, Mon Oct 25 11:34:35 PDT 2004
//    Reversed the sense of the "hidden" button.
//    Always access the expression list by index, just in case there
//    are two expressions with the same name.
//
hrchilds's avatar
hrchilds committed
904 905 906
//    Brad Whitlock, Thu Dec 9 14:04:22 PST 2004
//    Added a button to insert variable names.
//
907 908 909 910
//    Cyrus Harrison,  Mon Oct  1 16:24:32 PDT 2007
//    Changed definitionEdit to be readOnly instead of disabled
//    for database expressions so users can select/copy them.
//
whitlocb's avatar
whitlocb committed
911 912 913
//    Cyrus Harrison, Wed Jun 11 13:49:19 PDT 2008
//    Initial Qt4 Port.
//
hrchilds's avatar
hrchilds committed
914
// ****************************************************************************
hrchilds's avatar
hrchilds committed
915

hrchilds's avatar
hrchilds committed
916 917 918 919
void
QvisExpressionsWindow::UpdateWindowSensitivity()
{
    bool enable = true;
whitlocb's avatar
whitlocb committed
920
    int index = exprListBox->currentRow();
hrchilds's avatar
hrchilds committed
921 922

    if (index <  0)
hrchilds's avatar
hrchilds committed
923
    {
hrchilds's avatar
hrchilds committed
924 925
        enable = false;
    }
hrchilds's avatar
hrchilds committed
926
    else if ((*exprList)[indexMap[index]].GetFromDB())
hrchilds's avatar
hrchilds committed
927 928
    {
        enable = false;
hrchilds's avatar
hrchilds committed
929 930
    }

hrchilds's avatar
hrchilds committed
931 932
    nameEdit->setEnabled(enable);
    delButton->setEnabled(enable);
cyrush's avatar
cyrush committed
933

hrchilds's avatar
hrchilds committed
934
    typeList->setEnabled(enable);
cyrush's avatar
cyrush committed
935 936
    notHidden->setEnabled(enable);

937
    stdEditorWidget->setEnabled(enable && stdExprActive);
cyrush's avatar
cyrush committed
938
    pyEditorWidget->setEnabled(enable && pyExprActive);
hrchilds's avatar
hrchilds committed
939 940 941 942 943 944 945 946 947 948 949 950 951 952
}

// ****************************************************************************
//  Method:  QvisExpressionsWindow::BlockAllSignals
//
//  Purpose:
//    Block signals for all important widgets.  Or unblock, of course.
//
//  Arguments:
//    block      true to block, false to unblock
//
//  Programmer:  Jeremy Meredith
//  Creation:    October 10, 2004
//
953 954 955 956
// Modifications:
//   Cyrus Harrison, Fri Mar  5 13:22:24 PST 2010
//   Block signals from all edits related to python filters.
//
hrchilds's avatar
hrchilds committed
957 958 959 960 961 962
// ****************************************************************************
void
QvisExpressionsWindow::BlockAllSignals(bool block)
{
    exprListBox->blockSignals(block);
    nameEdit->blockSignals(block);
963 964 965 966

    stdDefinitionEdit->blockSignals(block);
    pyArgsEdit->blockSignals(block);
    pyFilterEdit->blockSignals(block);
hrchilds's avatar
hrchilds committed
967 968 969 970 971 972 973 974
}

// ****************************************************************************
// Method: QvisExpressionsWindow::Apply
//
// Purpose: 
//   This is a Qt slot function that is called when the Apply button is clicked.
//
hrchilds's avatar
hrchilds committed
975 976
// Programmer: Jeremy Meredith
// Creation:   October 10, 2004
hrchilds's avatar
hrchilds committed
977 978 979 980 981 982 983 984 985 986
//
// Modifications:
//   
// ****************************************************************************
void
QvisExpressionsWindow::Apply(bool forceUpdate)
{
    exprList->Notify();

    if (AutoUpdate() || forceUpdate)
hrchilds's avatar
hrchilds committed
987
        GetViewerMethods()->ProcessExpressions();
hrchilds's avatar
hrchilds committed
988 989 990 991 992 993 994 995 996
}

// ****************************************************************************
// Method: QvisExpressionsWindow::apply
//
// Purpose: 
//   This is a Qt slot function that is called when the window's Apply
//   button is clicked.
//
hrchilds's avatar
hrchilds committed
997 998
// Programmer: Jeremy Meredith
// Creation:   October 10, 2004
hrchilds's avatar
hrchilds committed
999 1000
//
// Modifications:
whitlocb's avatar
whitlocb committed
1001 1002 1003
//    Cyrus Harrison, Wed Jun 11 13:49:19 PDT 2008
//    Initial Qt4 Port.
//
1004 1005 1006 1007
//    Jeremy Meredith, Tue Jun  2 10:40:48 EDT 2009
//    Fix null pointer dereference when there's no current item (e.g. empty
//    window).
//
hrchilds's avatar
hrchilds committed
1008 1009 1010 1011
// ****************************************************************************
void
QvisExpressionsWindow::apply()
{
hrchilds's avatar
hrchilds committed
1012 1013
    // Apply will recreate the window and unselect the current expression.
    // If we have an expression selected, reselect it afterwards.
1014 1015 1016 1017
    bool reselect = (exprListBox->currentRow() != -1);
    QString item;
    if (reselect)
        item = exprListBox->currentItem()->text();
cyrush's avatar
cyrush committed
1018

hrchilds's avatar
hrchilds committed
1019
    Apply(true);
hrchilds's avatar
hrchilds committed
1020 1021 1022 1023 1024

    if (reselect)
    {
        for (int i=0; i<exprListBox->count(); i++)
        {
whitlocb's avatar
whitlocb committed
1025 1026 1027 1028 1029 1030 1031
            if (exprListBox->item(i)->text() == item)
            {
                exprListBox->item(i)->setSelected(true);
                exprListBox->setCurrentRow(i);
                UpdateWindowSingleItem();
                break;
            }
hrchilds's avatar
hrchilds committed
1032 1033
        }
    }
hrchilds's avatar
hrchilds committed
1034 1035 1036 1037 1038 1039 1040 1041
}

// ****************************************************************************
// Method: QvisExpressionsWindow::addExpression
//
// Purpose: 
//   This is a Qt slot function that adds a new expression that is empty.
//
hrchilds's avatar
hrchilds committed
1042 1043
// Programmer: Jeremy Meredith
// Creation:   October 10, 2004
hrchilds's avatar
hrchilds committed
1044 1045
//
// Modifications:
hrchilds's avatar
hrchilds committed
1046 1047 1048
//    Jeremy Meredith, Mon Oct 25 12:39:53 PDT 2004
//    Always access the expression list by index, just in case there
//    are two expressions with the same name.
whitlocb's avatar
whitlocb committed
1049 1050 1051 1052
//
//    Cyrus Harrison, Wed Jun 11 13:49:19 PDT 2008
//    Initial Qt4 Port.
//
hrchilds's avatar
hrchilds committed
1053 1054 1055 1056
// ****************************************************************************
void
QvisExpressionsWindow::addExpression()
{
hrchilds's avatar
hrchilds committed
1057 1058 1059 1060 1061 1062 1063
    // Find an unused expression name
    int newid = 1;
    bool okay = false;
    QString newName;
    while (!okay)
    {
        newName.sprintf("unnamed%d", newid);
whitlocb's avatar
whitlocb committed
1064
        if ((*exprList)[newName.toStdString().c_str()])
hrchilds's avatar
hrchilds committed
1065 1066 1067 1068
            newid++;
        else
            okay = true;
    }
hrchilds's avatar
hrchilds committed
1069

hrchilds's avatar
hrchilds committed
1070
    Expression e;
whitlocb's avatar
whitlocb committed
1071
    e.SetName(newName.toStdString());
hrchilds's avatar
hrchilds committed
1072
    e.SetDefinition("");
hrchilds's avatar
hrchilds committed
1073
    exprList->AddExpressions(e);
hrchilds's avatar
hrchilds committed
1074 1075

    exprList->Notify();
hrchilds's avatar
hrchilds committed
1076 1077 1078

    for (int i=0; i<exprListBox->count(); i++)
    {
whitlocb's avatar
whitlocb committed
1079 1080 1081 1082 1083 1084 1085
        if (exprListBox->item(i)->text() == newName)
        {
            exprListBox->item(i)->setSelected(true);
            exprListBox->setCurrentRow(i);
            UpdateWindowSingleItem();
            break;
        }
hrchilds's avatar
hrchilds committed
1086
    }
hrchilds's avatar
hrchilds committed
1087 1088 1089
}

// ****************************************************************************
hrchilds's avatar
hrchilds committed
1090
// Method: QvisExpressionsWindow::delExpression
hrchilds's avatar
hrchilds committed
1091 1092 1093 1094
//
// Purpose: 
//   This is a Qt slot function that is called to delete an expression.
//
hrchilds's avatar
hrchilds committed
1095 1096
// Programmer: Jeremy Meredith
// Creation:   October 10, 2004
hrchilds's avatar
hrchilds committed
1097 1098
//
// Modifications:
hrchilds's avatar
hrchilds committed
1099 1100 1101 1102
//    Jeremy Meredith, Mon Oct 17 10:39:56 PDT 2005
//    Made the delete action access the expression list by index in the
//    expression list (instead of assuming its index in the list box was
//    correct).  This was an oversight from my 10/25/04 change.  ('5682)
cyrush's avatar
cyrush committed
1103
//