diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 949fa0cebc9f5d58f953ee4194dc1c9c4d72aefa..e5cd347be430b51e5d7c9838530b9a6553d94b9c 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -57,7 +57,7 @@ native_Debian_clang: - mkdir build - cd build - cmake .. -DCMAKE_CXX_COMPILER_LAUNCHER=ccache #-DWERROR=ON - - xvfb-run make -j6 # TODO rm mvvm tests, then rm xvfb-run + - make -j6 - xvfb-run ctest -j6 --output-on-failure - make package_source artifacts: diff --git a/CMakeLists.txt b/CMakeLists.txt index 2e692f49d23546291dc90dd285e3caf8c10cd184..cc0034f1ef00457f51c555e2c9e7c06bd47cb37b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,7 +49,6 @@ add_custom_target(fullcheck COMMAND ${CMAKE_CTEST_COMMAND}) option(BORNAGAIN_PYTHON "Build with python support" ON) option(BORNAGAIN_GUI "Build a graphical user interface" ON) option(BORNAGAIN_TIFF_SUPPORT "Tiff files read/write support" ON) -option(BORNAGAIN_NEWREFL "Compile reflectometry GUI prototype" OFF) # options that are off by default (switch on for additional functionality) option(BORNAGAIN_MPI "Build with MPI support" OFF) @@ -163,10 +162,6 @@ if(BORNAGAIN_TIDY) set(CMAKE_CXX_CLANG_TIDY "clang-tidy") # has effect only if compiler is clang; uses .clang-tidy endif() -if(BORNAGAIN_NEWREFL) - add_subdirectory(mvvm) -endif() - # core components foreach(lib ${CoreComponents}) add_subdirectory(${lib}) @@ -192,10 +187,6 @@ if(BORNAGAIN_GUI) add_subdirectory(Tests/Unit/GUI) add_subdirectory(Tests/Performance/GUI) endif() -if(BORNAGAIN_NEWREFL) - add_subdirectory(gui2) - add_subdirectory(Tests/Unit/gui2) -endif() # TODO: split Core / GUI add_subdirectory(Tests/Functional) diff --git a/Tests/Unit/gui2/CMakeLists.txt b/Tests/Unit/gui2/CMakeLists.txt deleted file mode 100644 index 158fc060fb39c0caea366bb229aa7cb6d76d21bb..0000000000000000000000000000000000000000 --- a/Tests/Unit/gui2/CMakeLists.txt +++ /dev/null @@ -1,4 +0,0 @@ -include(GoogleTest) - -add_subdirectory(libtestmachinery) -add_subdirectory(testdareflcore) diff --git a/Tests/Unit/gui2/data/Untitled 1.csv b/Tests/Unit/gui2/data/Untitled 1.csv deleted file mode 100644 index 088bdf9ecf3f22526478f73a76c4ca5d76e2dba7..0000000000000000000000000000000000000000 --- a/Tests/Unit/gui2/data/Untitled 1.csv +++ /dev/null @@ -1,3 +0,0 @@ -# hello,,,, -1.23,42,abc,hello world,1.00E-03 -,,,,1.00E-03 diff --git a/Tests/Unit/gui2/data/bilayer1.txt b/Tests/Unit/gui2/data/bilayer1.txt deleted file mode 100644 index 7ea696e626e43fb73fc6dfad200cb5a2a823c93e..0000000000000000000000000000000000000000 --- a/Tests/Unit/gui2/data/bilayer1.txt +++ /dev/null @@ -1,503 +0,0 @@ -# BornAgain Intensity Data -# Simple array suitable for numpy, matlab etc. -# coordinates intensities -3.000000000000e-03 1.000000000000e+08 -9.000000000000e-03 1.000000000000e+08 -1.500000000000e-02 1.000000000000e+08 -2.100000000000e-02 1.000000000000e+08 -2.700000000000e-02 1.000000000000e+08 -3.300000000000e-02 1.000000000000e+08 -3.900000000000e-02 1.000000000000e+08 -4.500000000000e-02 1.000000000000e+08 -5.100000000000e-02 1.000000000000e+08 -5.700000000000e-02 1.000000000000e+08 -6.300000000000e-02 1.000000000000e+08 -6.900000000000e-02 1.000000000000e+08 -7.500000000000e-02 1.000000000000e+08 -8.100000000000e-02 1.000000000000e+08 -8.700000000000e-02 1.000000000000e+08 -9.300000000000e-02 1.000000000000e+08 -9.900000000000e-02 1.000000000000e+08 -1.050000000000e-01 1.000000000000e+08 -1.110000000000e-01 1.000000000000e+08 -1.170000000000e-01 1.000000000000e+08 -1.230000000000e-01 1.000000000000e+08 -1.290000000000e-01 1.000000000000e+08 -1.350000000000e-01 1.000000000000e+08 -1.410000000000e-01 1.000000000000e+08 -1.470000000000e-01 1.000000000000e+08 -1.530000000000e-01 1.000000000000e+08 -1.590000000000e-01 1.000000000000e+08 -1.650000000000e-01 1.000000000000e+08 -1.710000000000e-01 1.000000000000e+08 -1.770000000000e-01 1.000000000000e+08 -1.830000000000e-01 1.000000000000e+08 -1.890000000000e-01 1.000000000000e+08 -1.950000000000e-01 1.000000000000e+08 -2.010000000000e-01 1.000000000000e+08 -2.070000000000e-01 1.000000000000e+08 -2.130000000000e-01 1.000000000000e+08 -2.190000000000e-01 1.000000000000e+08 -2.250000000000e-01 1.000000000000e+08 -2.310000000000e-01 1.000000000000e+08 -2.370000000000e-01 1.000000000000e+08 -2.430000000000e-01 1.000000000000e+08 -2.490000000000e-01 1.000000000000e+08 -2.550000000000e-01 1.000000000000e+08 -2.610000000000e-01 1.000000000000e+08 -2.670000000000e-01 1.000000000000e+08 -2.730000000000e-01 1.000000000000e+08 -2.790000000000e-01 1.000000000000e+08 -2.850000000000e-01 1.000000000000e+08 -2.910000000000e-01 1.000000000000e+08 -2.970000000000e-01 1.000000000000e+08 -3.030000000000e-01 1.000000000000e+08 -3.090000000000e-01 1.000000000000e+08 -3.150000000000e-01 5.252514859094e+07 -3.210000000000e-01 3.012698683171e+07 -3.270000000000e-01 2.598017445747e+07 -3.330000000000e-01 2.207918447065e+07 -3.390000000000e-01 1.700163778446e+07 -3.450000000000e-01 1.124384831399e+07 -3.510000000000e-01 5.894216058224e+06 -3.570000000000e-01 2.045875035710e+06 -3.630000000000e-01 2.612612187593e+05 -3.690000000000e-01 3.553472115495e+05 -3.750000000000e-01 1.639935104717e+06 -3.810000000000e-01 3.348957557669e+06 -3.870000000000e-01 4.919489547851e+06 -3.930000000000e-01 6.059794537745e+06 -3.990000000000e-01 6.697353636462e+06 -4.050000000000e-01 6.896494971676e+06 -4.110000000000e-01 6.785236400962e+06 -4.170000000000e-01 6.500627600727e+06 -4.230000000000e-01 6.153148375207e+06 -4.290000000000e-01 5.809750069296e+06 -4.350000000000e-01 5.493631632724e+06 -4.410000000000e-01 5.195872583352e+06 -4.470000000000e-01 4.892004284118e+06 -4.530000000000e-01 4.557147798544e+06 -4.590000000000e-01 4.175921375539e+06 -4.650000000000e-01 3.746248183213e+06 -4.710000000000e-01 3.278240411146e+06 -4.770000000000e-01 2.790207969710e+06 -4.830000000000e-01 2.303819951618e+06 -4.890000000000e-01 1.839923758771e+06 -4.950000000000e-01 1.415807188754e+06 -5.010000000000e-01 1.044000666592e+06 -5.070000000000e-01 7.322305116300e+05 -5.130000000000e-01 4.839406040953e+05 -5.190000000000e-01 2.988835068687e+05 -5.250000000000e-01 1.735342981890e+05 -5.310000000000e-01 1.013542213516e+05 -5.370000000000e-01 7.310587248886e+04 -5.430000000000e-01 7.744355864765e+04 -5.490000000000e-01 1.018917826225e+05 -5.550000000000e-01 1.341514306365e+05 -5.610000000000e-01 1.635185514329e+05 -5.670000000000e-01 1.821233501493e+05 -5.730000000000e-01 1.857166663723e+05 -5.790000000000e-01 1.738314448531e+05 -5.850000000000e-01 1.492907247457e+05 -5.910000000000e-01 1.171801679809e+05 -5.970000000000e-01 8.351662911654e+04 -6.030000000000e-01 5.390001180840e+04 -6.090000000000e-01 3.242267091364e+04 -6.150000000000e-01 2.103412105088e+04 -6.210000000000e-01 1.944030846708e+04 -6.270000000000e-01 2.548896974943e+04 -6.330000000000e-01 3.588964907170e+04 -6.390000000000e-01 4.706291010464e+04 -6.450000000000e-01 5.591549983531e+04 -6.510000000000e-01 6.038737127484e+04 -6.570000000000e-01 5.969251386486e+04 -6.630000000000e-01 5.425572873747e+04 -6.690000000000e-01 4.541285854175e+04 -6.750000000000e-01 3.498081870649e+04 -6.810000000000e-01 2.481237243398e+04 -6.870000000000e-01 1.643234504228e+04 -6.930000000000e-01 1.081552781744e+04 -6.990000000000e-01 8.323253206492e+03 -7.050000000000e-01 8.776764935406e+03 -7.110000000000e-01 1.161947498279e+04 -7.170000000000e-01 1.611085368163e+04 -7.230000000000e-01 2.150103328993e+04 -7.290000000000e-01 2.715243717928e+04 -7.350000000000e-01 3.259627083081e+04 -7.410000000000e-01 3.753117289947e+04 -7.470000000000e-01 4.178420659253e+04 -7.530000000000e-01 4.525877439075e+04 -7.590000000000e-01 4.789064698061e+04 -7.650000000000e-01 4.962470561352e+04 -7.710000000000e-01 5.041468557126e+04 -7.770000000000e-01 5.023946698323e+04 -7.830000000000e-01 4.912454180710e+04 -7.890000000000e-01 4.715697407517e+04 -7.950000000000e-01 4.448580133922e+04 -8.010000000000e-01 4.130570270374e+04 -8.070000000000e-01 3.782778142640e+04 -8.130000000000e-01 3.424561360256e+04 -8.190000000000e-01 3.070615998786e+04 -8.250000000000e-01 2.729353988637e+04 -8.310000000000e-01 2.402973458658e+04 -8.370000000000e-01 2.089133593006e+04 -8.430000000000e-01 1.783697311592e+04 -8.490000000000e-01 1.483727551455e+04 -8.550000000000e-01 1.189883038377e+04 -8.610000000000e-01 9.075542431390e+03 -8.670000000000e-01 6.464438341853e+03 -8.730000000000e-01 4.187223684167e+03 -8.790000000000e-01 2.362640545612e+03 -8.850000000000e-01 1.076952744978e+03 -8.910000000000e-01 3.601982340400e+02 -8.970000000000e-01 1.742228205630e+02 -9.030000000000e-01 4.154585792631e+02 -9.090000000000e-01 9.317689964478e+02 -9.150000000000e-01 1.549375855374e+03 -9.210000000000e-01 2.103689179321e+03 -9.270000000000e-01 2.467234625757e+03 -9.330000000000e-01 2.568856763889e+03 -9.390000000000e-01 2.400630693471e+03 -9.450000000000e-01 2.011826706273e+03 -9.510000000000e-01 1.492127916676e+03 -9.570000000000e-01 9.484554472550e+02 -9.630000000000e-01 4.807798502925e+02 -9.690000000000e-01 1.620542932011e+02 -9.750000000000e-01 2.605684004077e+01 -9.810000000000e-01 6.487373737703e+01 -9.870000000000e-01 2.355145801321e+02 -9.930000000000e-01 4.732386443163e+02 -9.990000000000e-01 7.079811563525e+02 -1.005000000000e+00 8.799899223938e+02 -1.011000000000e+00 9.513840273463e+02 -1.017000000000e+00 9.116016899542e+02 -1.023000000000e+00 7.762665942107e+02 -1.029000000000e+00 5.804931483896e+02 -1.035000000000e+00 3.687501821765e+02 -1.041000000000e+00 1.839108034027e+02 -1.047000000000e+00 5.798768265208e+01 -1.053000000000e+00 6.388412606318e+00 -1.059000000000e+00 2.653308060155e+01 -1.065000000000e+00 1.006134440434e+02 -1.071000000000e+00 2.013840278680e+02 -1.077000000000e+00 2.993372430959e+02 -1.083000000000e+00 3.695056628377e+02 -1.089000000000e+00 3.964284303879e+02 -1.095000000000e+00 3.764023029455e+02 -1.101000000000e+00 3.168468060338e+02 -1.107000000000e+00 2.332747364964e+02 -1.113000000000e+00 1.448322463138e+02 -1.119000000000e+00 6.957433175815e+01 -1.125000000000e+00 2.055942210642e+01 -1.131000000000e+00 3.533273693131e+00 -1.137000000000e+00 1.652519628052e+01 -1.143000000000e+00 5.121453957676e+01 -1.149000000000e+00 9.554819709694e+01 -1.155000000000e+00 1.368741048667e+02 -1.161000000000e+00 1.648298823364e+02 -1.167000000000e+00 1.733725913735e+02 -1.173000000000e+00 1.616013721760e+02 -1.179000000000e+00 1.333357643762e+02 -1.185000000000e+00 9.569404525212e+01 -1.191000000000e+00 5.710882647854e+01 -1.197000000000e+00 2.528930524411e+01 -1.203000000000e+00 5.589633248060e+00 -1.209000000000e+00 9.685301973864e-02 -1.215000000000e+00 7.553960625711e+00 -1.221000000000e+00 2.403421996281e+01 -1.227000000000e+00 4.412637839279e+01 -1.233000000000e+00 6.230639865021e+01 -1.239000000000e+00 7.416948285793e+01 -1.245000000000e+00 7.726682024298e+01 -1.251000000000e+00 7.141005334040e+01 -1.257000000000e+00 5.844076524817e+01 -1.263000000000e+00 4.158068442096e+01 -1.269000000000e+00 2.455658449552e+01 -1.275000000000e+00 1.071971199477e+01 -1.281000000000e+00 2.353813983483e+00 -1.287000000000e+00 3.005661375010e-01 -1.293000000000e+00 3.945723175434e+00 -1.299000000000e+00 1.152495824347e+01 -1.305000000000e+00 2.064351684780e+01 -1.311000000000e+00 2.887025340096e+01 -1.317000000000e+00 3.426774243825e+01 -1.323000000000e+00 3.575131347599e+01 -1.329000000000e+00 3.322041130650e+01 -1.335000000000e+00 2.746211842145e+01 -1.341000000000e+00 1.987594246567e+01 -1.347000000000e+00 1.210128223223e+01 -1.353000000000e+00 5.639532579466e+00 -1.359000000000e+00 1.552136988813e+00 -1.365000000000e+00 2.891476075167e-01 -1.371000000000e+00 1.667923547168e+00 -1.377000000000e+00 4.987115324857e+00 -1.383000000000e+00 9.234405820501e+00 -1.389000000000e+00 1.333226856725e+01 -1.395000000000e+00 1.636558610667e+01 -1.401000000000e+00 1.774650634868e+01 -1.407000000000e+00 1.729124778044e+01 -1.413000000000e+00 1.520545393990e+01 -1.419000000000e+00 1.199411115295e+01 -1.425000000000e+00 8.325218972109e+00 -1.431000000000e+00 4.881478238306e+00 -1.437000000000e+00 2.231397254863e+00 -1.443000000000e+00 7.422547653667e-01 -1.449000000000e+00 5.451669528739e-01 -1.455000000000e+00 1.550194563148e+00 -1.461000000000e+00 3.499631764593e+00 -1.467000000000e+00 6.042002269970e+00 -1.473000000000e+00 8.808330890036e+00 -1.479000000000e+00 1.147534650191e+01 -1.485000000000e+00 1.380601452504e+01 -1.491000000000e+00 1.566446383137e+01 -1.497000000000e+00 1.700833886314e+01 -1.503000000000e+00 1.786569662793e+01 -1.509000000000e+00 1.830524027392e+01 -1.515000000000e+00 1.840804239515e+01 -1.521000000000e+00 1.824657495470e+01 -1.527000000000e+00 1.787371567566e+01 -1.533000000000e+00 1.732134773479e+01 -1.539000000000e+00 1.660591713644e+01 -1.545000000000e+00 1.573723665868e+01 -1.551000000000e+00 1.472694297380e+01 -1.557000000000e+00 1.359404209136e+01 -1.563000000000e+00 1.236646083375e+01 -1.569000000000e+00 1.107897282003e+01 -1.575000000000e+00 9.768900113463e+00 -1.581000000000e+00 8.471401440781e+00 -1.587000000000e+00 7.215944087707e+00 -1.593000000000e+00 6.024889492988e+00 -1.599000000000e+00 4.914271073357e+00 -1.605000000000e+00 3.896087194742e+00 -1.611000000000e+00 2.980986389883e+00 -1.617000000000e+00 2.180184049918e+00 -1.623000000000e+00 1.505789869334e+00 -1.629000000000e+00 9.693084156900e-01 -1.635000000000e+00 5.787099565727e-01 -1.641000000000e+00 3.349652317572e-01 -1.647000000000e+00 2.291592747697e-01 -1.653000000000e+00 2.411940062404e-01 -1.659000000000e+00 3.406976461652e-01 -1.665000000000e+00 4.901959680567e-01 -1.671000000000e+00 6.500200118542e-01 -1.677000000000e+00 7.839776460741e-01 -1.683000000000e+00 8.646113730324e-01 -1.689000000000e+00 8.769449155523e-01 -1.695000000000e+00 8.199569398427e-01 -1.701000000000e+00 7.055219875813e-01 -1.707000000000e+00 5.551020688246e-01 -1.713000000000e+00 3.949308077616e-01 -1.719000000000e+00 2.507066890908e-01 -1.725000000000e+00 1.428527972346e-01 -1.731000000000e+00 8.321410089400e-02 -1.737000000000e+00 7.370702466211e-02 -1.743000000000e+00 1.070003052480e-01 -1.749000000000e+00 1.688914182450e-01 -1.755000000000e+00 2.417360697923e-01 -1.761000000000e+00 3.081445009584e-01 -1.767000000000e+00 3.541918189630e-01 -1.773000000000e+00 3.715744431348e-01 -1.779000000000e+00 3.584251551441e-01 -1.785000000000e+00 3.188048211136e-01 -1.791000000000e+00 2.611519361094e-01 -1.797000000000e+00 1.961413608508e-01 -1.803000000000e+00 1.344569729125e-01 -1.809000000000e+00 8.492388413329e-02 -1.815000000000e+00 5.330271467128e-02 -1.821000000000e+00 4.186401643081e-02 -1.827000000000e+00 4.968121875287e-02 -1.833000000000e+00 7.344371983263e-02 -1.839000000000e+00 1.085210839501e-01 -1.845000000000e+00 1.500095739838e-01 -1.851000000000e+00 1.935515405895e-01 -1.857000000000e+00 2.358130022440e-01 -1.863000000000e+00 2.746071330557e-01 -1.869000000000e+00 3.087361116047e-01 -1.875000000000e+00 3.376739301577e-01 -1.881000000000e+00 3.612224387723e-01 -1.887000000000e+00 3.792470437035e-01 -1.893000000000e+00 3.915500287142e-01 -1.899000000000e+00 3.978849712878e-01 -1.905000000000e+00 3.980706849141e-01 -1.911000000000e+00 3.921382084322e-01 -1.917000000000e+00 3.804433731288e-01 -1.923000000000e+00 3.636972508307e-01 -1.929000000000e+00 3.428989416427e-01 -1.935000000000e+00 3.191889395030e-01 -1.941000000000e+00 2.936667229232e-01 -1.947000000000e+00 2.672266056918e-01 -1.953000000000e+00 2.404593840578e-01 -1.959000000000e+00 2.136469154969e-01 -1.965000000000e+00 1.868490557894e-01 -1.971000000000e+00 1.600555338416e-01 -1.977000000000e+00 1.333568028392e-01 -1.983000000000e+00 1.070824734350e-01 -1.989000000000e+00 8.186467665437e-02 -1.995000000000e+00 5.860389664006e-02 -2.001000000000e+00 3.834085436803e-02 -2.007000000000e+00 2.206302403909e-02 -2.013000000000e+00 1.049195749140e-02 -2.019000000000e+00 3.903507779074e-03 -2.025000000000e+00 2.026067164797e-03 -2.031000000000e+00 4.044061867603e-03 -2.037000000000e+00 8.709742894548e-03 -2.043000000000e+00 1.454169219730e-02 -2.049000000000e+00 2.006920819455e-02 -2.055000000000e+00 2.407213186862e-02 -2.061000000000e+00 2.576758645396e-02 -2.067000000000e+00 2.490765921304e-02 -2.073000000000e+00 2.177199726464e-02 -2.079000000000e+00 1.706185751924e-02 -2.085000000000e+00 1.172224505928e-02 -2.091000000000e+00 6.732132882175e-03 -2.097000000000e+00 2.906860585535e-03 -2.103000000000e+00 7.513376013128e-04 -2.109000000000e+00 3.894261669134e-04 -2.115000000000e+00 1.577226510581e-03 -2.121000000000e+00 3.790028154193e-03 -2.127000000000e+00 6.358289995263e-03 -2.133000000000e+00 8.619967896990e-03 -2.139000000000e+00 1.005602820967e-02 -2.145000000000e+00 1.038254481335e-02 -2.151000000000e+00 9.584376436546e-03 -2.157000000000e+00 7.889143343748e-03 -2.163000000000e+00 5.692946516061e-03 -2.169000000000e+00 3.458367515877e-03 -2.175000000000e+00 1.609142146106e-03 -2.181000000000e+00 4.441814774837e-04 -2.187000000000e+00 8.721929928972e-05 -2.193000000000e+00 4.791188360112e-04 -2.199000000000e+00 1.410038951418e-03 -2.205000000000e+00 2.580414479250e-03 -2.211000000000e+00 3.674665488006e-03 -2.217000000000e+00 4.430482330584e-03 -2.223000000000e+00 4.689267824495e-03 -2.229000000000e+00 4.418878822738e-03 -2.235000000000e+00 3.706706582359e-03 -2.241000000000e+00 2.727739705572e-03 -2.247000000000e+00 1.697165559335e-03 -2.253000000000e+00 8.193972203199e-04 -2.259000000000e+00 2.449263394940e-04 -2.265000000000e+00 4.349777691636e-05 -2.271000000000e+00 1.976630704601e-04 -2.277000000000e+00 6.159217793450e-04 -2.283000000000e+00 1.160498424648e-03 -2.289000000000e+00 1.682159338746e-03 -2.295000000000e+00 2.053761384789e-03 -2.301000000000e+00 2.195392204941e-03 -2.307000000000e+00 2.086554798175e-03 -2.313000000000e+00 1.764151202025e-03 -2.319000000000e+00 1.308236813323e-03 -2.325000000000e+00 8.199582378989e-04 -2.331000000000e+00 3.973062382952e-04 -2.337000000000e+00 1.141789175617e-04 -2.343000000000e+00 6.935255316084e-06 -2.349000000000e+00 7.053974315914e-05 -2.355000000000e+00 2.640901841824e-04 -2.361000000000e+00 5.235095555347e-04 -2.367000000000e+00 7.778732542680e-04 -2.373000000000e+00 9.654423599251e-04 -2.379000000000e+00 1.045968482009e-03 -2.385000000000e+00 1.007020021568e-03 -2.391000000000e+00 8.636200583148e-04 -2.397000000000e+00 6.520092067897e-04 -2.403000000000e+00 4.195247264000e-04 -2.409000000000e+00 2.132036072721e-04 -2.415000000000e+00 6.970199758118e-05 -2.421000000000e+00 8.550700321100e-06 -2.427000000000e+00 2.982320015770e-05 -2.433000000000e+00 1.162243685951e-04 -2.439000000000e+00 2.386591440051e-04 -2.445000000000e+00 3.637017069182e-04 -2.451000000000e+00 4.611586800717e-04 -2.457000000000e+00 5.101058145100e-04 -2.463000000000e+00 5.022885633666e-04 -2.469000000000e+00 4.424653822577e-04 -2.475000000000e+00 3.459703015307e-04 -2.481000000000e+00 2.343280663708e-04 -2.487000000000e+00 1.300689588041e-04 -2.493000000000e+00 5.192362162136e-05 -2.499000000000e+00 1.135777882358e-05 -2.505000000000e+00 1.101053682869e-05 -2.511000000000e+00 4.513368845897e-05 -2.517000000000e+00 1.017005902531e-04 -2.523000000000e+00 1.655476467796e-04 -2.529000000000e+00 2.217779332109e-04 -2.535000000000e+00 2.587008757938e-04 -2.541000000000e+00 2.697715073803e-04 -2.547000000000e+00 2.542684838268e-04 -2.553000000000e+00 2.167423256019e-04 -2.559000000000e+00 1.655107291819e-04 -2.565000000000e+00 1.106314944511e-04 -2.571000000000e+00 6.182655684059e-05 -2.577000000000e+00 2.676991417401e-05 -2.583000000000e+00 1.001595747579e-05 -2.589000000000e+00 1.267280981732e-05 -2.595000000000e+00 3.275925673414e-05 -2.601000000000e+00 6.605762409946e-05 -2.607000000000e+00 1.072086379867e-04 -2.613000000000e+00 1.507919634046e-04 -2.619000000000e+00 1.921874292699e-04 -2.625000000000e+00 2.280966571349e-04 -2.631000000000e+00 2.566988301301e-04 -2.637000000000e+00 2.774956437834e-04 -2.643000000000e+00 2.909536771099e-04 -2.649000000000e+00 2.980710678708e-04 -2.655000000000e+00 2.999820248777e-04 -2.661000000000e+00 2.976765390560e-04 -2.667000000000e+00 2.918666321535e-04 -2.673000000000e+00 2.829873260216e-04 -2.679000000000e+00 2.712898625067e-04 -2.685000000000e+00 2.569716613577e-04 -2.691000000000e+00 2.402915438887e-04 -2.697000000000e+00 2.216356335912e-04 -2.703000000000e+00 2.015219971164e-04 -2.709000000000e+00 1.805534687884e-04 -2.715000000000e+00 1.593425928727e-04 -2.721000000000e+00 1.384373744965e-04 -2.727000000000e+00 1.182718747812e-04 -2.733000000000e+00 9.915427547722e-05 -2.739000000000e+00 8.129126336467e-05 -2.745000000000e+00 6.483566110525e-05 -2.751000000000e+00 4.993754168949e-05 -2.757000000000e+00 3.677905453287e-05 -2.763000000000e+00 2.557929860609e-05 -2.769000000000e+00 1.656562939583e-05 -2.775000000000e+00 9.918628881197e-06 -2.781000000000e+00 5.706496022232e-06 -2.787000000000e+00 3.828543729780e-06 -2.793000000000e+00 3.985891072049e-06 -2.799000000000e+00 5.690916157634e-06 -2.805000000000e+00 8.317433018578e-06 -2.811000000000e+00 1.118342383429e-05 -2.817000000000e+00 1.365006210690e-05 -2.823000000000e+00 1.521664385075e-05 -2.829000000000e+00 1.559177206943e-05 -2.835000000000e+00 1.472638466250e-05 -2.841000000000e+00 1.280257958021e-05 -2.847000000000e+00 1.018162734844e-05 -2.853000000000e+00 7.322887836363e-06 -2.859000000000e+00 4.690766528013e-06 -2.865000000000e+00 2.668333036880e-06 -2.871000000000e+00 1.493702548128e-06 -2.877000000000e+00 1.229572266712e-06 -2.883000000000e+00 1.768868670416e-06 -2.889000000000e+00 2.872019234063e-06 -2.895000000000e+00 4.225492516267e-06 -2.901000000000e+00 5.508049212697e-06 -2.907000000000e+00 6.451033954906e-06 -2.913000000000e+00 6.881726894484e-06 -2.919000000000e+00 6.743407519357e-06 -2.925000000000e+00 6.091176476915e-06 -2.931000000000e+00 5.067517565017e-06 -2.937000000000e+00 3.865082057340e-06 -2.943000000000e+00 2.685684836981e-06 -2.949000000000e+00 1.703957215000e-06 -2.955000000000e+00 1.041892583538e-06 -2.961000000000e+00 7.573494174399e-07 -2.967000000000e+00 8.462531718732e-07 -2.973000000000e+00 1.255500079232e-06 -2.979000000000e+00 1.901914988380e-06 -2.985000000000e+00 2.692240646279e-06 -2.991000000000e+00 3.539915599577e-06 -2.997000000000e+00 4.375966275944e-06 diff --git a/Tests/Unit/gui2/data/bilayer2.txt b/Tests/Unit/gui2/data/bilayer2.txt deleted file mode 100644 index 3cea18c7c9c9f73b817261943b76477a6cdc5e82..0000000000000000000000000000000000000000 --- a/Tests/Unit/gui2/data/bilayer2.txt +++ /dev/null @@ -1,503 +0,0 @@ -# BornAgain Intensity Data -# Simple array suitable for numpy, matlab etc. -# coordinates intensities -3.000000000000e-03 1.000000000000e+08 -9.000000000000e-03 1.000000000000e+08 -1.500000000000e-02 1.000000000000e+08 -2.100000000000e-02 1.000000000000e+08 -2.700000000000e-02 1.000000000000e+08 -3.300000000000e-02 1.000000000000e+08 -3.900000000000e-02 1.000000000000e+08 -4.500000000000e-02 1.000000000000e+08 -5.100000000000e-02 1.000000000000e+08 -5.700000000000e-02 1.000000000000e+08 -6.300000000000e-02 1.000000000000e+08 -6.900000000000e-02 1.000000000000e+08 -7.500000000000e-02 1.000000000000e+08 -8.100000000000e-02 1.000000000000e+08 -8.700000000000e-02 1.000000000000e+08 -9.300000000000e-02 1.000000000000e+08 -9.900000000000e-02 1.000000000000e+08 -1.050000000000e-01 1.000000000000e+08 -1.110000000000e-01 1.000000000000e+08 -1.170000000000e-01 1.000000000000e+08 -1.230000000000e-01 1.000000000000e+08 -1.290000000000e-01 1.000000000000e+08 -1.350000000000e-01 1.000000000000e+08 -1.410000000000e-01 1.000000000000e+08 -1.470000000000e-01 1.000000000000e+08 -1.530000000000e-01 1.000000000000e+08 -1.590000000000e-01 1.000000000000e+08 -1.650000000000e-01 1.000000000000e+08 -1.710000000000e-01 1.000000000000e+08 -1.770000000000e-01 1.000000000000e+08 -1.830000000000e-01 1.000000000000e+08 -1.890000000000e-01 1.000000000000e+08 -1.950000000000e-01 1.000000000000e+08 -2.010000000000e-01 1.000000000000e+08 -2.070000000000e-01 1.000000000000e+08 -2.130000000000e-01 1.000000000000e+08 -2.190000000000e-01 1.000000000000e+08 -2.250000000000e-01 1.000000000000e+08 -2.310000000000e-01 1.000000000000e+08 -2.370000000000e-01 1.000000000000e+08 -2.430000000000e-01 1.000000000000e+08 -2.490000000000e-01 1.000000000000e+08 -2.550000000000e-01 1.000000000000e+08 -2.610000000000e-01 1.000000000000e+08 -2.670000000000e-01 1.000000000000e+08 -2.730000000000e-01 1.000000000000e+08 -2.790000000000e-01 1.000000000000e+08 -2.850000000000e-01 1.000000000000e+08 -2.910000000000e-01 1.000000000000e+08 -2.970000000000e-01 1.000000000000e+08 -3.030000000000e-01 1.000000000000e+08 -3.090000000000e-01 1.000000000000e+08 -3.150000000000e-01 4.958890595531e+07 -3.210000000000e-01 2.784755638488e+07 -3.270000000000e-01 2.517579061861e+07 -3.330000000000e-01 2.253765402056e+07 -3.390000000000e-01 1.835954817644e+07 -3.450000000000e-01 1.301817054916e+07 -3.510000000000e-01 7.531087265117e+06 -3.570000000000e-01 3.093202985447e+06 -3.630000000000e-01 5.620776609678e+05 -3.690000000000e-01 7.596761289755e+04 -3.750000000000e-01 1.112265320103e+06 -3.810000000000e-01 2.884476724466e+06 -3.870000000000e-01 4.714730894570e+06 -3.930000000000e-01 6.191043235474e+06 -3.990000000000e-01 7.154732942568e+06 -4.050000000000e-01 7.622556290697e+06 -4.110000000000e-01 7.705227830434e+06 -4.170000000000e-01 7.542030261838e+06 -4.230000000000e-01 7.254861890767e+06 -4.290000000000e-01 6.922529533066e+06 -4.350000000000e-01 6.575040691861e+06 -4.410000000000e-01 6.204198400524e+06 -4.470000000000e-01 5.783116414212e+06 -4.530000000000e-01 5.286318021468e+06 -4.590000000000e-01 4.704240550861e+06 -4.650000000000e-01 4.049431386988e+06 -4.710000000000e-01 3.354683709148e+06 -4.770000000000e-01 2.665204104379e+06 -4.830000000000e-01 2.027837099839e+06 -4.890000000000e-01 1.480630274508e+06 -4.950000000000e-01 1.045577831755e+06 -5.010000000000e-01 7.261925554482e+05 -5.070000000000e-01 5.099194483346e+05 -5.130000000000e-01 3.739299274257e+05 -5.190000000000e-01 2.920843125611e+05 -5.250000000000e-01 2.409834539126e+05 -5.310000000000e-01 2.037837787609e+05 -5.370000000000e-01 1.713874205511e+05 -5.430000000000e-01 1.413951843072e+05 -5.490000000000e-01 1.156699421907e+05 -5.550000000000e-01 9.749347302431e+04 -5.610000000000e-01 8.917182522366e+04 -5.670000000000e-01 9.063966365952e+04 -5.730000000000e-01 9.923352555011e+04 -5.790000000000e-01 1.104525516332e+05 -5.850000000000e-01 1.192894671663e+05 -5.910000000000e-01 1.216367404595e+05 -5.970000000000e-01 1.153425224947e+05 -6.030000000000e-01 1.006585222378e+05 -6.090000000000e-01 8.002378077552e+04 -6.150000000000e-01 5.730850706804e+04 -6.210000000000e-01 3.676325246995e+04 -6.270000000000e-01 2.196327853873e+04 -6.330000000000e-01 1.500677624787e+04 -6.390000000000e-01 1.613522522934e+04 -6.450000000000e-01 2.382321562681e+04 -6.510000000000e-01 3.526706099044e+04 -6.570000000000e-01 4.711579322237e+04 -6.630000000000e-01 5.625158504106e+04 -6.690000000000e-01 6.044059969400e+04 -6.750000000000e-01 5.872787890710e+04 -6.810000000000e-01 5.152230450258e+04 -6.870000000000e-01 4.039056862521e+04 -6.930000000000e-01 2.763713254338e+04 -6.990000000000e-01 1.578101382033e+04 -7.050000000000e-01 7.046816484403e+03 -7.110000000000e-01 2.969209888992e+03 -7.170000000000e-01 4.174050946452e+03 -7.230000000000e-01 1.035531971996e+04 -7.290000000000e-01 2.042536370361e+04 -7.350000000000e-01 3.278516999038e+04 -7.410000000000e-01 4.564639598747e+04 -7.470000000000e-01 5.733822466293e+04 -7.530000000000e-01 6.654654750581e+04 -7.590000000000e-01 7.245503774571e+04 -7.650000000000e-01 7.478137974017e+04 -7.710000000000e-01 7.372223636517e+04 -7.770000000000e-01 6.983421928668e+04 -7.830000000000e-01 6.388394378877e+04 -7.890000000000e-01 5.669874737633e+04 -7.950000000000e-01 4.904265636952e+04 -8.010000000000e-01 4.153219039444e+04 -8.070000000000e-01 3.459615295473e+04 -8.130000000000e-01 2.847477032061e+04 -8.190000000000e-01 2.324773395238e+04 -8.250000000000e-01 1.887830395501e+04 -8.310000000000e-01 1.526127910356e+04 -8.370000000000e-01 1.226542902853e+04 -8.430000000000e-01 9.764792661720e+03 -8.490000000000e-01 7.657028121727e+03 -8.550000000000e-01 5.869993524575e+03 -8.610000000000e-01 4.359564872105e+03 -8.670000000000e-01 3.102335965919e+03 -8.730000000000e-01 2.086540868269e+03 -8.790000000000e-01 1.303669926269e+03 -8.850000000000e-01 7.422004345400e+02 -8.910000000000e-01 3.839302915564e+02 -8.970000000000e-01 2.027522737366e+02 -9.030000000000e-01 1.653705147830e+02 -9.090000000000e-01 2.333753702193e+02 -9.150000000000e-01 3.661487659873e+02 -9.210000000000e-01 5.241643486942e+02 -9.270000000000e-01 6.723084634234e+02 -9.330000000000e-01 7.828627569469e+02 -9.390000000000e-01 8.377827322213e+02 -9.450000000000e-01 8.299249966261e+02 -9.510000000000e-01 7.629603889423e+02 -9.570000000000e-01 6.498766663589e+02 -9.630000000000e-01 5.102051019027e+02 -9.690000000000e-01 3.663525835953e+02 -9.750000000000e-01 2.396219649873e+02 -9.810000000000e-01 1.466005106524e+02 -9.870000000000e-01 9.655435128484e+01 -9.930000000000e-01 9.028543855367e+01 -9.990000000000e-01 1.206220271569e+02 -1.005000000000e+00 1.743869420735e+02 -1.011000000000e+00 2.353938083208e+02 -1.017000000000e+00 2.878265298207e+02 -1.023000000000e+00 3.193041905730e+02 -1.029000000000e+00 3.230309801777e+02 -1.035000000000e+00 2.986524924219e+02 -1.041000000000e+00 2.517320285265e+02 -1.047000000000e+00 1.920557560453e+02 -1.053000000000e+00 1.312086593532e+02 -1.059000000000e+00 7.998649722308e+01 -1.065000000000e+00 4.620213445470e+01 -1.071000000000e+00 3.331765520827e+01 -1.077000000000e+00 4.012274494702e+01 -1.083000000000e+00 6.143729151065e+01 -1.089000000000e+00 8.959759435274e+01 -1.095000000000e+00 1.163370697862e+02 -1.101000000000e+00 1.346208561086e+02 -1.107000000000e+00 1.400425525519e+02 -1.113000000000e+00 1.315212904312e+02 -1.119000000000e+00 1.112129290055e+02 -1.125000000000e+00 8.372786109627e+01 -1.131000000000e+00 5.489021548002e+01 -1.137000000000e+00 3.035121133693e+01 -1.143000000000e+00 1.437182554028e+01 -1.149000000000e+00 9.023237055111e+00 -1.155000000000e+00 1.393881106225e+01 -1.161000000000e+00 2.661838159232e+01 -1.167000000000e+00 4.316521163959e+01 -1.173000000000e+00 5.925344444584e+01 -1.179000000000e+00 7.109354278784e+01 -1.185000000000e+00 7.618667342628e+01 -1.191000000000e+00 7.372577879758e+01 -1.197000000000e+00 6.459224193958e+01 -1.203000000000e+00 5.099017784249e+01 -1.209000000000e+00 3.583487794922e+01 -1.215000000000e+00 2.205337210759e+01 -1.221000000000e+00 1.195775833795e+01 -1.227000000000e+00 6.819283272664e+00 -1.233000000000e+00 6.713948574170e+00 -1.239000000000e+00 1.064375721483e+01 -1.245000000000e+00 1.687719410310e+01 -1.251000000000e+00 2.341077694478e+01 -1.257000000000e+00 2.843768904314e+01 -1.263000000000e+00 3.072033525643e+01 -1.269000000000e+00 2.979593096971e+01 -1.275000000000e+00 2.598856773307e+01 -1.281000000000e+00 2.024656914900e+01 -1.287000000000e+00 1.386027651623e+01 -1.293000000000e+00 8.135672810081e+00 -1.299000000000e+00 4.100737246278e+00 -1.305000000000e+00 2.305819778018e+00 -1.311000000000e+00 2.751913587597e+00 -1.317000000000e+00 4.948794995786e+00 -1.323000000000e+00 8.076108995008e+00 -1.329000000000e+00 1.120064534602e+01 -1.335000000000e+00 1.349566848540e+01 -1.341000000000e+00 1.441351829629e+01 -1.347000000000e+00 1.377823514593e+01 -1.353000000000e+00 1.178616064457e+01 -1.359000000000e+00 8.924045541106e+00 -1.365000000000e+00 5.831364845832e+00 -1.371000000000e+00 3.142994402905e+00 -1.377000000000e+00 1.348895583756e+00 -1.383000000000e+00 6.998459880899e-01 -1.389000000000e+00 1.175093333321e+00 -1.395000000000e+00 2.512589765792e+00 -1.401000000000e+00 4.288748386655e+00 -1.407000000000e+00 6.025294940502e+00 -1.413000000000e+00 7.297338962210e+00 -1.419000000000e+00 7.819358337474e+00 -1.425000000000e+00 7.493143328432e+00 -1.431000000000e+00 6.411731286965e+00 -1.437000000000e+00 4.823494694988e+00 -1.443000000000e+00 3.068585528242e+00 -1.449000000000e+00 1.504367250740e+00 -1.455000000000e+00 4.367336631615e-01 -1.461000000000e+00 7.075769309964e-02 -1.467000000000e+00 4.881458854136e-01 -1.473000000000e+00 1.652127168882e+00 -1.479000000000e+00 3.434315408612e+00 -1.485000000000e+00 5.654030938598e+00 -1.491000000000e+00 8.119215368506e+00 -1.497000000000e+00 1.065940397251e+01 -1.503000000000e+00 1.314459866367e+01 -1.509000000000e+00 1.548828027174e+01 -1.515000000000e+00 1.763705888455e+01 -1.521000000000e+00 1.955258839831e+01 -1.527000000000e+00 2.119273783619e+01 -1.533000000000e+00 2.249846541021e+01 -1.539000000000e+00 2.339069454111e+01 -1.545000000000e+00 2.377840550018e+01 -1.551000000000e+00 2.357595747516e+01 -1.557000000000e+00 2.272512813000e+01 -1.563000000000e+00 2.121606764169e+01 -1.569000000000e+00 1.910154801334e+01 -1.575000000000e+00 1.650042453406e+01 -1.581000000000e+00 1.358869008565e+01 -1.587000000000e+00 1.057928589037e+01 -1.593000000000e+00 7.694291412396e+00 -1.599000000000e+00 5.134720118508e+00 -1.605000000000e+00 3.053586303063e+00 -1.611000000000e+00 1.537144007736e+00 -1.617000000000e+00 5.974567748544e-01 -1.623000000000e+00 1.771553923452e-01 -1.629000000000e+00 1.648890760558e-01 -1.635000000000e+00 4.180581609915e-01 -1.641000000000e+00 7.882927318396e-01 -1.647000000000e+00 1.144980471082e+00 -1.653000000000e+00 1.392906645043e+00 -1.659000000000e+00 1.481523555665e+00 -1.665000000000e+00 1.405168023092e+00 -1.671000000000e+00 1.195305998186e+00 -1.677000000000e+00 9.072591835504e-01 -1.683000000000e+00 6.046253871346e-01 -1.689000000000e+00 3.446553506005e-01 -1.695000000000e+00 1.672577795520e-01 -1.701000000000e+00 8.925776869819e-02 -1.707000000000e+00 1.042905171126e-01 -1.713000000000e+00 1.875429506827e-01 -1.719000000000e+00 3.036869169436e-01 -1.725000000000e+00 4.159193631440e-01 -1.731000000000e+00 4.940724007352e-01 -1.737000000000e+00 5.202134935792e-01 -1.743000000000e+00 4.908810247850e-01 -1.749000000000e+00 4.159125148752e-01 -1.755000000000e+00 3.145440937279e-01 -1.761000000000e+00 2.099520805494e-01 -1.767000000000e+00 1.235957163762e-01 -1.773000000000e+00 7.060092165109e-02 -1.779000000000e+00 5.705928145405e-02 -1.785000000000e+00 7.960933542981e-02 -1.791000000000e+00 1.271410070963e-01 -1.797000000000e+00 1.840308640625e-01 -1.803000000000e+00 2.340557749013e-01 -1.809000000000e+00 2.640801250317e-01 -1.815000000000e+00 2.667545434913e-01 -1.821000000000e+00 2.417503574088e-01 -1.827000000000e+00 1.954081002475e-01 -1.833000000000e+00 1.390192959347e-01 -1.839000000000e+00 8.621940662359e-02 -1.845000000000e+00 5.010221903224e-02 -1.851000000000e+00 4.065919139901e-02 -1.857000000000e+00 6.301872034333e-02 -1.863000000000e+00 1.167502789937e-01 -1.869000000000e+00 1.962592343935e-01 -1.875000000000e+00 2.920818843664e-01 -1.881000000000e+00 3.927378676425e-01 -1.887000000000e+00 4.867314815774e-01 -1.893000000000e+00 5.643168721279e-01 -1.899000000000e+00 6.187383305107e-01 -1.905000000000e+00 6.467970298948e-01 -1.911000000000e+00 6.487452910920e-01 -1.917000000000e+00 6.276372925710e-01 -1.923000000000e+00 5.883482497423e-01 -1.929000000000e+00 5.365020642846e-01 -1.935000000000e+00 4.775227431748e-01 -1.941000000000e+00 4.159605859620e-01 -1.947000000000e+00 3.551597194136e-01 -1.953000000000e+00 2.972499039936e-01 -1.959000000000e+00 2.433803088561e-01 -1.965000000000e+00 1.940772489846e-01 -1.971000000000e+00 1.496047749216e-01 -1.977000000000e+00 1.102320012183e-01 -1.983000000000e+00 7.635410907742e-02 -1.989000000000e+00 4.846244473319e-02 -1.995000000000e+00 2.700100658818e-02 -2.001000000000e+00 1.217298913640e-02 -2.007000000000e+00 3.767789515923e-03 -2.013000000000e+00 1.066900266715e-03 -2.019000000000e+00 2.861541201053e-03 -2.025000000000e+00 7.583390615651e-03 -2.031000000000e+00 1.352052059377e-02 -2.037000000000e+00 1.907036569855e-02 -2.043000000000e+00 2.297421495520e-02 -2.049000000000e+00 2.448389283579e-02 -2.055000000000e+00 2.342841857659e-02 -2.061000000000e+00 2.017169793699e-02 -2.067000000000e+00 1.547596846420e-02 -2.073000000000e+00 1.030449311105e-02 -2.079000000000e+00 5.607155649231e-03 -2.085000000000e+00 2.132674238372e-03 -2.091000000000e+00 3.019801976602e-04 -2.097000000000e+00 1.616956758697e-04 -2.103000000000e+00 1.418502114524e-03 -2.109000000000e+00 3.538603775072e-03 -2.115000000000e+00 5.884809394932e-03 -2.121000000000e+00 7.858955177213e-03 -2.127000000000e+00 9.019788418139e-03 -2.133000000000e+00 9.154780831002e-03 -2.139000000000e+00 8.296271121975e-03 -2.145000000000e+00 6.684967256126e-03 -2.151000000000e+00 4.694447763655e-03 -2.157000000000e+00 2.736884282411e-03 -2.163000000000e+00 1.171826084409e-03 -2.169000000000e+00 2.367517059893e-04 -2.175000000000e+00 1.139193930034e-05 -2.181000000000e+00 4.193704292770e-04 -2.187000000000e+00 1.262469754599e-03 -2.193000000000e+00 2.276520648688e-03 -2.199000000000e+00 3.194639249207e-03 -2.205000000000e+00 3.803644880361e-03 -2.211000000000e+00 3.982569533556e-03 -2.217000000000e+00 3.717230102832e-03 -2.223000000000e+00 3.090580630306e-03 -2.229000000000e+00 2.253702785106e-03 -2.235000000000e+00 1.385813290848e-03 -2.241000000000e+00 6.530109152494e-04 -2.247000000000e+00 1.746209440219e-04 -2.253000000000e+00 3.360201461992e-06 -2.259000000000e+00 1.219025129350e-04 -2.265000000000e+00 4.546597563975e-04 -2.271000000000e+00 8.905168869420e-04 -2.277000000000e+00 1.310440675264e-03 -2.283000000000e+00 1.613559299604e-03 -2.289000000000e+00 1.736377377024e-03 -2.295000000000e+00 1.661861202881e-03 -2.301000000000e+00 1.417647692374e-03 -2.307000000000e+00 1.065013809496e-03 -2.313000000000e+00 6.820036477390e-04 -2.319000000000e+00 3.449491152318e-04 -2.325000000000e+00 1.124680809258e-04 -2.331000000000e+00 1.502862694771e-05 -2.337000000000e+00 5.163817603197e-05 -2.343000000000e+00 1.935364030187e-04 -2.349000000000e+00 3.933122344677e-04 -2.355000000000e+00 5.969086593920e-04 -2.361000000000e+00 7.556666785597e-04 -2.367000000000e+00 8.358813484445e-04 -2.373000000000e+00 8.241564588184e-04 -2.379000000000e+00 7.279213172140e-04 -2.385000000000e+00 5.715568681989e-04 -2.391000000000e+00 3.894414309671e-04 -2.397000000000e+00 2.177146125702e-04 -2.403000000000e+00 8.661417390671e-05 -2.409000000000e+00 1.490463702359e-05 -2.415000000000e+00 7.305118674737e-06 -2.421000000000e+00 5.509736807330e-05 -2.427000000000e+00 1.394179186380e-04 -2.433000000000e+00 2.362449192157e-04 -2.439000000000e+00 3.218602609299e-04 -2.445000000000e+00 3.776163265800e-04 -2.451000000000e+00 3.931197326304e-04 -2.457000000000e+00 3.673745776948e-04 -2.463000000000e+00 3.078982849778e-04 -2.469000000000e+00 2.282326015952e-04 -2.475000000000e+00 1.445446334305e-04 -2.481000000000e+00 7.210981154150e-05 -2.487000000000e+00 2.239315194273e-05 -2.493000000000e+00 1.234784775662e-06 -2.499000000000e+00 8.360817698301e-06 -2.505000000000e+00 3.814866998514e-05 -2.511000000000e+00 8.133695070642e-05 -2.517000000000e+00 1.272247553183e-04 -2.523000000000e+00 1.658702421136e-04 -2.529000000000e+00 1.898652203823e-04 -2.535000000000e+00 1.954035135407e-04 -2.541000000000e+00 1.825372769054e-04 -2.547000000000e+00 1.546869986615e-04 -2.553000000000e+00 1.176042241351e-04 -2.559000000000e+00 7.806046552757e-05 -2.565000000000e+00 4.254562597362e-05 -2.571000000000e+00 1.621275729407e-05 -2.577000000000e+00 2.221293842023e-06 -2.583000000000e+00 1.530988680077e-06 -2.589000000000e+00 1.310583838258e-05 -2.595000000000e+00 3.441838166785e-05 -2.601000000000e+00 6.210920351821e-05 -2.607000000000e+00 9.265522251350e-05 -2.613000000000e+00 1.229272527303e-04 -2.619000000000e+00 1.505617467419e-04 -2.625000000000e+00 1.741213350763e-04 -2.631000000000e+00 1.930629125915e-04 -2.637000000000e+00 2.075630268629e-04 -2.643000000000e+00 2.182649059085e-04 -2.649000000000e+00 2.260104039522e-04 -2.655000000000e+00 2.316073924701e-04 -2.661000000000e+00 2.356639870542e-04 -2.667000000000e+00 2.385010852846e-04 -2.673000000000e+00 2.401382146212e-04 -2.679000000000e+00 2.403369651742e-04 -2.685000000000e+00 2.386818996529e-04 -2.691000000000e+00 2.346794013261e-04 -2.697000000000e+00 2.278586272243e-04 -2.703000000000e+00 2.178632824795e-04 -2.709000000000e+00 2.045268203015e-04 -2.715000000000e+00 1.879261321525e-04 -2.721000000000e+00 1.684099247637e-04 -2.727000000000e+00 1.465986207851e-04 -2.733000000000e+00 1.233535764236e-04 -2.739000000000e+00 9.971558307121e-05 -2.745000000000e+00 7.681606241377e-05 -2.751000000000e+00 5.576874730310e-05 -2.757000000000e+00 3.755398689848e-05 -2.763000000000e+00 2.291091753997e-05 -2.769000000000e+00 1.225356221786e-05 -2.775000000000e+00 5.624805801831e-06 -2.781000000000e+00 2.697190509113e-06 -2.787000000000e+00 2.822330861223e-06 -2.793000000000e+00 5.122752451708e-06 -2.799000000000e+00 8.612693312614e-06 -2.805000000000e+00 1.232935355556e-05 -2.811000000000e+00 1.545429531663e-05 -2.817000000000e+00 1.740657260306e-05 -2.823000000000e+00 1.789434993200e-05 -2.829000000000e+00 1.691921423289e-05 -2.835000000000e+00 1.473563710489e-05 -2.841000000000e+00 1.177550866037e-05 -2.847000000000e+00 8.552970414223e-06 -2.853000000000e+00 5.567031106867e-06 -2.859000000000e+00 3.218409668336e-06 -2.865000000000e+00 1.753127178635e-06 -2.871000000000e+00 1.239507355051e-06 -2.877000000000e+00 1.578699030273e-06 -2.883000000000e+00 2.542891762494e-06 -2.889000000000e+00 3.831120143862e-06 -2.895000000000e+00 5.130588382763e-06 -2.901000000000e+00 6.171927026062e-06 -2.907000000000e+00 6.769363089567e-06 -2.913000000000e+00 6.840716708380e-06 -2.919000000000e+00 6.406518398978e-06 -2.925000000000e+00 5.571473971575e-06 -2.931000000000e+00 4.494286077422e-06 -2.937000000000e+00 3.353085009636e-06 -2.943000000000e+00 2.313394233683e-06 -2.949000000000e+00 1.503945833406e-06 -2.955000000000e+00 1.003273351698e-06 -2.961000000000e+00 8.374415121770e-07 -2.967000000000e+00 9.870688966875e-07 -2.973000000000e+00 1.400353291584e-06 -2.979000000000e+00 2.008295327407e-06 -2.985000000000e+00 2.738684393483e-06 -2.991000000000e+00 3.526432769323e-06 -2.997000000000e+00 4.319182015173e-06 diff --git a/Tests/Unit/gui2/data/bilayer3a.txt b/Tests/Unit/gui2/data/bilayer3a.txt deleted file mode 100644 index ef62fc7c6213c15ca322e232baa1d2f516ae924f..0000000000000000000000000000000000000000 --- a/Tests/Unit/gui2/data/bilayer3a.txt +++ /dev/null @@ -1,501 +0,0 @@ -# data from TimeOfFlightReflectometry.py -0, 0.01, 0.9999999999999998 -1, 0.011983967935871743, 1.0 -2, 0.013967935871743487, 1.0000000000000004 -3, 0.01595190380761523, 1.0000000000000002 -4, 0.017935871743486972, 0.9999999999999999 -5, 0.019919839679358717, 1.0 -6, 0.02190380761523046, 1.0000000000000004 -7, 0.023887775551102206, 1.0000000000000002 -8, 0.02587174348697395, 1.0000000000000004 -9, 0.027855711422845694, 1.0 -10, 0.02983967935871744, 1.0 -11, 0.031823647294589176, 1.0000000000000002 -12, 0.03380761523046092, 1.0000000000000004 -13, 0.035791583166332665, 0.9999999999999996 -14, 0.03777555110220441, 0.9999999999999998 -15, 0.03975951903807615, 0.9999999999999998 -16, 0.0417434869739479, 1.0 -17, 0.04372745490981964, 1.0 -18, 0.045711422845691387, 1.0 -19, 0.04769539078156313, 1.0 -20, 0.049679358717434875, 1.0 -21, 0.05166332665330661, 1.0 -22, 0.05364729458917836, 1.0000000000000002 -23, 0.0556312625250501, 1.0000000000000007 -24, 0.057615230460921846, 0.9999999999999998 -25, 0.05959919839679359, 1.0 -26, 0.061583166332665334, 0.9999999999999998 -27, 0.06356713426853708, 0.9999999999999996 -28, 0.06555110220440881, 0.9999999999999998 -29, 0.06753507014028055, 1.0 -30, 0.0695190380761523, 0.9999999999999999 -31, 0.07150300601202404, 0.9999999999999996 -32, 0.07348697394789579, 0.9999999999999997 -33, 0.07547094188376753, 0.9999999999999997 -34, 0.07745490981963928, 0.9999999999999996 -35, 0.07943887775551102, 0.9999999999999996 -36, 0.08142284569138276, 0.9999999999999998 -37, 0.08340681362725451, 1.0000000000000004 -38, 0.08539078156312625, 0.9999999999999993 -39, 0.087374749498998, 0.9999999999999996 -40, 0.08935871743486974, 1.0000000000000004 -41, 0.09134268537074147, 1.0000000000000004 -42, 0.09332665330661322, 1.0000000000000009 -43, 0.09531062124248496, 0.9999999999999998 -44, 0.0972945891783567, 0.9999999999999999 -45, 0.09927855711422845, 0.9999999999999993 -46, 0.1012625250501002, 1.0000000000000002 -47, 0.10324649298597194, 0.9999992528061048 -48, 0.10523046092184368, 0.9999985974506073 -49, 0.10721442885771543, 0.999997921309658 -50, 0.10919839679358717, 0.9999971427452203 -51, 0.11118236472945892, 0.9999962122090085 -52, 0.11316633266533066, 0.9999950799230959 -53, 0.1151503006012024, 0.9999936875180906 -54, 0.11713426853707415, 0.9999919626983287 -55, 0.1191182364729459, 0.9999898137850864 -56, 0.12110220440881762, 0.9999871230233972 -57, 0.12308617234468937, 0.9999837378321051 -58, 0.12507014028056113, 0.9999794590650891 -59, 0.12705410821643287, 0.9999740250410741 -60, 0.12903807615230461, 0.9999670895946517 -61, 0.13102204408817636, 0.999958191635177 -62, 0.1330060120240481, 0.999946712547489 -63, 0.13498997995991985, 0.9999318160224282 -64, 0.1369739478957916, 0.9999123622332293 -65, 0.13895791583166334, 0.9998867841333866 -66, 0.14094188376753508, 0.999852907147281 -67, 0.14292585170340683, 0.9998076831535236 -68, 0.14490981963927857, 0.9997467928547588 -69, 0.14689378757515031, 0.99966404291278 -70, 0.14887775551102206, 0.9995504376444865 -71, 0.1508617234468938, 0.9993927251319745 -72, 0.15284569138276555, 0.999171077251899 -73, 0.1548296593186373, 0.9988553104956281 -74, 0.15681362725450904, 0.9983985870085685 -75, 0.15879759519038078, 0.9977266436988359 -76, 0.16078156312625252, 0.9967188386688286 -77, 0.16276553106212427, 0.9951737046113363 -78, 0.164749498997996, 0.9927440254766213 -79, 0.16673346693386776, 0.9888093621532706 -80, 0.1687174348697395, 0.9822141139510879 -81, 0.17070140280561122, 0.9707022984498375 -82, 0.17268537074148296, 0.9496383601680007 -83, 0.1746693386773547, 0.909021525956259 -84, 0.17665330661322645, 0.8268006578284636 -85, 0.1786372745490982, 0.6588522111821937 -86, 0.18062124248496994, 0.3622399614191024 -87, 0.18260521042084168, 0.06420150811805793 -88, 0.18458917835671343, 0.024633662977522494 -89, 0.18657314629258517, 0.15244093776327813 -90, 0.18855711422845692, 0.27529995099868965 -91, 0.19054108216432866, 0.3526612082641258 -92, 0.1925250501002004, 0.39063545710665876 -93, 0.19450901803607215, 0.3990333790987325 -94, 0.1964929859719439, 0.3845452071189573 -95, 0.19847695390781564, 0.35144925997264576 -96, 0.20046092184368738, 0.3031439950053475 -97, 0.20244488977955913, 0.24353655832687798 -98, 0.20442885771543087, 0.17808572440435927 -99, 0.20641282565130262, 0.11410584881256816 -100, 0.20839679358717436, 0.059830552998912524 -101, 0.2103807615230461, 0.022250824859572964 -102, 0.21236472945891785, 0.004789833661897041 -103, 0.2143486973947896, 0.006356984649312908 -104, 0.21633266533066134, 0.022365632593830034 -105, 0.21831663326653308, 0.04682241052607952 -106, 0.22030060120240483, 0.07416136769212864 -107, 0.22228456913827657, 0.1001720615138792 -108, 0.22426853707414832, 0.12213465250467488 -109, 0.22625250501002006, 0.13855308036162264 -110, 0.2282364729458918, 0.1487974036569265 -111, 0.23022044088176355, 0.15280542074664977 -112, 0.23220440881763527, 0.15088251751204407 -113, 0.234188376753507, 0.14358811351822667 -114, 0.23617234468937875, 0.13168199675274497 -115, 0.2381563126252505, 0.11610304292527356 -116, 0.24014028056112224, 0.09795584761494282 -117, 0.242124248496994, 0.07848468865313928 -118, 0.24410821643286573, 0.05901971090221587 -119, 0.24609218436873748, 0.04088892407033809 -120, 0.24807615230460922, 0.02530184438722244 -121, 0.25006012024048097, 0.013223849390327617 -122, 0.2520440881763527, 0.0052693211843496445 -123, 0.25402805611222445, 0.0016411405846048022 -124, 0.2560120240480962, 0.002132606619548132 -125, 0.25799599198396794, 0.006189794194701373 -126, 0.2599799599198397, 0.013015844928207822 -127, 0.26196392785571143, 0.021690550068973954 -128, 0.2639478957915832, 0.03128056624196508 -129, 0.2659318637274549, 0.04092443009513365 -130, 0.26791583166332666, 0.049887002117678506 -131, 0.2698997995991984, 0.05758607973651505 -132, 0.27188376753507015, 0.06359816326314606 -133, 0.2738677354709419, 0.06765120572513812 -134, 0.27585170340681364, 0.06961093772604753 -135, 0.2778356713426854, 0.0694652862160818 -136, 0.27981963927855713, 0.06730932686430591 -137, 0.2818036072144289, 0.06333151898991729 -138, 0.2837875751503006, 0.05780078596127256 -139, 0.28577154308617236, 0.051053313090844835 -140, 0.2877555110220441, 0.04347770115747981 -141, 0.28973947895791585, 0.035497304971156975 -142, 0.2917234468937876, 0.027549165730337055 -143, 0.29370741482965934, 0.02005983448493074 -144, 0.2956913827655311, 0.013419426316096529 -145, 0.29767535070140283, 0.007956202507095663 -146, 0.2996593186372746, 0.0039145718050655805 -147, 0.3016432865731463, 0.0014393995905691696 -148, 0.30362725450901806, 0.0005688307236762597 -149, 0.3056112224448898, 0.0012365918074232387 -150, 0.30759519038076155, 0.0032832519146904853 -151, 0.3095791583166333, 0.006474578249753218 -152, 0.31156312625250504, 0.010524253267492914 -153, 0.3135470941883768, 0.01511797850115291 -154, 0.31553106212424853, 0.01993633203535728 -155, 0.3175150300601203, 0.024674476171810362 -156, 0.319498997995992, 0.02905767996968943 -157, 0.32148296593186376, 0.03285241227312436 -158, 0.3234669338677355, 0.03587334202207215 -159, 0.32545090180360725, 0.03798691116784891 -160, 0.327434869739479, 0.03911224589336394 -161, 0.3294188376753507, 0.039220104446289754 -162, 0.33140280561122243, 0.03833039410542655 -163, 0.3333867735470942, 0.036508587609869456 -164, 0.3353707414829659, 0.0338611788968911 -165, 0.33735470941883766, 0.03053017320088866 -166, 0.3393386773547094, 0.02668652941152426 -167, 0.34132264529058115, 0.02252247460745127 -168, 0.3433066132264529, 0.01824269289141468 -169, 0.34529058116232464, 0.01405454201275371 -170, 0.3472745490981964, 0.010157647151281007 -171, 0.34925851703406813, 0.006733424032981525 -172, 0.35124248496993987, 0.003935247174387443 -173, 0.3532264529058116, 0.0018800579891315712 -174, 0.35521042084168336, 0.0006421686942934479 -175, 0.3571943887775551, 0.0002498520126686543 -176, 0.35917835671342685, 0.0006850336571871474 -177, 0.3611623246492986, 0.0018860713465820211 -178, 0.36314629258517034, 0.0037532727931319895 -179, 0.3651302605210421, 0.006156536579232831 -180, 0.3671142284569138, 0.008944337730497173 -181, 0.36909819639278557, 0.011953240771592386 -182, 0.3710821643286573, 0.015017195992625963 -183, 0.37306613226452906, 0.017976027723366806 -184, 0.3750501002004008, 0.020682715399392357 -185, 0.37703406813627255, 0.02300925974043486 -186, 0.3790180360721443, 0.024851087812409446 -187, 0.38100200400801604, 0.026130065575115363 -188, 0.3829859719438878, 0.026796250719654913 -189, 0.3849699398797595, 0.02682853773180647 -190, 0.38695390781563127, 0.026234332576648815 -191, 0.388937875751503, 0.025048360075339858 -192, 0.39092184368737476, 0.02333066686964983 -193, 0.3929058116232465, 0.021163849255882144 -194, 0.39488977955911825, 0.018649518038920673 -195, 0.39687374749499, 0.015904018618641446 -196, 0.39885771543086174, 0.013053456576381392 -197, 0.4008416833667335, 0.01022813530149914 -198, 0.4028256513026052, 0.007556585914512282 -199, 0.40480961923847697, 0.005159449356900526 -200, 0.4067935871743487, 0.003143540947434207 -201, 0.40877755511022046, 0.001596472756954287 -202, 0.4107615230460922, 0.0005822148779162445 -203, 0.41274549098196395, 0.0001379349307479975 -204, 0.4147294589178357, 0.0002723663906171204 -205, 0.41671342685370744, 0.0009658304295724124 -206, 0.4186973947895792, 0.0021718907815956433 -207, 0.4206813627254509, 0.0038204786964381836 -208, 0.42266533066132267, 0.005822206686778807 -209, 0.4246492985971944, 0.00807351144553656 -210, 0.42663326653306616, 0.010462235517300439 -211, 0.4286172344689379, 0.012873272374476484 -212, 0.43060120240480965, 0.015193951170327341 -213, 0.4325851703406814, 0.017318911741101627 -214, 0.43456913827655314, 0.019154302457323406 -215, 0.4365531062124249, 0.02062121023427756 -216, 0.4385370741482966, 0.021658294151797174 -217, 0.44052104208416837, 0.022223636927716544 -218, 0.4425050100200401, 0.022295851343178564 -219, 0.44448897795591186, 0.021874484335386073 -220, 0.4464729458917836, 0.02097975476338624 -221, 0.44845691382765535, 0.019651647884218724 -222, 0.4504408817635271, 0.017948376696229146 -223, 0.45242484969939883, 0.015944213409551735 -224, 0.4544088176352705, 0.013726698199906193 -225, 0.45639278557114227, 0.011393250203976028 -226, 0.458376753507014, 0.00904723825169567 -227, 0.46036072144288576, 0.0067936141627217735 -228, 0.4623446893787575, 0.004734264635469744 -229, 0.46432865731462925, 0.002963291172441509 -230, 0.466312625250501, 0.001562471623510888 -231, 0.46829659318637273, 0.0005971820099725045 -232, 0.4702805611222445, 0.00011305525542118876 -233, 0.4722645290581162, 0.00013361998494645114 -234, 0.47424849699398797, 0.0006590985922606173 -235, 0.4762324649298597, 0.0016664559033823143 -236, 0.47821643286573146, 0.0031106893010797083 -237, 0.4802004008016032, 0.004927252009008278 -238, 0.48218436873747494, 0.007035416996440179 -239, 0.4841683366733467, 0.00934233025415317 -240, 0.48615230460921843, 0.011747474637648414 -241, 0.4881362725450902, 0.014147269061668665 -242, 0.4901202404809619, 0.016439557549772294 -243, 0.49210420841683367, 0.018527790107948538 -244, 0.4940881763527054, 0.020324752880853687 -245, 0.49607214428857715, 0.021755759417808256 -246, 0.4980561122244489, 0.022761260944526455 -247, 0.5000400801603206, 0.023298866813712966 -248, 0.5020240480961924, 0.023344785094500477 -249, 0.5040080160320641, 0.022894698329123202 -250, 0.5059919839679359, 0.0219640835395822 -251, 0.5079759519038076, 0.02058797266194096 -252, 0.5099599198396794, 0.01882013459000496 -253, 0.5119438877755511, 0.016731648124927643 -254, 0.5139278557114229, 0.014408831409332683 -255, 0.5159118236472946, 0.011950502241680821 -256, 0.5178957915831663, 0.009464568041977305 -257, 0.5198797595190381, 0.007063985106731697 -258, 0.5218637274549098, 0.004862182277144541 -259, 0.5238476953907816, 0.0029681091037364084 -260, 0.5258316633266533, 0.0014811346546237739 -261, 0.5278156312625251, 0.000486079503704131 -262, 0.5297995991983968, 4.869861470054776e-05 -263, 0.5317835671342686, 0.00021193684162505277 -264, 0.5337675350701403, 0.0009932457099753257 -265, 0.535751503006012, 0.0023831802222176583 -266, 0.5377354709418838, 0.004345394715813398 -267, 0.5397194388777555, 0.0068180403841822815 -268, 0.5417034068136273, 0.009716450625062706 -269, 0.543687374749499, 0.012936900724504447 -270, 0.5456713426853708, 0.01636115898480383 -271, 0.5476553106212425, 0.019861514793368784 -272, 0.5496392785571143, 0.023305975875961987 -273, 0.551623246492986, 0.026563366329670324 -274, 0.5536072144288577, 0.029508118832884456 -275, 0.5555911823647295, 0.03202462662109848 -276, 0.5575751503006012, 0.03401109178813516 -277, 0.559559118236473, 0.0353828667589039 -278, 0.5615430861723447, 0.03607532889791913 -279, 0.5635270541082165, 0.03604635071583357 -280, 0.5655110220440882, 0.03527842913439466 -281, 0.56749498997996, 0.033780517814299825 -282, 0.5694789579158317, 0.03158956906567713 -283, 0.5714629258517034, 0.02877173989735132 -284, 0.5734468937875752, 0.025423155100636436 -285, 0.5754308617234469, 0.021670055336900616 -286, 0.5774148296593187, 0.017668098632004647 -287, 0.5793987975951904, 0.01360054066770616 -288, 0.5813827655310622, 0.009675006335630927 -289, 0.5833667334669339, 0.006118596777585109 -290, 0.5853507014028057, 0.0031711655175897836 -291, 0.5873346693386774, 0.0010767514123354313 -292, 0.5893186372745491, 7.337126248933872e-05 -293, 0.5913026052104209, 0.00038163193943142594 -294, 0.5932865731462926, 0.0021928845162606674 -295, 0.5952705410821644, 0.0056578607646843365 -296, 0.5972545090180361, 0.010876850180429382 -297, 0.5992384769539079, 0.017892447510133306 -298, 0.6012224448897796, 0.02668570573220913 -299, 0.6032064128256514, 0.037176183119206514 -300, 0.6051903807615231, 0.04922592865951015 -301, 0.6071743486973948, 0.06264698790058769 -302, 0.6091583166332666, 0.07721161770418648 -303, 0.6111422845691383, 0.09266414313905552 -304, 0.6131262525050101, 0.10873330807907763 -305, 0.6151102204408818, 0.1251440579875237 -306, 0.6170941883767536, 0.14162790993709415 -307, 0.6190781563126253, 0.15793135330400035 -308, 0.621062124248497, 0.17382202514428602 -309, 0.6230460921843688, 0.18909266915069564 -310, 0.6250300601202405, 0.2035630872277019 -311, 0.6270140280561123, 0.21708041825847607 -312, 0.628997995991984, 0.22951813481130462 -313, 0.6309819639278558, 0.24077414965038677 -314, 0.6329659318637275, 0.2507683876073812 -315, 0.6349498997995993, 0.2594401213643935 -316, 0.636933867735471, 0.2667453054381796 -317, 0.6389178356713427, 0.27265408047685313 -318, 0.6409018036072145, 0.2771485653514613 -319, 0.6428857715430862, 0.28022100981180365 -320, 0.644869739478958, 0.2818723458635943 -321, 0.6468537074148296, 0.28211115035364215 -322, 0.6488376753507014, 0.28095301267295864 -323, 0.6508216432865731, 0.27842028792463336 -324, 0.6528056112224448, 0.2745422053320233 -325, 0.6547895791583166, 0.26935529229416066 -326, 0.6567735470941883, 0.26290406487717055 -327, 0.6587575150300601, 0.2552419246275385 -328, 0.6607414829659318, 0.2464321888632971 -329, 0.6627254509018036, 0.2365491670864776 -330, 0.6647094188376753, 0.22567918059298267 -331, 0.6666933867735471, 0.21392140723490657 -332, 0.6686773547094188, 0.2013884209214198 -333, 0.6706613226452905, 0.18820628886495724 -334, 0.6726452905811623, 0.17451409231440515 -335, 0.674629258517034, 0.1604627521165676 -336, 0.6766132264529058, 0.1462130717958097 -337, 0.6785971943887775, 0.13193295929218454 -338, 0.6805811623246493, 0.11779385297798245 -339, 0.682565130260521, 0.10396645389418357 -340, 0.6845490981963928, 0.09061594680987843 -341, 0.6865330661322645, 0.07789696743553526 -342, 0.6885170340681362, 0.06594863026369184 -343, 0.690501002004008, 0.054889960155995815 -344, 0.6924849699398797, 0.0448160631944758 -345, 0.6944689378757515, 0.03579532599062774 -346, 0.6964529058116232, 0.027867851529310705 -347, 0.698436873747495, 0.02104523376601873 -348, 0.7004208416833667, 0.015311657001329292 -349, 0.7024048096192385, 0.01062619545703843 -350, 0.7043887775551102, 0.006926097790945572 -351, 0.706372745490982, 0.004130780592705779 -352, 0.7083567134268537, 0.0021462285840382345 -353, 0.7103406813627254, 0.0008695059176485245 -354, 0.7123246492985972, 0.000193116620165803 -355, 0.7143086172344689, 9.004092252511728e-06 -356, 0.7162925851703407, 0.0002120401728068695 -357, 0.7182765531062124, 0.000702915069422189 -358, 0.7202605210420842, 0.0013903939835314 -359, 0.7222444889779559, 0.0021929505257092573 -360, 0.7242284569138276, 0.003039819393007217 -361, 0.7262124248496994, 0.003871531521672373 -362, 0.7281963927855711, 0.0046400055593236855 -363, 0.7301803607214429, 0.0053082722075593804 -364, 0.7321643286573146, 0.00584990512316418 -365, 0.7341482965931864, 0.006248225808298112 -366, 0.7361322645290581, 0.006495342061634846 -367, 0.7381162324649299, 0.006591071435228216 -368, 0.7401002004008016, 0.006541793617286351 -369, 0.7420841683366733, 0.006359269203542507 -370, 0.7440681362725451, 0.006059457066852846 -371, 0.7460521042084168, 0.00566135838422228 -372, 0.7480360721442886, 0.005185912077448136 -373, 0.7500200400801603, 0.0046549636367218305 -374, 0.7520040080160321, 0.004090326684460166 -375, 0.7539879759519038, 0.003512953900481543 -376, 0.7559719438877756, 0.0029422308513142605 -377, 0.7579559118236473, 0.0023954027315925422 -378, 0.759939879759519, 0.0018871400311782185 -379, 0.7619238476953908, 0.0014292447890569052 -380, 0.7639078156312625, 0.0010304945698099762 -381, 0.7658917835671343, 0.0006966168414242411 -382, 0.767875751503006, 0.00043038230631217646 -383, 0.7698597194388778, 0.00023180218940765428 -384, 0.7718436873747495, 9.84117236624081e-05 -385, 0.7738276553106213, 2.5620234778188087e-05 -386, 0.775811623246493, 7.107377406914545e-06 -387, 0.7777955911823647, 3.52452002712822e-05 -388, 0.7797795591182365, 0.00010152673394992479 -389, 0.7817635270541082, 0.00019698356418977264 -390, 0.78374749498998, 0.0003125772019421228 -391, 0.7857314629258517, 0.0004395517998419576 -392, 0.7877154308617235, 0.0005697387072413838 -393, 0.7896993987975952, 0.0006958063329571489 -394, 0.791683366733467, 0.0008114516542151142 -395, 0.7936673346693387, 0.0009115323612152717 -396, 0.7956513026052104, 0.0009921409810344773 -397, 0.7976352705410822, 0.0010506243337552023 -398, 0.7996192384769539, 0.001085553314410324 -399, 0.8016032064128257, 0.0010966492627619995 -400, 0.8035871743486974, 0.0010846740892822139 -401, 0.8055711422845692, 0.0010512918893824008 -402, 0.8075551102204409, 0.0009989100239061956 -403, 0.8095390781563127, 0.0009305076002728938 -404, 0.8115230460921844, 0.0008494589854774166 -405, 0.8135070140280561, 0.00075935945102763 -406, 0.8154909819639279, 0.0006638593242132494 -407, 0.8174749498997996, 0.0005665121353902215 -408, 0.8194589178356714, 0.0004706412451662618 -409, 0.8214428857715431, 0.00037922834870297243 -410, 0.8234268537074149, 0.0002948261286759213 -411, 0.8254108216432866, 0.00021949620614409963 -412, 0.8273947895791584, 0.00015477246102135799 -413, 0.8293787575150301, 0.0001016487995011666 -414, 0.8313627254509018, 6.058956842976623e-05 -415, 0.8333466933867736, 3.156008360717915e-05 -416, 0.8353306613226453, 1.4074169956026223e-05 -417, 0.8373146292585171, 7.255217543491329e-06 -418, 0.8392985971943888, 9.90704095152882e-06 -419, 0.8412825651302606, 2.0590784494257463e-05 -420, 0.8432665330661323, 3.770422887497309e-05 -421, 0.845250501002004, 5.956010654522103e-05 -422, 0.8472344689378758, 8.446039924674957e-05 -423, 0.8492184368737475, 0.00011076404514623134 -424, 0.8512024048096193, 0.000136945996638117 -425, 0.853186372745491, 0.00016164611570323428 -426, 0.8551703406813628, 0.00018370694574904647 -427, 0.8571543086172345, 0.00020219993387200045 -428, 0.8591382765531063, 0.00021644017559656643 -429, 0.861122244488978, 0.00022599019928002835 -430, 0.8631062124248498, 0.00023065368741721326 -431, 0.8650901803607215, 0.0002304603388671356 -432, 0.8670741482965932, 0.00022564330514447347 -433, 0.869058116232465, 0.00021661078442208924 -434, 0.8710420841683367, 0.00020391343091570734 -435, 0.8730260521042085, 0.00018820923967411692 -436, 0.8750100200400802, 0.00017022750450188212 -437, 0.876993987975952, 0.00015073332857219645 -438, 0.8789779559118237, 0.00013049400330005412 -439, 0.8809619238476954, 0.000110248372099437 -440, 0.8829458917835672, 9.068007294074733e-05 -441, 0.8849298597194389, 7.239531824426369e-05 -442, 0.8869138276553107, 5.590563314823341e-05 -443, 0.8888977955911824, 4.1615743224692816e-05 -444, 0.8908817635270542, 2.9816588699738765e-05 -445, 0.8928657314629259, 2.0683251103241476e-05 -446, 0.8948496993987977, 1.4277415306972197e-05 -447, 0.8968336673346694, 1.0553858652037456e-05 -448, 0.898817635270541, 9.37036112123466e-06 -449, 0.9008016032064128, 1.0500366435400228e-05 -450, 0.9027855711422845, 1.3647692212306002e-05 -451, 0.9047695390781563, 1.846258532505323e-05 -452, 0.906753507014028, 2.455844273946196e-05 -453, 0.9087374749498998, 3.152856409783335e-05 -454, 0.9107214428857715, 3.896236544615011e-05 -455, 0.9127054108216432, 4.646055895408592e-05 -456, 0.914689378757515, 5.3648886578259536e-05 -457, 0.9166733466933867, 6.0190082063025034e-05 -458, 0.9186573146292585, 6.579382169509857e-05 -459, 0.9206412825651302, 7.022450672594404e-05 -460, 0.922625250501002, 7.330679697464244e-05 -461, 0.9246092184368737, 7.492888419096991e-05 -462, 0.9265931863727455, 7.504355436828833e-05 -463, 0.9285771543086172, 7.366714005748984e-05 -464, 0.930561122244489, 7.087650708308553e-05 -465, 0.9325450901803607, 6.68042555393723e-05 -466, 0.9345290581162324, 6.163234345009486e-05 -467, 0.9365130260521042, 5.55843640350746e-05 -468, 0.9384969939879759, 4.891672516024524e-05 -469, 0.9404809619238477, 4.190899314945568e-05 -470, 0.9424649298597194, 3.485367338835541e-05 -471, 0.9444488977955912, 2.8045707454866356e-05 -472, 0.9464328657314629, 2.177197095804266e-05 -473, 0.9484168336673346, 1.6301057635033626e-05 -474, 0.9504008016032064, 1.1873633040468727e-05 -475, 0.9523847695390781, 8.693634636673068e-06 -476, 0.9543687374749499, 6.92058338840771e-06 -477, 0.9563527054108216, 6.663254174100191e-06 -478, 0.9583366733466934, 7.974927607402354e-06 -479, 0.9603206412825651, 1.0850413561052086e-05 -480, 0.9623046092184369, 1.522499642978052e-05 -481, 0.9642885771543086, 2.0975403970465235e-05 -482, 0.9662725450901803, 2.7922845876944936e-05 -483, 0.9682565130260521, 3.5838106039737854e-05 -484, 0.9702404809619238, 4.444860517151333e-05 -485, 0.9722244488977956, 5.344728009985515e-05 -486, 0.9742084168336673, 6.250305492762241e-05 -487, 0.9761923847695391, 7.127261017668016e-05 -488, 0.9781763527054108, 7.941309194198597e-05 -489, 0.9801603206412826, 8.659534707463544e-05 -490, 0.9821442885771543, 9.251722552731721e-05 -491, 0.984128256513026, 9.691646007784041e-05 -492, 0.9861122244488978, 9.958261918441031e-05 -493, 0.9880961923847695, 0.00010036763270500964 -494, 0.9900801603206413, 9.919441397882462e-05 -495, 0.992064128256513, 9.606314591544722e-05 -496, 0.9940480961923848, 9.10548630266493e-05 -497, 0.9960320641282565, 8.433204463476253e-05 -498, 0.9980160320641283, 7.613603476225939e-05 -499, 1.0, 6.678121852368965e-05 diff --git a/Tests/Unit/gui2/data/bilayer3b.txt b/Tests/Unit/gui2/data/bilayer3b.txt deleted file mode 100644 index 801a30c227d337d546c5ae57e28289b0ac02349b..0000000000000000000000000000000000000000 --- a/Tests/Unit/gui2/data/bilayer3b.txt +++ /dev/null @@ -1,501 +0,0 @@ -# data from TimeOfFlightReflectometry.py -0.01 0.9999999999999998 -0.011983967935871743 1.0 -0.013967935871743487 1.0000000000000004 -0.01595190380761523 1.0000000000000002 -0.017935871743486972 0.9999999999999999 -0.019919839679358717 1.0 -0.02190380761523046 1.0000000000000004 -0.023887775551102206 1.0000000000000002 -0.02587174348697395 1.0000000000000004 -0.027855711422845694 1.0 -0.02983967935871744 1.0 -0.031823647294589176 1.0000000000000002 -0.03380761523046092 1.0000000000000004 -0.035791583166332665 0.9999999999999996 -0.03777555110220441 0.9999999999999998 -0.03975951903807615 0.9999999999999998 -0.0417434869739479 1.0 -0.04372745490981964 1.0 -0.045711422845691387 1.0 -0.04769539078156313 1.0 -0.049679358717434875 1.0 -0.05166332665330661 1.0 -0.05364729458917836 1.0000000000000002 -0.0556312625250501 1.0000000000000007 -0.057615230460921846 0.9999999999999998 -0.05959919839679359 1.0 -0.061583166332665334 0.9999999999999998 -0.06356713426853708 0.9999999999999996 -0.06555110220440881 0.9999999999999998 -0.06753507014028055 1.0 -0.0695190380761523 0.9999999999999999 -0.07150300601202404 0.9999999999999996 -0.07348697394789579 0.9999999999999997 -0.07547094188376753 0.9999999999999997 -0.07745490981963928 0.9999999999999996 -0.07943887775551102 0.9999999999999996 -0.08142284569138276 0.9999999999999998 -0.08340681362725451 1.0000000000000004 -0.08539078156312625 0.9999999999999993 -0.087374749498998 0.9999999999999996 -0.08935871743486974 1.0000000000000004 -0.09134268537074147 1.0000000000000004 -0.09332665330661322 1.0000000000000009 -0.09531062124248496 0.9999999999999998 -0.0972945891783567 0.9999999999999999 -0.09927855711422845 0.9999999999999993 -0.1012625250501002 1.0000000000000002 -0.10324649298597194 0.9999992528061048 -0.10523046092184368 0.9999985974506073 -0.10721442885771543 0.999997921309658 -0.10919839679358717 0.9999971427452203 -0.11118236472945892 0.9999962122090085 -0.11316633266533066 0.9999950799230959 -0.1151503006012024 0.9999936875180906 -0.11713426853707415 0.9999919626983287 -0.1191182364729459 0.9999898137850864 -0.12110220440881762 0.9999871230233972 -0.12308617234468937 0.9999837378321051 -0.12507014028056113 0.9999794590650891 -0.12705410821643287 0.9999740250410741 -0.12903807615230461 0.9999670895946517 -0.13102204408817636 0.999958191635177 -0.1330060120240481 0.999946712547489 -0.13498997995991985 0.9999318160224282 -0.1369739478957916 0.9999123622332293 -0.13895791583166334 0.9998867841333866 -0.14094188376753508 0.999852907147281 -0.14292585170340683 0.9998076831535236 -0.14490981963927857 0.9997467928547588 -0.14689378757515031 0.99966404291278 -0.14887775551102206 0.9995504376444865 -0.1508617234468938 0.9993927251319745 -0.15284569138276555 0.999171077251899 -0.1548296593186373 0.9988553104956281 -0.15681362725450904 0.9983985870085685 -0.15879759519038078 0.9977266436988359 -0.16078156312625252 0.9967188386688286 -0.16276553106212427 0.9951737046113363 -0.164749498997996 0.9927440254766213 -0.16673346693386776 0.9888093621532706 -0.1687174348697395 0.9822141139510879 -0.17070140280561122 0.9707022984498375 -0.17268537074148296 0.9496383601680007 -0.1746693386773547 0.909021525956259 -0.17665330661322645 0.8268006578284636 -0.1786372745490982 0.6588522111821937 -0.18062124248496994 0.3622399614191024 -0.18260521042084168 0.06420150811805793 -0.18458917835671343 0.024633662977522494 -0.18657314629258517 0.15244093776327813 -0.18855711422845692 0.27529995099868965 -0.19054108216432866 0.3526612082641258 -0.1925250501002004 0.39063545710665876 -0.19450901803607215 0.3990333790987325 -0.1964929859719439 0.3845452071189573 -0.19847695390781564 0.35144925997264576 -0.20046092184368738 0.3031439950053475 -0.20244488977955913 0.24353655832687798 -0.20442885771543087 0.17808572440435927 -0.20641282565130262 0.11410584881256816 -0.20839679358717436 0.059830552998912524 -0.2103807615230461 0.022250824859572964 -0.21236472945891785 0.004789833661897041 -0.2143486973947896 0.006356984649312908 -0.21633266533066134 0.022365632593830034 -0.21831663326653308 0.04682241052607952 -0.22030060120240483 0.07416136769212864 -0.22228456913827657 0.1001720615138792 -0.22426853707414832 0.12213465250467488 -0.22625250501002006 0.13855308036162264 -0.2282364729458918 0.1487974036569265 -0.23022044088176355 0.15280542074664977 -0.23220440881763527 0.15088251751204407 -0.234188376753507 0.14358811351822667 -0.23617234468937875 0.13168199675274497 -0.2381563126252505 0.11610304292527356 -0.24014028056112224 0.09795584761494282 -0.242124248496994 0.07848468865313928 -0.24410821643286573 0.05901971090221587 -0.24609218436873748 0.04088892407033809 -0.24807615230460922 0.02530184438722244 -0.25006012024048097 0.013223849390327617 -0.2520440881763527 0.0052693211843496445 -0.25402805611222445 0.0016411405846048022 -0.2560120240480962 0.002132606619548132 -0.25799599198396794 0.006189794194701373 -0.2599799599198397 0.013015844928207822 -0.26196392785571143 0.021690550068973954 -0.2639478957915832 0.03128056624196508 -0.2659318637274549 0.04092443009513365 -0.26791583166332666 0.049887002117678506 -0.2698997995991984 0.05758607973651505 -0.27188376753507015 0.06359816326314606 -0.2738677354709419 0.06765120572513812 -0.27585170340681364 0.06961093772604753 -0.2778356713426854 0.0694652862160818 -0.27981963927855713 0.06730932686430591 -0.2818036072144289 0.06333151898991729 -0.2837875751503006 0.05780078596127256 -0.28577154308617236 0.051053313090844835 -0.2877555110220441 0.04347770115747981 -0.28973947895791585 0.035497304971156975 -0.2917234468937876 0.027549165730337055 -0.29370741482965934 0.02005983448493074 -0.2956913827655311 0.013419426316096529 -0.29767535070140283 0.007956202507095663 -0.2996593186372746 0.0039145718050655805 -0.3016432865731463 0.0014393995905691696 -0.30362725450901806 0.0005688307236762597 -0.3056112224448898 0.0012365918074232387 -0.30759519038076155 0.0032832519146904853 -0.3095791583166333 0.006474578249753218 -0.31156312625250504 0.010524253267492914 -0.3135470941883768 0.01511797850115291 -0.31553106212424853 0.01993633203535728 -0.3175150300601203 0.024674476171810362 -0.319498997995992 0.02905767996968943 -0.32148296593186376 0.03285241227312436 -0.3234669338677355 0.03587334202207215 -0.32545090180360725 0.03798691116784891 -0.327434869739479 0.03911224589336394 -0.3294188376753507 0.039220104446289754 -0.33140280561122243 0.03833039410542655 -0.3333867735470942 0.036508587609869456 -0.3353707414829659 0.0338611788968911 -0.33735470941883766 0.03053017320088866 -0.3393386773547094 0.02668652941152426 -0.34132264529058115 0.02252247460745127 -0.3433066132264529 0.01824269289141468 -0.34529058116232464 0.01405454201275371 -0.3472745490981964 0.010157647151281007 -0.34925851703406813 0.006733424032981525 -0.35124248496993987 0.003935247174387443 -0.3532264529058116 0.0018800579891315712 -0.35521042084168336 0.0006421686942934479 -0.3571943887775551 0.0002498520126686543 -0.35917835671342685 0.0006850336571871474 -0.3611623246492986 0.0018860713465820211 -0.36314629258517034 0.0037532727931319895 -0.3651302605210421 0.006156536579232831 -0.3671142284569138 0.008944337730497173 -0.36909819639278557 0.011953240771592386 -0.3710821643286573 0.015017195992625963 -0.37306613226452906 0.017976027723366806 -0.3750501002004008 0.020682715399392357 -0.37703406813627255 0.02300925974043486 -0.3790180360721443 0.024851087812409446 -0.38100200400801604 0.026130065575115363 -0.3829859719438878 0.026796250719654913 -0.3849699398797595 0.02682853773180647 -0.38695390781563127 0.026234332576648815 -0.388937875751503 0.025048360075339858 -0.39092184368737476 0.02333066686964983 -0.3929058116232465 0.021163849255882144 -0.39488977955911825 0.018649518038920673 -0.39687374749499 0.015904018618641446 -0.39885771543086174 0.013053456576381392 -0.4008416833667335 0.01022813530149914 -0.4028256513026052 0.007556585914512282 -0.40480961923847697 0.005159449356900526 -0.4067935871743487 0.003143540947434207 -0.40877755511022046 0.001596472756954287 -0.4107615230460922 0.0005822148779162445 -0.41274549098196395 0.0001379349307479975 -0.4147294589178357 0.0002723663906171204 -0.41671342685370744 0.0009658304295724124 -0.4186973947895792 0.0021718907815956433 -0.4206813627254509 0.0038204786964381836 -0.42266533066132267 0.005822206686778807 -0.4246492985971944 0.00807351144553656 -0.42663326653306616 0.010462235517300439 -0.4286172344689379 0.012873272374476484 -0.43060120240480965 0.015193951170327341 -0.4325851703406814 0.017318911741101627 -0.43456913827655314 0.019154302457323406 -0.4365531062124249 0.02062121023427756 -0.4385370741482966 0.021658294151797174 -0.44052104208416837 0.022223636927716544 -0.4425050100200401 0.022295851343178564 -0.44448897795591186 0.021874484335386073 -0.4464729458917836 0.02097975476338624 -0.44845691382765535 0.019651647884218724 -0.4504408817635271 0.017948376696229146 -0.45242484969939883 0.015944213409551735 -0.4544088176352705 0.013726698199906193 -0.45639278557114227 0.011393250203976028 -0.458376753507014 0.00904723825169567 -0.46036072144288576 0.0067936141627217735 -0.4623446893787575 0.004734264635469744 -0.46432865731462925 0.002963291172441509 -0.466312625250501 0.001562471623510888 -0.46829659318637273 0.0005971820099725045 -0.4702805611222445 0.00011305525542118876 -0.4722645290581162 0.00013361998494645114 -0.47424849699398797 0.0006590985922606173 -0.4762324649298597 0.0016664559033823143 -0.47821643286573146 0.0031106893010797083 -0.4802004008016032 0.004927252009008278 -0.48218436873747494 0.007035416996440179 -0.4841683366733467 0.00934233025415317 -0.48615230460921843 0.011747474637648414 -0.4881362725450902 0.014147269061668665 -0.4901202404809619 0.016439557549772294 -0.49210420841683367 0.018527790107948538 -0.4940881763527054 0.020324752880853687 -0.49607214428857715 0.021755759417808256 -0.4980561122244489 0.022761260944526455 -0.5000400801603206 0.023298866813712966 -0.5020240480961924 0.023344785094500477 -0.5040080160320641 0.022894698329123202 -0.5059919839679359 0.0219640835395822 -0.5079759519038076 0.02058797266194096 -0.5099599198396794 0.01882013459000496 -0.5119438877755511 0.016731648124927643 -0.5139278557114229 0.014408831409332683 -0.5159118236472946 0.011950502241680821 -0.5178957915831663 0.009464568041977305 -0.5198797595190381 0.007063985106731697 -0.5218637274549098 0.004862182277144541 -0.5238476953907816 0.0029681091037364084 -0.5258316633266533 0.0014811346546237739 -0.5278156312625251 0.000486079503704131 -0.5297995991983968 4.869861470054776e-05 -0.5317835671342686 0.00021193684162505277 -0.5337675350701403 0.0009932457099753257 -0.535751503006012 0.0023831802222176583 -0.5377354709418838 0.004345394715813398 -0.5397194388777555 0.0068180403841822815 -0.5417034068136273 0.009716450625062706 -0.543687374749499 0.012936900724504447 -0.5456713426853708 0.01636115898480383 -0.5476553106212425 0.019861514793368784 -0.5496392785571143 0.023305975875961987 -0.551623246492986 0.026563366329670324 -0.5536072144288577 0.029508118832884456 -0.5555911823647295 0.03202462662109848 -0.5575751503006012 0.03401109178813516 -0.559559118236473 0.0353828667589039 -0.5615430861723447 0.03607532889791913 -0.5635270541082165 0.03604635071583357 -0.5655110220440882 0.03527842913439466 -0.56749498997996 0.033780517814299825 -0.5694789579158317 0.03158956906567713 -0.5714629258517034 0.02877173989735132 -0.5734468937875752 0.025423155100636436 -0.5754308617234469 0.021670055336900616 -0.5774148296593187 0.017668098632004647 -0.5793987975951904 0.01360054066770616 -0.5813827655310622 0.009675006335630927 -0.5833667334669339 0.006118596777585109 -0.5853507014028057 0.0031711655175897836 -0.5873346693386774 0.0010767514123354313 -0.5893186372745491 7.337126248933872e-05 -0.5913026052104209 0.00038163193943142594 -0.5932865731462926 0.0021928845162606674 -0.5952705410821644 0.0056578607646843365 -0.5972545090180361 0.010876850180429382 -0.5992384769539079 0.017892447510133306 -0.6012224448897796 0.02668570573220913 -0.6032064128256514 0.037176183119206514 -0.6051903807615231 0.04922592865951015 -0.6071743486973948 0.06264698790058769 -0.6091583166332666 0.07721161770418648 -0.6111422845691383 0.09266414313905552 -0.6131262525050101 0.10873330807907763 -0.6151102204408818 0.1251440579875237 -0.6170941883767536 0.14162790993709415 -0.6190781563126253 0.15793135330400035 -0.621062124248497 0.17382202514428602 -0.6230460921843688 0.18909266915069564 -0.6250300601202405 0.2035630872277019 -0.6270140280561123 0.21708041825847607 -0.628997995991984 0.22951813481130462 -0.6309819639278558 0.24077414965038677 -0.6329659318637275 0.2507683876073812 -0.6349498997995993 0.2594401213643935 -0.636933867735471 0.2667453054381796 -0.6389178356713427 0.27265408047685313 -0.6409018036072145 0.2771485653514613 -0.6428857715430862 0.28022100981180365 -0.644869739478958 0.2818723458635943 -0.6468537074148296 0.28211115035364215 -0.6488376753507014 0.28095301267295864 -0.6508216432865731 0.27842028792463336 -0.6528056112224448 0.2745422053320233 -0.6547895791583166 0.26935529229416066 -0.6567735470941883 0.26290406487717055 -0.6587575150300601 0.2552419246275385 -0.6607414829659318 0.2464321888632971 -0.6627254509018036 0.2365491670864776 -0.6647094188376753 0.22567918059298267 -0.6666933867735471 0.21392140723490657 -0.6686773547094188 0.2013884209214198 -0.6706613226452905 0.18820628886495724 -0.6726452905811623 0.17451409231440515 -0.674629258517034 0.1604627521165676 -0.6766132264529058 0.1462130717958097 -0.6785971943887775 0.13193295929218454 -0.6805811623246493 0.11779385297798245 -0.682565130260521 0.10396645389418357 -0.6845490981963928 0.09061594680987843 -0.6865330661322645 0.07789696743553526 -0.6885170340681362 0.06594863026369184 -0.690501002004008 0.054889960155995815 -0.6924849699398797 0.0448160631944758 -0.6944689378757515 0.03579532599062774 -0.6964529058116232 0.027867851529310705 -0.698436873747495 0.02104523376601873 -0.7004208416833667 0.015311657001329292 -0.7024048096192385 0.01062619545703843 -0.7043887775551102 0.006926097790945572 -0.706372745490982 0.004130780592705779 -0.7083567134268537 0.0021462285840382345 -0.7103406813627254 0.0008695059176485245 -0.7123246492985972 0.000193116620165803 -0.7143086172344689 9.004092252511728e-06 -0.7162925851703407 0.0002120401728068695 -0.7182765531062124 0.000702915069422189 -0.7202605210420842 0.0013903939835314 -0.7222444889779559 0.0021929505257092573 -0.7242284569138276 0.003039819393007217 -0.7262124248496994 0.003871531521672373 -0.7281963927855711 0.0046400055593236855 -0.7301803607214429 0.0053082722075593804 -0.7321643286573146 0.00584990512316418 -0.7341482965931864 0.006248225808298112 -0.7361322645290581 0.006495342061634846 -0.7381162324649299 0.006591071435228216 -0.7401002004008016 0.006541793617286351 -0.7420841683366733 0.006359269203542507 -0.7440681362725451 0.006059457066852846 -0.7460521042084168 0.00566135838422228 -0.7480360721442886 0.005185912077448136 -0.7500200400801603 0.0046549636367218305 -0.7520040080160321 0.004090326684460166 -0.7539879759519038 0.003512953900481543 -0.7559719438877756 0.0029422308513142605 -0.7579559118236473 0.0023954027315925422 -0.759939879759519 0.0018871400311782185 -0.7619238476953908 0.0014292447890569052 -0.7639078156312625 0.0010304945698099762 -0.7658917835671343 0.0006966168414242411 -0.767875751503006 0.00043038230631217646 -0.7698597194388778 0.00023180218940765428 -0.7718436873747495 9.84117236624081e-05 -0.7738276553106213 2.5620234778188087e-05 -0.775811623246493 7.107377406914545e-06 -0.7777955911823647 3.52452002712822e-05 -0.7797795591182365 0.00010152673394992479 -0.7817635270541082 0.00019698356418977264 -0.78374749498998 0.0003125772019421228 -0.7857314629258517 0.0004395517998419576 -0.7877154308617235 0.0005697387072413838 -0.7896993987975952 0.0006958063329571489 -0.791683366733467 0.0008114516542151142 -0.7936673346693387 0.0009115323612152717 -0.7956513026052104 0.0009921409810344773 -0.7976352705410822 0.0010506243337552023 -0.7996192384769539 0.001085553314410324 -0.8016032064128257 0.0010966492627619995 -0.8035871743486974 0.0010846740892822139 -0.8055711422845692 0.0010512918893824008 -0.8075551102204409 0.0009989100239061956 -0.8095390781563127 0.0009305076002728938 -0.8115230460921844 0.0008494589854774166 -0.8135070140280561 0.00075935945102763 -0.8154909819639279 0.0006638593242132494 -0.8174749498997996 0.0005665121353902215 -0.8194589178356714 0.0004706412451662618 -0.8214428857715431 0.00037922834870297243 -0.8234268537074149 0.0002948261286759213 -0.8254108216432866 0.00021949620614409963 -0.8273947895791584 0.00015477246102135799 -0.8293787575150301 0.0001016487995011666 -0.8313627254509018 6.058956842976623e-05 -0.8333466933867736 3.156008360717915e-05 -0.8353306613226453 1.4074169956026223e-05 -0.8373146292585171 7.255217543491329e-06 -0.8392985971943888 9.90704095152882e-06 -0.8412825651302606 2.0590784494257463e-05 -0.8432665330661323 3.770422887497309e-05 -0.845250501002004 5.956010654522103e-05 -0.8472344689378758 8.446039924674957e-05 -0.8492184368737475 0.00011076404514623134 -0.8512024048096193 0.000136945996638117 -0.853186372745491 0.00016164611570323428 -0.8551703406813628 0.00018370694574904647 -0.8571543086172345 0.00020219993387200045 -0.8591382765531063 0.00021644017559656643 -0.861122244488978 0.00022599019928002835 -0.8631062124248498 0.00023065368741721326 -0.8650901803607215 0.0002304603388671356 -0.8670741482965932 0.00022564330514447347 -0.869058116232465 0.00021661078442208924 -0.8710420841683367 0.00020391343091570734 -0.8730260521042085 0.00018820923967411692 -0.8750100200400802 0.00017022750450188212 -0.876993987975952 0.00015073332857219645 -0.8789779559118237 0.00013049400330005412 -0.8809619238476954 0.000110248372099437 -0.8829458917835672 9.068007294074733e-05 -0.8849298597194389 7.239531824426369e-05 -0.8869138276553107 5.590563314823341e-05 -0.8888977955911824 4.1615743224692816e-05 -0.8908817635270542 2.9816588699738765e-05 -0.8928657314629259 2.0683251103241476e-05 -0.8948496993987977 1.4277415306972197e-05 -0.8968336673346694 1.0553858652037456e-05 -0.898817635270541 9.37036112123466e-06 -0.9008016032064128 1.0500366435400228e-05 -0.9027855711422845 1.3647692212306002e-05 -0.9047695390781563 1.846258532505323e-05 -0.906753507014028 2.455844273946196e-05 -0.9087374749498998 3.152856409783335e-05 -0.9107214428857715 3.896236544615011e-05 -0.9127054108216432 4.646055895408592e-05 -0.914689378757515 5.3648886578259536e-05 -0.9166733466933867 6.0190082063025034e-05 -0.9186573146292585 6.579382169509857e-05 -0.9206412825651302 7.022450672594404e-05 -0.922625250501002 7.330679697464244e-05 -0.9246092184368737 7.492888419096991e-05 -0.9265931863727455 7.504355436828833e-05 -0.9285771543086172 7.366714005748984e-05 -0.930561122244489 7.087650708308553e-05 -0.9325450901803607 6.68042555393723e-05 -0.9345290581162324 6.163234345009486e-05 -0.9365130260521042 5.55843640350746e-05 -0.9384969939879759 4.891672516024524e-05 -0.9404809619238477 4.190899314945568e-05 -0.9424649298597194 3.485367338835541e-05 -0.9444488977955912 2.8045707454866356e-05 -0.9464328657314629 2.177197095804266e-05 -0.9484168336673346 1.6301057635033626e-05 -0.9504008016032064 1.1873633040468727e-05 -0.9523847695390781 8.693634636673068e-06 -0.9543687374749499 6.92058338840771e-06 -0.9563527054108216 6.663254174100191e-06 -0.9583366733466934 7.974927607402354e-06 -0.9603206412825651 1.0850413561052086e-05 -0.9623046092184369 1.522499642978052e-05 -0.9642885771543086 2.0975403970465235e-05 -0.9662725450901803 2.7922845876944936e-05 -0.9682565130260521 3.5838106039737854e-05 -0.9702404809619238 4.444860517151333e-05 -0.9722244488977956 5.344728009985515e-05 -0.9742084168336673 6.250305492762241e-05 -0.9761923847695391 7.127261017668016e-05 -0.9781763527054108 7.941309194198597e-05 -0.9801603206412826 8.659534707463544e-05 -0.9821442885771543 9.251722552731721e-05 -0.984128256513026 9.691646007784041e-05 -0.9861122244488978 9.958261918441031e-05 -0.9880961923847695 0.00010036763270500964 -0.9900801603206413 9.919441397882462e-05 -0.992064128256513 9.606314591544722e-05 -0.9940480961923848 9.10548630266493e-05 -0.9960320641282565 8.433204463476253e-05 -0.9980160320641283 7.613603476225939e-05 -1.0 6.678121852368965e-05 diff --git a/Tests/Unit/gui2/data/p15320_00017128_report.csv b/Tests/Unit/gui2/data/p15320_00017128_report.csv deleted file mode 100644 index e668b1fc1c333c2d3a127bb8a4e317c90ef415a4..0000000000000000000000000000000000000000 --- a/Tests/Unit/gui2/data/p15320_00017128_report.csv +++ /dev/null @@ -1,254 +0,0 @@ -# ***************************************************************************** - -# Reflected beam: p15320_00017128.cfg - -# Primary beam: p15320_00017114.cfg - -# Comment: reflectivity for Sample_1_water_swollen static at 0.60 deg - -# wavelength -# alpha_corr -# q_nomin -# q_corr -# prim_integ_peak -# prim_sigma_integ_peak -# refl_integ_peak -# refl_sigma_integ_peak -# reflectivity -# sigma_reflectivity - -# ***************************************************************************** - -2e-10, --, 0.06579616009915212, --, --, 0.0, --, 0.0, --, -- -2.0201005025125624e-10, --, 0.06514147193896157, --, --, 0.0, --, 0.0, --, -- -2.0404030201257538e-10, --, 0.06449329808882265, --, --, 0.0, --, 0.0, --, -- -2.0609095831420927e-10, --, 0.06385157372972991, --, --, 0.0, --, 0.0, --, -- -2.0816222422691487e-10, --, 0.06321623468764305, --, --, 0.0, --, 0.0, --, -- -2.102543068824617e-10, --, 0.06258721742706949, --, --, 0.0, --, 0.0, --, -- -2.123674154943457e-10, --, 0.0619644590447106, --, --, 0.0, --, 0.0, --, -- -2.1450176137871093e-10, --, 0.06134789726317121, --, --, 0.0, --, 0.0, --, -- -2.1665755797548188e-10, --, 0.0607374704247317, --, --, 0.0, --, 0.0, --, -- -2.1883502086970776e-10, --, 0.06013311748518215, --, --, 0.0, --, 0.0, --, -- -2.2103436781312186e-10, --, 0.05953477800771766, --, --, 0.0, --, 0.0, --, -- -2.2325581874591706e-10, --, 0.058942392156894605, --, --, 0.0, --, 0.0, --, -- -2.254995958187403e-10, --, 0.058355900692646914, --, --, 0.0, --, 0.0, --, -- -2.277659234149085e-10, --, 0.05777524496436188, --, --, 0.0, --, 0.0, --, -- -2.300550281728472e-10, --, 0.05720036690501501, --, --, 0.0, --, 0.0, --, -- -2.323671390087552e-10, --, 0.05663120902536312, --, --, 0.0, --, 0.0, --, -- -2.347024871394964e-10, --, 0.05606771440819534, --, --, 0.0, --, 0.0, --, -- -2.370613061057225e-10, --, 0.05550982670264116, --, --, 0.0, --, 0.0, --, -- -2.394438317952272e-10, --, 0.054957490118535283, --, 398.4040263797292, 21.143187154929578, 0.0, 1.0, --, -- -2.4185030246653594e-10, --, 0.05441064942083844, --, 1534.6363068379035, 40.841746377161826, 2.0, 1.7320508075688772, 7.174614594692112e-05, 6.245216967779148e-05 -2.4428095877273223e-10, --, 0.05386924992411369, --, 1571.062200624783, 41.776479152073485, 5.0, 2.6457513110645907, 0.00018093055054731107, 9.695866471987633e-05 -2.467360437855235e-10, 0.5658307609070953, 0.05333323748705783, 0.05029607896932152, 1609.1153418951753, 42.4964992330779, 8.7428554899919, 3.6308772628693364, 0.00031875719788951106, 0.00013503187882546317 -2.492158030195488e-10, --, 0.05280255850708713, --, 1804.0966099733887, 44.64826087194522, 5.0, 3.1622776601683795, 0.00015543733529493358, 9.910737714287484e-05 -2.5172048445693114e-10, --, 0.05227715991497681, --, 1905.99856531297, 46.198585125687686, 7.721774846696749, 3.7479602227489783, 0.00021474955458839, 0.00010568298278671186 -2.5425033857207615e-10, 0.5634863884525005, 0.051756989169554166, 0.04860736967987198, 2039.8120444290178, 47.24636149029365, 12.0, 3.872983346207417, 0.00036869987271973123, 0.00012213594755335256 -2.568056183567201e-10, 0.5713083859852034, 0.05124199425244418, 0.04879171830060828, 2141.590072891357, 48.50213534412636, 14.0, 4.0, 0.00035446361790297755, 0.00010470511834254454 -2.5938657934522977e-10, --, 0.05073212366286763, --, 2236.3705889158855, 49.56563496401141, 5.850225616105519, 3.633552998549248, 0.00015025608606638726, 9.393883523707522e-05 -2.6199347964015667e-10, 0.5677963509669373, 0.05022732641249085, 0.04753157851263009, 2302.157237070461, 50.905139402940115, 10.0, 3.605551275463989, 0.00023744327450590788, 8.727146133225931e-05 -2.646265799380477e-10, 0.5722895294845328, 0.04972755202032676, 0.047431007138860386, 2508.854911489066, 52.66065978043699, 20.19378687955571, 5.6013275066596675, 0.0004614643484094782, 0.0001318102634290037 -2.672861435555154e-10, 0.5736917814912171, 0.04923275050768672, 0.04707411437361956, 2473.2956727987967, 52.487171371921704, 18.678792086081224, 4.693892580777178, 0.00043012186251625194, 0.00011177463926242429 -2.699724364555708e-10, 0.5673838849262329, 0.048742872393182375, 0.04609328960397372, 2553.0380539164644, 53.60685494976364, 10.0, 3.4641016151377544, 0.00019529503293149234, 6.894263191780379e-05 -2.7268572727421967e-10, 0.5703073662094136, 0.04825786868777759, 0.0458697775751033, 2581.8108989934053, 53.542769676755654, 15.0, 4.0, 0.000295488443890465, 8.11691197407189e-05 -2.754262873473274e-10, 0.572172846813268, 0.04777769088988926, 0.04556190446932175, 2665.3453314821245, 55.25926397241143, 21.656704847853753, 5.001804603184886, 0.00043356143273443585, 0.00010369473055768681 -2.7819439073775273e-10, 0.5717746304843873, 0.047302290980537134, 0.04507715893548082, 2794.9199583477957, 56.197629405966936, 12.626564850167767, 4.366377803139587, 0.0002554589412383227, 8.967655403117131e-05 -2.809903142627552e-10, 0.576570012954414, 0.04683162141854175, 0.0450029105982062, 2750.573446719889, 55.569241902415435, 20.0, 5.0990195135927845, 0.00041561028353391874, 0.00010876079076377993 -2.8381433752167737e-10, 0.5725709086495587, 0.04636563513577019, 0.044246095315304754, 2857.5741756334605, 56.430373190298766, 27.0, 5.291502622129181, 0.0005440962814405112, 0.00011113317638011863 -2.8666674292390517e-10, 0.5746153748632182, 0.045904285532429215, 0.04396224694909134, 2935.753939604304, 57.30902668943389, 19.716117088973736, 5.116484171206859, 0.00038541462664650443, 0.00010240776492185803 -2.8954781571711026e-10, 0.5698054126261662, 0.04544752647240504, 0.04316048835638389, 3058.1888233252344, 58.2220849564387, 29.0, 5.916079783099616, 0.0004911096972496526, 0.0001039771848510276 -2.9245784401577466e-10, 0.5733696028334697, 0.04499531227864977, 0.04299830876441435, 3337.0747657063516, 60.62404845973859, 30.587191947240537, 6.014445182259056, 0.0005013210960663508, 0.00010222661196437309 -2.953971188300034e-10, 0.5716442005021961, 0.044547597728613476, 0.04244236473496125, 3592.761818812912, 63.30881376813905, 41.0, 6.48074069840786, 0.0006126764318371097, 0.00010233658468871584 -2.9836593409462653e-10, 0.5708395221880317, 0.0441043380497218, 0.04196090483279468, 3779.889482818466, 64.80665983234653, 23.69802152030545, 5.568948721673628, 0.0003224553722452253, 7.774949758730845e-05 -3.013645866985925e-10, 0.5724348686872228, 0.043665488914898715, 0.04165948237670842, 3891.5324540090246, 66.06008698133806, 26.43653823903737, 6.274276005727119, 0.0003650870019924193, 8.868101897045752e-05 -3.043933765146588e-10, 0.5725411974241433, 0.04323100643813355, 0.04125262108544657, 3978.883720930233, 65.948711573006, 33.047529792895986, 6.498124045100933, 0.00046225822313480854, 9.38367830129222e-05 -3.0745260642937894e-10, 0.5716207902656013, 0.04280084717009243, 0.040776492306401145, 4134.832696980216, 67.54499959139945, 42.66459562651857, 7.417415270054759, 0.0005772955944842899, 0.00010426584080885295 -3.105425823733927e-10, 0.5750610953929685, 0.04237496809377312, 0.04061371970709788, 4100.026726830962, 66.97107811372003, 50.0, 7.416198487095663, 0.0006502373192951335, 0.00010139067377168397 -3.1366361335201975e-10, 0.5690533953142517, 0.04195332662020323, 0.039789544680610384, 4111.689806780054, 67.57334452259086, 37.58694897604998, 7.368657887016019, 0.0004632440650837637, 9.346574069364315e-05 -3.168160114761606e-10, 0.5701125645904992, 0.04153588058418132, 0.039466949077802224, 4325.352701608238, 68.50574277226899, 52.29940992710865, 7.879384037790949, 0.0006317448114345859, 9.965439780906357e-05 -3.2000009199350886e-10, 0.5709010070900161, 0.04112258824006012, 0.03912827941940098, 4234.6447529792895, 68.05526114813603, 54.42540784449844, 8.136205993548533, 0.0006386144021849369, 9.997887832101616e-05 -3.2321617332007674e-10, 0.5745362371604681, 0.04071340825757197, 0.03898560650077779, 4460.844706699063, 69.22707856614485, 49.0, 7.416198487095663, 0.0005963518369003051, 9.400150511290926e-05 -3.264645770720372e-10, 0.5724001235643003, 0.04030829971769564, 0.0384541894049841, 4554.0874696286, 69.55284861480425, 54.160823788036566, 8.555208947702019, 0.0006259820670105101, 0.00010263802037503378 -3.297456280978868e-10, 0.57096302720046, 0.039907222108564344, 0.03797597945935461, 4561.069536040728, 69.34183068551383, 56.0, 8.06225774829855, 0.0006836675075753987, 0.00010264651379216846 -3.330596545109308e-10, 0.5708771323986914, 0.03951013532141446, 0.03759245300232875, 4586.875112808052, 69.75350560798051, 49.71072544255467, 7.351349971773715, 0.0005634676758406563, 8.676083357828955e-05 -3.364069877220959e-10, 0.5717266439194317, 0.03911699964657452, 0.03727378090572066, 4680.320953372672, 70.00460886300118, 54.0, 7.416198487095662, 0.0005893689938457065, 8.473371457359537e-05 -3.397879624730717e-10, 0.5717390051047588, 0.03872777576949418, 0.0369036953571727, 4633.793127386326, 69.49249508122209, 69.43543908365152, 8.604503877835503, 0.0007957714256769522, 0.00010391591883596735 -3.432029168697859e-10, 0.5712708066166515, 0.038342424766812655, 0.03650657557440909, 4820.991044776119, 71.20173148993062, 93.0, 10.198039027185569, 0.001041349412329139, 0.00012179686100677445 -3.4665219241621584e-10, 0.5720740787224103, 0.037960908102466266, 0.03619414602968369, 4781.520930232558, 70.84227485743766, 82.0, 9.643650760992955, 0.0008726753161453195, 0.00010875003466703083 -3.501361340485396e-10, 0.573752343401439, 0.03758318762383477, 0.03593912616629551, 4837.281846581048, 71.34140434292186, 82.33473331019322, 9.38955973423551, 0.0009528707479953561, 0.0001149937949272083 -3.536550901696304e-10, 0.5719640497121008, 0.03720922555792597, 0.03547062473167824, 5015.888233252343, 72.11873381270401, 96.51336341548074, 10.256600214956954, 0.0010073825719030497, 0.00011422588565711758 -3.5720941268389793e-10, 0.5728005627246247, 0.03683898450759836, 0.035169042051076724, 5085.875911141965, 72.52754686187009, 71.03967372440125, 8.902514961986078, 0.0006678780108985284, 8.79904803968042e-05 -3.6079945703247974e-10, 0.5769617572666634, 0.03647242744782127, 0.0350720413347633, 5070.514092329052, 72.49624821230009, 90.61159319680667, 10.344717969313148, 0.0009101472364839245, 0.00010990705762652325 -3.64425582228786e-10, 0.5715158396112747, 0.0361095177219723, 0.03439532716968344, 5204.508932083767, 73.43756069661542, 92.0, 9.848857801796104, 0.0009429414140672893, 0.0001072752712189468 -3.6808815089440196e-10, 0.5741689039788583, 0.035750219038171584, 0.03421115948378256, 5168.169755871805, 73.26219715114135, 89.29774383894481, 9.8574180912949, 0.0009522770700153147, 0.00011102337898862297 -3.7178752929535066e-10, 0.5733690006101942, 0.03539449546565247, 0.03382356448002948, 5358.880944116628, 74.48569698863919, 118.0, 11.180339887498949, 0.001132087581918549, 0.00011555452414208149 -3.7552408737872097e-10, 0.5728423666506173, 0.03504231143116837, 0.03345625512411443, 5136.973273169038, 72.64314645464472, 111.9674881406919, 11.188470909432546, 0.0011114651741212947, 0.00011861919609936893 -3.792981988096627e-10, 0.5705584576087975, 0.034693631715435366, 0.03299129939171578, 5218.977542519958, 73.40484138887994, 133.68737706814764, 12.183657634857255, 0.001369364630723623, 0.0001345232709398948 -3.831102410087548e-10, 0.5748390612539285, 0.034348421449610145, 0.03290807328988706, 5211.23443248872, 73.60582230641594, 126.24609510586602, 11.626207095462734, 0.0011949865303339648, 0.00011872070918704905 -3.8696059518974716e-10, 0.57301323423922, 0.03400664611180309, 0.032477149319660545, 5134.689135716764, 73.21928379608234, 120.42276987157237, 11.586356864604182, 0.0012736894512957151, 0.0001308684990980158 -3.9084964639768436e-10, 0.5740816740172163, 0.03366827152362594, 0.03221394589784299, 5047.3873192178635, 72.55331855485153, 118.0, 11.135528725660043, 0.0012798303754431532, 0.00012911806427506333 -3.947777835474097e-10, 0.5829130102640814, 0.03333326384677395, 0.03238402185000811, 5047.389448108295, 72.3077565868085, 116.66545181071388, 11.55147843090244, 0.001219091748190807, 0.00012834095790293686 -3.9874539946245903e-10, 0.5734533951683128, 0.033001589579641874, 0.03154150586824322, 4861.257399051255, 71.05592001743747, 109.85428670600488, 11.003849000008806, 0.0011308745002155446, 0.00012049536700593618 -4.027528909143429e-10, 0.574423816390964, 0.0326732155539738, 0.031280502989561726, 4779.589031586254, 70.30520561684953, 139.53748698368622, 12.048798730595475, 0.00151037096742173, 0.00014104167293775395 -4.068006586622257e-10, 0.571617846501096, 0.03234810893154621, 0.030817979304927617, 5054.877820201319, 72.25041300780696, 148.46830961471713, 12.417251270785846, 0.0015564771106532183, 0.00014117278848532584 -4.1088910749300176e-10, 0.5752544730134882, 0.032026237200884065, 0.030705439009390607, 5753.4571329399505, 77.0749172368031, 174.59922480620153, 14.053759528680173, 0.001469191308377735, 0.00012929786067982627 -4.150186462617755e-10, 0.5746640055649891, 0.031707568174009604, 0.030368709442419806, 6325.7330787920855, 80.59487479000032, 220.32725905356935, 15.237561146654064, 0.0017178564798984324, 0.0001332170609006542 -4.191896879327481e-10, 0.5740514943557751, 0.03139206998322345, 0.03003448759561688, 6376.506907323846, 80.96316027529606, 234.0, 15.716233645501712, 0.0018864153075920616, 0.00014240119726563924 -4.234026496205144e-10, 0.573699709787592, 0.031079711077917734, 0.02971741528253069, 6453.634154807359, 81.63780797146187, 251.18974892976976, 16.85570795496185, 0.0020375165152231017, 0.0001532169949973361 -4.2765795263177574e-10, 0.5749996200109653, 0.030770460221421055, 0.029488382203408416, 6873.7108642832345, 84.00172102830254, 292.63141270392225, 17.527575338816735, 0.002148601543616395, 0.00014798345093327945 -4.319560225074719e-10, 0.5750440231172188, 0.03046428648787458, 0.029197219907648377, 7251.577577230129, 86.00826950223956, 235.02395001735508, 15.892885989043739, 0.0016503642763768187, 0.00012440925023239483 -4.362972890653358e-10, 0.5736513841124758, 0.03016115925913952, 0.028836696533043733, 7533.131366423697, 87.90233330986719, 264.4900497512438, 16.99077888633064, 0.001725166066098775, 0.00012474734683688303 -4.4068218644287687e-10, 0.5671194806471337, 0.02986104822173515, 0.02822469192251784, 7969.8205484206865, 90.31710497784633, 247.23060279995372, 16.351304259576356, 0.001623746573557252, 0.00011929673190829297 -4.4511115314079515e-10, 0.572220423664031, 0.029563923363807438, 0.028195181201302707, 8130.924887191946, 91.20996218813103, 294.18026148328124, 17.321449926604732, 0.0019010623114440604, 0.00012661746070131576 -4.495846320668332e-10, 0.5733729825044432, 0.02926975497212777, 0.0279708555439751, 8155.658104824712, 91.29996599315125, 328.28110609741987, 18.52674268124196, 0.001961574824274164, 0.00012663379569156544 -4.5410307058006753e-10, 0.5736514820901536, 0.028978513629121537, 0.02770598898544913, 8389.960499826448, 92.4450135355855, 379.6629063982413, 20.208063865512734, 0.002255183461558323, 0.00013829980500958938 -4.5866692053564604e-10, 0.5730601470369867, 0.0286901702099263, 0.027402032563095095, 8454.53453661923, 93.0455021125727, 400.56279069767436, 20.604741268001337, 0.0024579728292377844, 0.00014596617718058808 -4.6327663832997415e-10, 0.5746506347129868, 0.02840469587947927, 0.02720466865347032, 8659.185352308225, 93.80732726014409, 501.4527941686913, 22.790437169561475, 0.0028900596590930644, 0.00015658000338939436 -4.679326849463557e-10, 0.574236420152664, 0.02812206208963371, 0.0269145617746557, 9046.70322804582, 96.22004350422101, 597.3315052643758, 25.01945789119018, 0.00322743737317117, 0.0001645102979335105 -4.726355260010928e-10, 0.5746629200318323, 0.02784224057630403, 0.02666654574390238, 9442.388753904896, 97.94698181207579, 599.2557792433182, 24.967865498117916, 0.003329727961537192, 0.00016726031567660727 -4.773856317900485e-10, 0.5743535538785467, 0.027565203356639315, 0.02638699453346676, 9820.2484901076, 100.1217759052098, 651.1440472058314, 25.96828760478075, 0.0034708770457513214, 0.0001686320846076389 -4.82183477335677e-10, 0.5759424916237067, 0.027290922726225002, 0.02619670768222673, 9673.279416869142, 99.40684374393373, 591.9342242276986, 24.83166513137624, 0.003236193225285449, 0.0001620531211825134 -4.870295424345279e-10, 0.5763216758393273, 0.02701937125631232, 0.025953118904844714, 9908.820779821819, 100.3866699949212, 539.2454356126345, 23.649815642780847, 0.0026927470725172918, 0.00013964985374412457 -4.919243117052266e-10, 0.5747566681558366, 0.02675052179107539, 0.025625106540492215, 10039.580701145434, 101.17024907972977, 484.28229781325933, 22.968656487482807, 0.0024734587477531424, 0.00013519362256487227 -4.968682746369373e-10, 0.5754240988864506, 0.026484347444895535, 0.025399590189374533, 10093.056577577232, 101.25681914035603, 463.3333333333333, 22.262678762261334, 0.002430722444227431, 0.00013341385164323668 -5.018619256383135e-10, 0.5724898773806631, 0.0262208215996727, 0.025018632541203706, 10063.116626171466, 101.0588114605972, 499.96253615642723, 23.332177125450553, 0.002528726378738469, 0.00013558619484851776 -5.069057640869398e-10, 0.5753518877081896, 0.02595991790216352, 0.02489351623000045, 10078.170426935092, 101.35990120883558, 593.4656369316209, 25.05917328873028, 0.0029820878246752816, 0.00014841194499557456 -5.120002943792707e-10, 0.5747830734074706, 0.02570161026134598, 0.024621454593929365, 10116.581858151103, 101.75781833600111, 726.2631030892053, 27.682354282690973, 0.0036441332168153096, 0.00016858470784409028 -5.171460259810723e-10, 0.5749741338894291, 0.0254458728458102, 0.024384567570760473, 10269.115237764665, 102.52748296059616, 838.6434571329398, 29.646125304573168, 0.0040982749375797255, 0.0001800523508631565 -5.223434734783693e-10, 0.5755117693140166, 0.025192680081175287, 0.02416450846122641, 10415.67823672336, 102.99185289757943, 1083.146546338077, 33.4010425359037, 0.005448484713155046, 0.00021756771372107876 -5.275931566289057e-10, 0.5757902269350959, 0.024942006647531746, 0.023935640704693225, 10755.464074973968, 104.88599453717386, 1133.3293995140577, 34.618895029920814, 0.005393097929112829, 0.00021418150353603386 -5.328956004141207e-10, 0.5756725757651175, 0.02469382747690955, 0.023692633185342094, 10448.732384588686, 103.335703488249, 1192.0208376721046, 35.17743983743189, 0.005724924024935895, 0.00022368867578771479 -5.382513350916495e-10, 0.5757338531194964, 0.02444811775077115, 0.023459382371009235, 10337.415133634153, 102.6945457788859, 1151.7091287747312, 34.75464654458072, 0.0056418963617233765, 0.00022216404740035722 -5.436608962483494e-10, 0.5761992286416322, 0.02420485289752965, 0.023244728985389332, 10389.57931273863, 102.97776792716652, 1022.4426240888579, 32.64024555651484, 0.004838490128990716, 0.00019692794605593163 -5.491248248538603e-10, 0.5768607233388297, 0.023964008590091547, 0.023039857402736067, 10566.998727293765, 103.75772952057854, 971.970010413051, 31.863798131704165, 0.0046809673582241165, 0.00019237601889880623 -5.546436673147031e-10, 0.5772154482820445, 0.02372556074342397, 0.022824631382251884, 10187.850399166955, 102.12394039433696, 885.2778202013191, 30.6468616407558, 0.00445196690350773, 0.00018920147756995015 -5.602179755289211e-10, 0.5750979131844203, 0.023489485512146125, 0.022514623615163494, 10118.078676385516, 101.77883509779055, 729.0910563461761, 28.121624329796443, 0.003669487725549219, 0.00016770841255349603 -5.65848306941272e-10, 0.5769916426284344, 0.023255759288144676, 0.022363995334904567, 10096.096147171116, 101.74922040403493, 783.9695823209534, 29.016961131754705, 0.003969784884894351, 0.0001762330780558802 -5.715352245989731e-10, 0.5741310652763524, 0.023024358698212892, 0.022031699952056283, 10078.172162443596, 101.48580673723764, 833.8023371514521, 29.79816403169565, 0.004176936236631505, 0.00018081099842836773 -5.772792972080078e-10, 0.5744003894925092, 0.022795260601713267, 0.02182271092289715, 9965.558486636584, 101.00713595268117, 992.4444290177022, 32.29509136180509, 0.005113188185003203, 0.00020762075014822147 -5.830810991899978e-10, 0.5754097763379805, 0.022568442088263387, 0.021643535450924112, 10018.931273863243, 101.29199734498653, 1256.1749045470322, 36.30575163148736, 0.006609522876246469, 0.00024839670475572157 -5.889412107396459e-10, 0.5765830124527359, 0.02234388047544485, 0.021471866559164516, 9724.022364919589, 99.74794509761844, 1467.2318639361333, 39.17031758790732, 0.007586876050644626, 0.0002747289169914237 -5.948602178827578e-10, 0.5756727221653276, 0.022121553306534956, 0.021224655503751737, 9713.45678583825, 99.87764121244429, 1651.492676154113, 41.73184673939626, 0.008701801274324421, 0.0003055130898612273 -6.008387125348458e-10, 0.5760116605530755, 0.021901438348260978, 0.021025836566670477, 9478.162790697674, 98.34041493354768, 1839.0514057618884, 43.93641472289062, 0.00957336234159374, 0.0003279690238381971 -6.068772925603215e-10, 0.5774393445442857, 0.021683513588576793, 0.020868217933752077, 9299.503297466159, 97.47049144502064, 2004.5599676038412, 46.00431215923147, 0.0108886829769264, 0.0003660480964268284 -6.129765618322844e-10, 0.5772448425394644, 0.021467757234461603, 0.02065361499729097, 9237.611246095104, 97.45967757952462, 1912.7417563346064, 44.64792658279896, 0.01041204738474301, 0.000352000686871265 -6.191371302929103e-10, 0.5782539306466206, 0.021254147709740597, 0.020483850739173654, 9107.975355779243, 96.45749990768739, 1749.6733772995485, 43.23283186168793, 0.009448405476001292, 0.00033139208602521534 -6.253596140144469e-10, 0.5780418027300006, 0.021042663652927264, 0.02027259201094195, 9032.176674765706, 96.26434088090093, 1546.265440240657, 40.30635890963839, 0.008826981541765467, 0.00031522036266125086 -6.316446352608231e-10, 0.5785736295211894, 0.020833283915087195, 0.020089340238594593, 8753.96910794863, 94.6945710381685, 1280.3019784796945, 36.99159355518723, 0.00724739508377976, 0.00027634134545126323 -6.379928225498765e-10, 0.5784642538322843, 0.020625987557723147, 0.019885686459486955, 8629.803193335647, 94.36735032130738, 1154.63908365151, 35.25520583339059, 0.006546905923014836, 0.0002589220701989955 -6.444048107162068e-10, 0.5778823998309648, 0.02042075385068113, 0.01966801641662558, 8623.50196690964, 94.39119306014149, 1059.1502140460489, 34.08734722065474, 0.006054594616777095, 0.0002469046687081223 -6.508812409746611e-10, 0.5751914700037796, 0.02021756227007734, 0.019381644291775326, 8502.547032280456, 93.43154161052648, 1076.6750202475994, 34.29805855363275, 0.006304229245587982, 0.0002549971943677087 -6.574227609844566e-10, 0.5759369333011319, 0.020016392496245726, 0.019213660452751618, 8220.879555709822, 92.21236600527163, 1183.275286358903, 36.01841096574153, 0.007080428145357753, 0.0002801171674086077 -6.640300249139485e-10, 0.5769509144138034, 0.01981722441170597, 0.019055969154295423, 7965.077403679278, 90.52460396074218, 1478.022145088511, 39.77025308189336, 0.009408686001937712, 0.0003465437609886113 -6.707036935060482e-10, 0.577118015105115, 0.019620038099151693, 0.0188718215468921, 7953.752863589031, 90.71519793513636, 1852.3984727525167, 44.22218365534976, 0.011252043164312272, 0.00039301156759626824 -6.774444341443e-10, 0.5757523377405839, 0.01942481383945864, 0.018639830276573382, 7884.450885109338, 90.02526931306933, 2185.020467430291, 48.43392246700388, 0.013546451256573375, 0.00045809975045043894 -6.842529209196194e-10, 0.5769860076463694, 0.019231532109712787, 0.018493900321201934, 7631.8205484206865, 88.57301762714937, 2539.574973967372, 51.62236384025239, 0.016438818960202623, 0.0005349151729436704 -6.91129834697706e-10, 0.57845952239549, 0.019040173581257935, 0.018356639851102453, 7602.125303713988, 88.29503097944543, 2826.359944463728, 54.44773055620663, 0.018085978544159997, 0.0005835138832817013 -6.9807586318713e-10, 0.5787190090655621, 0.018850719117762836, 0.01818213896879982, 7490.732384588685, 87.62572462131948, 2985.9334258937865, 55.84940329729279, 0.019599283910849988, 0.0006225378583616453 -7.05091701008106e-10, 0.5788390487934849, 0.018663149773307488, 0.018004955906578628, 7313.957653592502, 86.7354734027981, 3025.781673030198, 56.33326418679823, 0.019784266537672637, 0.000637599765803666 -7.12178049761956e-10, 0.5793710445187742, 0.018477446790488513, 0.017842184783574907, 7322.607427976398, 86.72019702482001, 2778.1180145782714, 54.18269069401645, 0.018898536342721352, 0.0006149447180153205 -7.193356181012722e-10, 0.5797278412500374, 0.018293591598543355, 0.017675528738411637, 6913.762929538355, 84.29256829911903, 2537.241814184889, 51.94453427214205, 0.017962748709489298, 0.0006003036376468966 -7.265651218007823e-10, 0.580421431331919, 0.018111565811493174, 0.017520588810910905, 6825.765359250261, 83.64947483845754, 2125.5949554552817, 48.15685063522208, 0.015425011419489964, 0.0005362923983674231 -7.338672838289307e-10, 0.5809978409534856, 0.017931351226304192, 0.017363480362905397, 6555.6581048247135, 82.39139454563981, 1806.1103783408535, 44.426165009510704, 0.013501679009336716, 0.0004892789817753431 -7.412428344201763e-10, 0.5789128603672831, 0.017752929821067333, 0.017129020590151575, 6508.61413860928, 81.65421161342717, 1530.495209996529, 41.53726011408903, 0.011739298461060947, 0.00044684571763288207 -7.486925111480169e-10, 0.5807386674846756, 0.017576283753196024, 0.017012065653076256, 6418.234640749739, 81.06025758193876, 1344.1370126113618, 38.71567519399834, 0.010043263945779975, 0.00039670644864411213 -7.562170589987507e-10, 0.5800094819679792, 0.017401395357641836, 0.016821643990631966, 6331.6946662038645, 80.48253037302385, 1491.5842415827838, 40.38141650596367, 0.011715538007768481, 0.0004474738460926948 -7.638172304459743e-10, 0.5782092295766281, 0.017228247145127988, 0.016602574155535753, 6040.4321416174935, 78.99726487912417, 1695.6585907670947, 42.960997947812956, 0.013823063817386627, 0.0005150080860127682 -7.714937855258331e-10, 0.5786747790282124, 0.017056821800400353, 0.016450608636845054, 5826.154113155153, 77.30359556220425, 2084.7837556404024, 47.352045830772695, 0.017140186771994154, 0.0006136483751792636 -7.792474919130274e-10, 0.5786614627533209, 0.016887102180495873, 0.016286546212157547, 5681.8590767094765, 76.46660005054838, 2619.0901307416407, 53.27592507867457, 0.02200482935141593, 0.000761446497074403 -7.870791249975803e-10, 0.5799137256532573, 0.016719071313028255, 0.016159384334783394, 5592.981372208726, 75.82370077650285, 3288.9166955918085, 59.111285277904685, 0.0280781495427234, 0.0009393257194318495 -7.949894679623799e-10, 0.5806119026261397, 0.016552712394490663, 0.016017855009551104, 5472.651162790698, 74.928958602194, 3949.818882332523, 64.44927562645472, 0.03582318165396904, 0.0011632509174815944 -8.029793118614991e-10, 0.5809823647544003, 0.016388008788575336, 0.01586859159375547, 5280.467198889275, 73.79385341009592, 4264.988892745575, 67.55754742816565, 0.03963711057254274, 0.0012934378455997809 -8.11049455699303e-10, 0.5817488155235502, 0.016224944024509913, 0.0157314205065644, 5212.629526784682, 73.37530774167392, 4676.711361795674, 70.26867662241747, 0.04433796721564227, 0.0014298675615017928 -8.192007065103511e-10, 0.5819230535452956, 0.01606350179541032, 0.01557955359192765, 5045.472058313086, 72.00366616837586, 4746.8169038528295, 70.87197515379845, 0.04642998356596498, 0.0015120335575906356 -8.274338794401033e-10, 0.5828795405329966, 0.015903665956650017, 0.015449885061015635, 4754.7705657757715, 70.06039443543303, 4489.029387944002, 68.83838328173289, 0.04406217169171844, 0.0014709774950951919 -8.357497978264359e-10, 0.5827603410368657, 0.015745420524245542, 0.015293026889078716, 4782.566817077404, 69.96022572092372, 4165.335647344673, 66.75825306773184, 0.0407386947201747, 0.0013773931309600082 -8.441492932819778e-10, 0.5832800079720074, 0.015588749673258026, 0.015154358611338396, 4671.7613097304165, 69.40693378532178, 3510.5813953488373, 61.62659498384058, 0.03601271214811765, 0.0012461721977905676 -8.526332057772739e-10, 0.5836768350779183, 0.015433637736210684, 0.015013776107013148, 4553.124609510586, 68.50456474198937, 2980.2614832812683, 56.9855295028291, 0.030862720891363216, 0.0011042185772915402 -8.61202383724784e-10, 0.5838328573754975, 0.015280069201522025, 0.01486835855221142, 4276.980562304755, 66.27231275348133, 2463.1249103320606, 52.309843057176494, 0.028052541829640593, 0.0010348654405636416 -8.698576840637264e-10, 0.5837318443873853, 0.015128028711954645, 0.014717867892698524, 4306.891704269349, 66.6416408541285, 2067.9741987735742, 48.5335955024813, 0.02319045118889747, 0.0008900746001524405 -8.785999723457736e-10, 0.5812790446354094, 0.014977501063079478, 0.014510195473084223, 4089.4057618882334, 64.91990633166199, 2058.309961818813, 48.339321863067, 0.023454419044044238, 0.0009175175769403318 -8.874301228216105e-10, 0.5811843502813222, 0.014828471201755306, 0.014363475208766815, 4069.4831655675116, 64.90390461622852, 2348.393405067685, 51.29014457892239, 0.028693958102837962, 0.001084452277853452 -8.963490185283603e-10, 0.5823633804782643, 0.014680924224623413, 0.014249402852495374, 3858.559875043387, 63.40694066864141, 2953.940645609164, 57.1056858324181, 0.03569674469916246, 0.0013272761796816362 -9.053575513778913e-10, 0.5823723659429287, 0.014534845376617212, 0.01410783541278572, 3749.0746268656712, 62.11219987357015, 3884.3623741756332, 64.73513440029585, 0.050358498737409746, 0.0018100967840493421 -9.144566222460106e-10, 0.5829894576898422, 0.014390220049486696, 0.013982258589560764, 3636.7847159551084, 61.22477804549306, 4853.400555362721, 71.96248637058949, 0.06378234999134863, 0.0022594642372782505 -9.236471410625534e-10, 0.5825645482890798, 0.014247033780337577, 0.013833042478287792, 3505.0437348143, 59.84944665730586, 5815.6122874002085, 78.78943726921511, 0.07667931171601396, 0.0027084571811122147 -9.329300269023777e-10, 0.5840507536331833, 0.014105272250184969, 0.01373033797751234, 3440.715376605345, 59.578261528759874, 6672.941686914266, 84.38636331236069, 0.08682292798771808, 0.0030902328147362117 -9.423062080772758e-10, 0.5850233531028101, 0.013964921282521438, 0.013616354059849903, 3248.927837556404, 58.19610708248198, 7180.322457480042, 87.58811302066027, 0.09834666755351175, 0.0035520561944728055 -9.517766222288061e-10, 0.5851466939851487, 0.013825966841899335, 0.013483710031808285, 3147.901076015272, 57.070998974827205, 7505.209302325581, 89.09989168160878, 0.1084238170675303, 0.003909591873012023 -9.613422164220603e-10, 0.5864702716356646, 0.013688395032527206, 0.013379738825992641, 3020.9616336920053, 56.06178101455682, 7245.986810135369, 87.76111433809754, 0.11070516677219362, 0.004052437756206878 -9.710039472403723e-10, 0.5864067713304041, 0.013552192096880172, 0.013245172864736589, 2975.8930926761536, 55.50771934896844, 6734.225026032627, 84.86880251951739, 0.10366654490113454, 0.0038240942067708267 -9.807627808809788e-10, 0.5876016994479974, 0.013417344414324154, 0.01314010045608965, 2928.9119518685643, 55.29191724349004, 5995.988545643873, 80.75277985528503, 0.09643574549593698, 0.003598557006581921 -9.906196932516417e-10, 0.5879303439383797, 0.013283838499753765, 0.013016629038557019, 2815.860465116279, 54.535672131951586, 5044.974661575841, 73.95961964764393, 0.08337480673768596, 0.003175624918247139 -1.000575670068241e-09, 0.5888044604807128, 0.01315166100224378, 0.012906269822345908, 2737.1324771491386, 53.70993417245492, 4288.861506421381, 68.30913916584382, 0.07305521333852232, 0.0028625418847804886 -1.0106317069533489e-09, 0.5884842435596351, 0.013020798703713992, 0.012770900333382056, 2681.720930232558, 52.94600145211574, 4011.6876084692817, 66.43276594821805, 0.0700793384821887, 0.0027707986566655575 -1.0207888095357943e-09, 0.5848430306061603, 0.01289123851760739, 0.012565596461623509, 2613.076709475877, 52.18163748412006, 4205.483061437, 68.24459094308168, 0.07003003031606726, 0.002833990712376606 -1.0310479935512293e-09, 0.58529372152017, 0.012762967487581448, 0.012450152248924777, 2334.5310193219943, 49.53751046155044, 5133.4321416174935, 74.69650499442731, 0.09739968900806702, 0.003955043957482669 -1.0414102849437037e-09, 0.5868525469203367, 0.01263597278621248, 0.012359097811776971, 2352.1797986810134, 49.3337632997827, 6629.513710517182, 83.78834220512313, 0.1265251267950927, 0.0050474073842564394 -1.0518767199682633e-09, 0.5869790195400427, 0.012510241713712856, 0.012238758629061871, 2352.190211732038, 49.46523818064523, 8566.667129468933, 95.36421168620367, 0.16067607491348276, 0.0064291096243517 -1.0624483452945776e-09, 0.5883001050660626, 0.012385761696660986, 0.012144250084508958, 2185.1649311581627, 47.70454597882853, 10568.875390489413, 105.78811185341473, 0.22115897540535212, 0.008801793853401874 -1.0731262181116082e-09, 0.5882413266125379, 0.012262520286743966, 0.012022210529941235, 2033.2158972578968, 45.93238620779573, 11956.689691079484, 111.91653277742532, 0.26564569857043596, 0.0108464157863694 -1.0839114062333327e-09, 0.5887508956214, 0.012140505159512685, 0.011912896897773865, 2114.6476917736895, 46.66210784165575, 12696.782714335299, 115.40891337182194, 0.2625356395655608, 0.01082006355002557 -1.0948049882055269e-09, 0.5895402340806787, 0.012019704113149374, 0.011810172754506942, 1964.7285664699757, 45.35715416039706, 12812.410274210344, 116.34685094917548, 0.28936747143012165, 0.012119805928851335 -1.1058080534136223e-09, 0.5907083397031141, 0.011900105067247395, 0.011715825425068232, 1906.0735855605697, 44.440144176627406, 12129.090940645608, 113.59977578919067, 0.28449883742831805, 0.011930092733329607 -1.1169217021916486e-09, 0.5912213954427857, 0.011781696061603142, 0.011609324140596502, 1834.7896563693164, 43.83161351844903, 11194.920166608816, 109.14247492791789, 0.27765792018669533, 0.011778647269578474 -1.128147045932268e-09, 0.5901714243864992, 0.011664465255020028, 0.01147339693771463, 1738.7098229781327, 42.66485880700729, 11122.074279763974, 108.62746301113742, 0.2553746600640163, 0.011467187817671334 -1.1394852071979186e-09, 0.5908200442238961, 0.01154840092412431, 0.01137171755248398, 1583.6716417910447, 40.97141340517691, 12259.250607427975, 113.72664328367395, 0.32016589845006, 0.014451802102902932 -1.1509373198330733e-09, 0.5906002786123183, 0.011433491462192727, 0.01125437846633924, 1601.616105518917, 41.06560476214959, 14595.986115931968, 124.1370769917998, 0.39276548062133404, 0.01769943169071254 -1.1625045290776268e-09, 0.590677805507453, 0.011319725377991804, 0.011143857188623523, 1549.9197038065483, 40.47375639364707, 18322.123915307184, 138.88079811368027, 0.5557435356838124, 0.02470433618391924 -1.1741879916814216e-09, 0.592073123668846, 0.011207091294628706, 0.011059034555617112, 1499.1386092791854, 39.89943101883182, 21912.375216938563, 151.60351177681022, 0.6297032364662322, 0.028931376901843508 -1.1859888760199282e-09, 0.5921962603130255, 0.011095577948413498, 0.010951271451188105, 1433.3950017355087, 39.39809635666403, 24532.57480041652, 160.47562182332703, 0.7319702480096729, 0.0341528916902918 -1.1979083622110831e-09, 0.5937592992409984, 0.010985174187732767, 0.010870919657962077, 1470.0565775772304, 39.02490771831203, 26205.42589378688, 165.7726578969316, 0.7740064329256464, 0.0360236191245588 -1.2099476422333047e-09, 0.5940468606968569, 0.010875868971934434, 0.010767963586255829, 1233.638088626634, 36.29988100033755, 26797.818812912185, 167.63108657730467, 0.943870376929199, 0.04547319104447396 -1.2221079200446945e-09, 0.5951203191443921, 0.010767651370223645, 0.010680083361968143, 1225.6549809094065, 36.14975696798184, 26654.75564040264, 167.6163606561047, 0.9508975782670601, 0.046586782780240435 -1.234390411703435e-09, 0.5947627772045, 0.01066051056056968, 0.010567461469437236, 1210.764665046859, 36.05877611557471, 26333.997223186394, 166.18063297753324, 0.9500960449810729, 0.04675230326499962 -1.2467963454893992e-09, 0.5946755042927604, 0.010554435828623714, 0.010460777459826492, 1092.2347333101932, 34.425774955061044, 25453.02637972926, 163.8748718390673, 0.9658927677256465, 0.04969134027856357 -1.2593269620269806e-09, 0.5957667468935169, 0.010449416566647362, 0.010375694191262125, 1041.8833738285316, 33.55766121426623, 24517.974314474144, 161.01871222167273, 0.9934019478866505, 0.051596263546925154 -1.271983514409161e-09, 0.5970652942739055, 0.010345442272451868, 0.010294842727477682, 1052.4859423811176, 34.28577048308645, 23885.182228392918, 158.89561910766162, 0.8837546287170633, 0.04742840566589401 -1.2847672683228207e-09, 0.5976909624653584, 0.010242502548347871, 0.01020308677619031, 1002.0537429133402, 32.47298292309528, 22535.924678930925, 154.54150031971696, 0.9893136615028234, 0.05197314859242925 -1.2976795021753112e-09, 0.5972893052155368, 0.010140587100105606, 0.010094775369180365, 1006.9160013884067, 32.895045198503574, 22030.818118708787, 152.63741966271317, 0.9874399633914812, 0.05194839131489955 -1.3107215072222989e-09, 0.597767243985373, 0.010039685735925454, 0.010002326812806541, 915.0249913224575, 31.33648047687459, 21209.801457827147, 150.02066038440458, 0.9607726132835948, 0.05310768758337278 -1.323894587696895e-09, 0.5987310479728758, 0.009939788365418731, 0.00991876727376405, 864.2040958000694, 30.672396453487792, 20007.500520652553, 146.41550286546655, 0.9681556274569953, 0.05463435942125302 -1.3372000609400796e-09, 0.5995535470392663, 0.009840884998598646, 0.009833562778895676, 855.7427976397084, 30.401598680995242, 19603.360638667127, 144.34901926003124, 0.9764237066967213, 0.05524133391974118 -1.3506392575324419e-09, 0.5994621713552392, 0.009742965744881248, 0.009734232653592129, 813.0013884068032, 30.01663891232989, 18643.43769524471, 141.22167788535617, 0.9276920270599444, 0.054341011135331595 -1.3642135214272401e-09, 0.5985454988752335, 0.009646020812096362, 0.009622638083561294, 746.0937174592154, 28.738585256424585, 18121.90454703228, 139.30217318106605, 1.0998247736110323, 0.06492858091058354 -1.3779242100848e-09, 0.6007870450271008, 0.009550040505508341, 0.009562567233164471, 663.0312391530719, 27.073395812991915, 17142.771954182575, 135.2487635648379, 1.0836453055726352, 0.06669841408020052 -1.3917726946082652e-09, 0.6014839704682703, 0.009455015226846566, 0.009478399307807375, 736.2315168344325, 27.96012308924207, 16645.275945852132, 133.4530780991876, 0.9229295769947128, 0.05625680647060416 -1.4057603598807097e-09, 0.6019721514060951, 0.009360935473345608, 0.009391702979826697, 697.1777160708087, 27.27565712702833, 15435.57827143353, 129.08300325204118, 0.9394610323964148, 0.05765439053756752 -1.419888604703631e-09, 0.6027846808569759, 0.00926779183679491, 0.009310803324374162, 637.0494041420803, 26.60781281655717, 14802.535925026032, 126.52851091739745, 0.8953709521567955, 0.058384328284785604 -1.4341588419368332e-09, 0.6026291009514585, 0.009175575002597946, 0.00921577937817392, 589.5871803771838, 25.654595658001785, 14434.123221103782, 125.05949295793668, 1.0618403514367134, 0.06907238045818391 -1.4485724986397158e-09, 0.6030628024457724, 0.009084275748840753, 0.009130646277368029, 536.6980215203052, 24.625265060056275, 13883.267268309615, 122.97045471043191, 1.0548362473106565, 0.07166035179334895 -1.4631310162139839e-09, 0.6044860397075766, 0.008993884945369703, 0.009061127334624077, 562.9452620617841, 25.40224813562041, 13027.87608469282, 119.10551588951364, 0.944041672046378, 0.06438359750716491 -1.4778358505477926e-09, 0.6035116400070953, 0.008904393552878464, 0.008956506672154998, 570.9232905241234, 24.941465664148055, 12488.575841721626, 117.16835817864128, 0.8738235117721207, 0.05991892986263024 -1.4926884721613379e-09, 0.6038751035443021, 0.008815792622004054, 0.00887272736923343, 495.6689806780052, 23.759709098945315, 11895.08261020479, 114.13114119203054, 0.9526471992543925, 0.06821307375797614 -1.5076903663539138e-09, 0.6071174458855236, 0.008728073292431875, 0.008831605422371049, 512.1279185468009, 24.077351341506677, 11399.529677195418, 111.97977640094028, 0.839161907863425, 0.06098394747792023 -1.5228430333524455e-09, 0.6062002431488687, 0.008641226792009668, 0.00873051965576641, 460.04859423811183, 22.909409146048144, 10709.407150295036, 109.0760874330619, 0.8427963494476273, 0.06412932531918272 -1.5381479884615152e-09, 0.60793586492057, 0.008555244435870269, 0.00866839565746391, 415.4307763508041, 21.683317590135566, 10270.444984380423, 106.26172883790089, 0.9197476958526316, 0.07145712870007224 -1.5536067622148969e-09, 0.607697813423301, 0.008470117625563104, 0.008578782551724968, 378.700867754252, 20.89976242497364, 9841.933356473446, 104.32193749891033, 1.1323555183485408, 0.08796650338524525 -1.5692209005286139e-09, 0.610224516376923, 0.00838583784819432, 0.008528734384247562, 381.0118130278838, 20.70563594639063, 9275.457132939951, 101.78675192312626, 1.0345928584673185, 0.08085263616300195 -1.5849919648555344e-09, 0.6082069055217229, 0.008302396675575472, 0.008415954080711401, 376.0891819969917, 20.607402719865732, 8812.533148212426, 98.83049555571182, 0.8774899713852518, 0.0713945068040351 -1.6009215323415195e-09, 0.6115854365673558, 0.008219785763380692, 0.008378496136751021, 359.6353696633113, 20.122964582167, 8301.6518569941, 97.37221443002053, 0.9800136724017913, 0.07898171695712884 -1.6170111959831424e-09, 0.6142870418288007, 0.00813799685031223, 0.008331769347474796, 315.5737591114197, 18.837528547480975, 7926.045123221103, 94.7942766034896, 1.0013215214560696, 0.08533938878683045 -1.6332625647869927e-09, 0.6105061978735955, 0.0080570217572743, 0.008198097571990526, 314.4033321763277, 19.224897082264768, 7500.663658451926, 92.22438040750436, 1.0393429905793479, 0.08876000198261938 -1.6496772639305801e-09, 0.6101415824253196, 0.007976852386555155, 0.008111677175561863, 319.39592734004395, 19.60757845680979, 7341.605345366192, 91.82807116908101, 0.87215546748432, 0.07731232769092775 -1.6662569349248573e-09, 0.6124746753622068, 0.007897480721017291, 0.008061672044023405, 285.78306143700104, 18.08913869046835, 6720.543908365152, 87.52403150926521, 1.0301112171493358, 0.09092097963475786 -1.6830032357783734e-09, 0.615241977195925, 0.007818898823295728, 0.008017517079587054, 289.177368969108, 18.676793917342774, 6467.818812912182, 86.1462778481335, 0.911639845953131, 0.08338285925599645 -1.6999178411630802e-09, 0.6131865051048203, 0.00774109883500423, 0.007911222474999426, 242.15779243318295, 17.69478790257297, 5975.014925373135, 83.23451852823362, 0.9994863175522324, 0.09819693506223756 -1.7170024425818043e-09, 0.6143414833683057, 0.007664072975949463, 0.007847256329407479, 224.23160939488602, 16.98911385525887, 5710.637625824366, 81.63554602117655, 1.1552198019489681, 0.11418973798730464 -1.7342587485374001e-09, 0.6176547214015712, 0.007587813543352952, 0.007811072908447886, 229.47784334143236, 17.490137053035955, 5321.3391183616795, 79.08009156316348, 0.8807799686982775, 0.09126299899582709 -1.7516884847036046e-09, 0.613727951381251, 0.007512312911080785, 0.0076841875214758186, 220.64977438389442, 16.320239753634304, 5221.342936480389, 77.65730528108486, 1.0537992585936233, 0.1051797824413345 -1.7692933940976106e-09, 0.6172432850443558, 0.007437563528880976, 0.007651302088735933, 188.98507462686567, 15.673915968609911, 4846.055883373828, 75.98647324771805, 1.1541502220233884, 0.12395198055092563 -1.7870752372543705e-09, 0.6210230495259008, 0.007363557921628429, 0.007621555393650287, 194.35260904778434, 15.451461324532369, 4706.9173897952105, 74.94719881493097, 1.003098559435399, 0.10741138946782941 -1.805035792402655e-09, 0.6400451756114651, 0.007290288688577403, 0.007776837233485063, 180.25442554668518, 14.857509025853386, 4409.272821936828, 72.7854874137913, 1.1595293806771054, 0.12317898294506015 -1.8231768556428823e-09, 0.6182270941046347, 0.007217748502621411, 0.007437004420599897, 155.97959041999303, 14.4657730787917, 4076.835820895522, 69.82953658090878, 0.9754798913848411, 0.11783310152259556 -1.84150024112673e-09, 0.6245133436830408, 0.007145930109560502, 0.007437869842405078, 160.6629642485248, 14.154046621071842, 3989.8833738285316, 69.4774540852748, 1.1448780495290698, 0.1292414845652645 -1.860007781238556e-09, 0.6217625338465699, 0.007074826327375822, 0.007331426676323603, 159.35265532801105, 14.75287581022727, 3680.5741062131206, 67.53832907162332, 0.8972305174367942, 0.10918744350285654 -1.878701326778642e-09, 0.6384247559767222, 0.007004430045511386, 0.007452984564889887, 143.6039569593891, 13.29631851608639, 3543.6362374175633, 66.66606154995536, 0.8935742172578933, 0.11053735289550325 -1.897582747148276e-09, 0.6202051057411267, 0.006934734224163017, 0.0071682536487873965, 135.3119055883374, 12.924338601599256, 3349.9555709822976, 64.63779412246137, 0.9709994987681356, 0.12002235318410412 -1.9166539305367008e-09, 0.6265234922281538, 0.00686573189357433, 0.007169225363506401, 124.46407497396737, 12.269308253770163, 3151.5588337382856, 62.1404953815281, 0.993593715994068, 0.12788508120969153 -1.9359167841099335e-09, 0.6227710181281332, 0.006797416153339761, 0.007055379657088446, 108.54714798102513, 11.949854731972174, 2971.707046164526, 61.239635480916064, 1.0523404837781152, 0.1468696716104045 -1.95537323420149e-09, 0.6283167576526549, 0.006729780171714492, 0.0070473769838584836, 123.43570519495543, 12.96885704436362, 2773.463727872267, 59.19912391351525, 1.0545382983684768, 0.1398064692335227 -1.9750252265050225e-09, 0.636107971013765, 0.006662817184931264, 0.007063769194480512, 101.53332176327666, 12.263196039013962, 2606.9906282540783, 57.48051297392814, 1.0937468659281957, 0.1605552164379071 -1.9948747262688914e-09, 0.634749007063621, 0.006596520496523989, 0.006978542857004066, --, 11.02669444036391, --, 55.63627727335115, --, -- -2.0149237184926994e-09, 0.6031970373841334, 0.006530883476658078, 0.006565681325456984, --, 10.2190007533557, --, 49.552719989048896, --, -- -2.035174208125791e-09, 0.6157967206590592, 0.006465899561467454, 0.006636126439430265, --, 7.7534688410909, --, 36.707659602815056, --, -- diff --git a/Tests/Unit/gui2/libtestmachinery/CMakeLists.txt b/Tests/Unit/gui2/libtestmachinery/CMakeLists.txt deleted file mode 100644 index 6bc5f9012057dac09d452afd8ef92e65ad170840..0000000000000000000000000000000000000000 --- a/Tests/Unit/gui2/libtestmachinery/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ -set(library_name darefltestmachinery) - -file(GLOB source_files "*.cpp") -file(GLOB include_files "*.h") - -find_package(Qt5 COMPONENTS Widgets Core Test REQUIRED) - -if(WIN32) - add_definitions(-DGTEST_LINKED_AS_SHARED_LIBRARY) -endif() - -add_library(${library_name} STATIC ${source_files} ${include_files}) -target_link_libraries(${library_name} gtest gmock Qt5::Core Qt5::Test MVVM::View) -target_include_directories(${library_name} PUBLIC - $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}> $<BUILD_INTERFACE:${DAREFL_AUTOGEN_DIR}>) - -target_compile_features(${library_name} PUBLIC cxx_std_17) diff --git a/Tests/Unit/gui2/libtestmachinery/folderbasedtest.cpp b/Tests/Unit/gui2/libtestmachinery/folderbasedtest.cpp deleted file mode 100644 index 8cd4db462b4e9e4c570b14842d91f0b22c2e2414..0000000000000000000000000000000000000000 --- a/Tests/Unit/gui2/libtestmachinery/folderbasedtest.cpp +++ /dev/null @@ -1,42 +0,0 @@ -// ************************************************************************** // -// -// Reflectometry simulation software prototype -// -//! @license GNU General Public License v3 or higher (see COPYING) -//! @authors see AUTHORS -// -// ************************************************************************** // - -#include "folderbasedtest.h" -#include "mvvm/utils/fileutils.h" -#include "test_utils.h" - -FolderBasedTest::FolderBasedTest(const std::string& test_dir) : m_test_dir(test_dir) -{ - TestUtils::CreateTestDirectory(m_test_dir); -} - -std::string FolderBasedTest::testDir() const -{ - return m_test_dir; -} - -//! Return full path to the test folder. Located in CMAKE_BINARY_DIR/test_output/<m_test_dir>. - -std::string FolderBasedTest::testPath() const -{ - return TestUtils::TestDirectoryPath(m_test_dir); -} - -//! Creates an empty directory in main test folder. -//! Remove recursively previous one with the same name, if exist. - -std::string FolderBasedTest::createEmptyDir(const std::string& subdir) const -{ - auto path = ModelView::Utils::join(testPath(), subdir); - ModelView::Utils::remove_all(path); - ModelView::Utils::create_directory(path); - return path; -} - -FolderBasedTest::~FolderBasedTest() = default; diff --git a/Tests/Unit/gui2/libtestmachinery/folderbasedtest.h b/Tests/Unit/gui2/libtestmachinery/folderbasedtest.h deleted file mode 100644 index c8a127cbe9fde6a6fe261e1eb8c6d25af10c227e..0000000000000000000000000000000000000000 --- a/Tests/Unit/gui2/libtestmachinery/folderbasedtest.h +++ /dev/null @@ -1,33 +0,0 @@ -// ************************************************************************** // -// -// Reflectometry simulation software prototype -// -//! @license GNU General Public License v3 or higher (see COPYING) -//! @authors see AUTHORS -// -// ************************************************************************** // - -#ifndef BORNAGAIN_TESTS_UNITTESTS_GUI2_LIBTESTMACHINERY_FOLDERBASEDTEST_H -#define BORNAGAIN_TESTS_UNITTESTS_GUI2_LIBTESTMACHINERY_FOLDERBASEDTEST_H - -#include <gtest/gtest.h> -#include <string> - -//! Convenience class which creates a directory on disk for test content. - -class FolderBasedTest : public ::testing::Test { -public: - FolderBasedTest(const std::string& test_dir); - ~FolderBasedTest(); - - std::string testDir() const; - - std::string testPath() const; - - std::string createEmptyDir(const std::string& subdir) const; - -protected: - std::string m_test_dir; //! main directory of given test -}; - -#endif // BORNAGAIN_TESTS_UNITTESTS_GUI2_LIBTESTMACHINERY_FOLDERBASEDTEST_H diff --git a/Tests/Unit/gui2/libtestmachinery/google_test.h b/Tests/Unit/gui2/libtestmachinery/google_test.h deleted file mode 100644 index 8c07c25edc9008fc7e40e77c45c20acc1668c54e..0000000000000000000000000000000000000000 --- a/Tests/Unit/gui2/libtestmachinery/google_test.h +++ /dev/null @@ -1,15 +0,0 @@ -// ************************************************************************** // -// -// Reflectometry simulation software prototype -// -//! @license GNU General Public License v3 or higher (see COPYING) -//! @authors see AUTHORS -// -// ************************************************************************** // - -#ifndef BORNAGAIN_TESTS_UNITTESTS_GUI2_LIBTESTMACHINERY_GOOGLE_TEST_H -#define BORNAGAIN_TESTS_UNITTESTS_GUI2_LIBTESTMACHINERY_GOOGLE_TEST_H - -#include <gtest/gtest.h> - -#endif // BORNAGAIN_TESTS_UNITTESTS_GUI2_LIBTESTMACHINERY_GOOGLE_TEST_H diff --git a/Tests/Unit/gui2/libtestmachinery/test_utils.cpp b/Tests/Unit/gui2/libtestmachinery/test_utils.cpp deleted file mode 100644 index cacc9445978feb56eb99f4ea1f1b818ec57474b5..0000000000000000000000000000000000000000 --- a/Tests/Unit/gui2/libtestmachinery/test_utils.cpp +++ /dev/null @@ -1,73 +0,0 @@ -// ************************************************************************** // -// -// Reflectometry simulation software prototype -// -//! @license GNU General Public License v3 or higher (see COPYING) -//! @authors see AUTHORS -// -// ************************************************************************** // - -#include "test_utils.h" -#include "mvvm/utils/fileutils.h" -#include "testconfig.h" // this file is auto generated by the build system in build directory -#include <QFile> -#include <QString> -#include <QTextStream> -#include <stdexcept> -#include <string> - -using namespace ModelView; - -std::string TestUtils::TestOutputDir() -{ - return TestConfig::TestOutputDir(); // defined in auto-generated testconfig.h -} - -std::string TestUtils::CreateTestDirectory(const std::string& test_sub_dir) -{ - std::string result = TestDirectoryPath(test_sub_dir); - Utils::create_directory(result); - return result; -} - -std::string TestUtils::TestDirectoryPath(const std::string& test_sub_dir) -{ - return TestOutputDir() + std::string("/") + test_sub_dir; -} - -std::string TestUtils::TestFileName(const std::string& test_sub_dir, const std::string& file_name) -{ - - return TestDirectoryPath(test_sub_dir) + std::string("/") + file_name; -} - -std::string TestUtils::CreateTestFile(const std::string& dirname, const std::string& fileName, - const std::string& content) -{ - std::string filename = dirname.empty() ? fileName : dirname + "/" + fileName; - - QFile file(QString::fromStdString(filename)); - if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) - throw std::runtime_error("TestFileUtils::createTestFile() -> Error. " - "Can't create file"); - - QTextStream out(&file); - if (content.empty()) - out << "Test file " << 42 << "\n"; - else - out << QString::fromStdString(content); - file.close(); - - return filename; -} - -std::string TestUtils::CreateEmptyFile(const std::string& dirname, const std::string& fileName) -{ - std::string filename = dirname.empty() ? fileName : dirname + "/" + fileName; - - QFile file(QString::fromStdString(filename)); - if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) - throw std::runtime_error("TestFileUtils::createTestFile() -> Error. " - "Can't create file"); - return filename; -} diff --git a/Tests/Unit/gui2/libtestmachinery/test_utils.h b/Tests/Unit/gui2/libtestmachinery/test_utils.h deleted file mode 100644 index 805ad3d2f0ac57458ef888e7eafccc92540afe85..0000000000000000000000000000000000000000 --- a/Tests/Unit/gui2/libtestmachinery/test_utils.h +++ /dev/null @@ -1,63 +0,0 @@ -// ************************************************************************** // -// -// Reflectometry simulation software prototype -// -//! @license GNU General Public License v3 or higher (see COPYING) -//! @authors see AUTHORS -// -// ************************************************************************** // - -#ifndef BORNAGAIN_TESTS_UNITTESTS_GUI2_LIBTESTMACHINERY_TEST_UTILS_H -#define BORNAGAIN_TESTS_UNITTESTS_GUI2_LIBTESTMACHINERY_TEST_UTILS_H - -#include "mvvm/model/customvariants.h" -#include <QString> -#include <memory> - -//! @file Tests/Unit/gui2/libtestmachinery/test_utils.h -//! @brief Collection of utility functions for various unit tests. - -class QJsonObject; -class QJsonArray; - -namespace ModelView { -class SessionModel; -} - -//! Various common utils for unit tests. - -namespace TestUtils { - -//! Returns full path to the main test folder, as defined by CMake at compile time. -//! Should point to CMAKE_BINARY_DIR/test_output -std::string TestOutputDir(); - -//! Creates test directory in main test folder and returns full path. -//! If directory exists, will do nothing. -std::string CreateTestDirectory(const std::string& test_sub_dir); - -//! Returns full path to the main test folder in CMAKE_BINARY_DIR. -std::string TestDirectoryPath(const std::string& test_sub_dir); - -//! Returns full path to the file in test directory. -std::string TestFileName(const std::string& test_sub_dir, const std::string& file_name); - -//! Helper function to create test file in a given directory (directory should exist). -//! Returns full path of the file. -std::string CreateTestFile(const std::string& dirname, const std::string& fileName, - const std::string& content = {}); - -//! Helper function to create empty file in a given directory (directory should exist). -//! Returns full path of the file. -std::string CreateEmptyFile(const std::string& dirname, const std::string& fileName); - -template <typename T = std::string, typename... Args> std::vector<T> toStringVector(Args&&... args) -{ - std::vector<T> v; - (v.push_back(std::string(args)), ...); - return v; -} - -} // namespace TestUtils - -#endif // BORNAGAIN_TESTS_UNITTESTS_GUI2_LIBTESTMACHINERY_TEST_UTILS_H diff --git a/Tests/Unit/gui2/libtestmachinery/widgetbasedtest.cpp b/Tests/Unit/gui2/libtestmachinery/widgetbasedtest.cpp deleted file mode 100644 index 54c52b64ae8cd3d9af96504ff8d699c685941499..0000000000000000000000000000000000000000 --- a/Tests/Unit/gui2/libtestmachinery/widgetbasedtest.cpp +++ /dev/null @@ -1,33 +0,0 @@ -// ************************************************************************** // -// -// Reflectometry simulation software prototype -// -//! @license GNU General Public License v3 or higher (see COPYING) -//! @authors see AUTHORS -// -// ************************************************************************** // - -#include "widgetbasedtest.h" -#include <QApplication> - -QApplication* WidgetBasedTest::m_app = nullptr; - -namespace { -// faking argc and argv -char progname[] = "testview"; -char* argv[] = {&progname[0], nullptr}; -int argc = 1; -} // namespace - -WidgetBasedTest::WidgetBasedTest() {} - -void WidgetBasedTest::SetUpTestSuite() -{ - m_app = new QApplication(argc, argv); -} - -void WidgetBasedTest::TearDownTestSuite() -{ - delete m_app; - m_app = 0; -} diff --git a/Tests/Unit/gui2/libtestmachinery/widgetbasedtest.h b/Tests/Unit/gui2/libtestmachinery/widgetbasedtest.h deleted file mode 100644 index 2aa33ef5c72f96a87ac7297c66248b987993846e..0000000000000000000000000000000000000000 --- a/Tests/Unit/gui2/libtestmachinery/widgetbasedtest.h +++ /dev/null @@ -1,31 +0,0 @@ -// ************************************************************************** // -// -// Reflectometry simulation software prototype -// -//! @license GNU General Public License v3 or higher (see COPYING) -//! @authors see AUTHORS -// -// ************************************************************************** // - -#ifndef BORNAGAIN_TESTS_UNITTESTS_GUI2_LIBTESTMACHINERY_WIDGETBASEDTEST_H -#define BORNAGAIN_TESTS_UNITTESTS_GUI2_LIBTESTMACHINERY_WIDGETBASEDTEST_H - -#include <gtest/gtest.h> - -class QApplication; - -//! Convenience class to setup QApplication for tests involving QWidget creation. - -class WidgetBasedTest : public ::testing::Test { -public: - WidgetBasedTest(); - - static void SetUpTestSuite(); - - static void TearDownTestSuite(); - -protected: - static QApplication* m_app; -}; - -#endif // BORNAGAIN_TESTS_UNITTESTS_GUI2_LIBTESTMACHINERY_WIDGETBASEDTEST_H diff --git a/Tests/Unit/gui2/testdareflcore/CMakeLists.txt b/Tests/Unit/gui2/testdareflcore/CMakeLists.txt deleted file mode 100644 index 2cb782766f3c2d2521f924d01f86dc2903e3fe11..0000000000000000000000000000000000000000 --- a/Tests/Unit/gui2/testdareflcore/CMakeLists.txt +++ /dev/null @@ -1,26 +0,0 @@ -set(executable_name testdareflcore) - -include(GoogleTest) - -file(GLOB source_files "*.cpp") -file(GLOB include_files "*.h") - -find_package(Qt5Core REQUIRED) -find_package(Qt5Test REQUIRED) - -if(WIN32) - add_definitions(-DGTEST_LINKED_AS_SHARED_LIBRARY) -endif() - -# necessary for Qt creator and clang code model -include_directories(${gtest_SOURCE_DIR}/include ${gtest_SOURCE_DIR}) - -set(CMAKE_AUTOMOC ON) -add_executable(${executable_name} ${source_files} ${include_files}) -target_link_libraries(${executable_name} gtest gmock Qt5::Core Qt5::Test dareflcore - darefltestmachinery) - -# to make clang code model in Qt creator happy -target_compile_features(${executable_name} PUBLIC cxx_std_17) - -gtest_discover_tests(${executable_name}) diff --git a/Tests/Unit/gui2/testdareflcore/TestAll.cpp b/Tests/Unit/gui2/testdareflcore/TestAll.cpp deleted file mode 100644 index 14e42475c912798bc1cb05334e4ce9fd2d49dede..0000000000000000000000000000000000000000 --- a/Tests/Unit/gui2/testdareflcore/TestAll.cpp +++ /dev/null @@ -1,26 +0,0 @@ -// ************************************************************************** // -// -// Reflectometry simulation software prototype -// -//! @license GNU General Public License v3 or higher (see COPYING) -//! @authors see AUTHORS -// -// ************************************************************************** // - -#include "google_test.h" -#include "mvvm/model/comparators.h" -#include <QApplication> -#include <QStandardItem> -#include <string> - -int main(int argc, char** argv) -{ - QApplication app(argc, argv); - Q_UNUSED(app) - - ModelView::Comparators::registerComparators(); - qRegisterMetaType<QStandardItem*>("QStandardItem*"); - - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/Tests/Unit/gui2/testdareflcore/applicationmodels.test.cpp b/Tests/Unit/gui2/testdareflcore/applicationmodels.test.cpp deleted file mode 100644 index b29320d22e569695fb6c2ec477b6b47c3f384416..0000000000000000000000000000000000000000 --- a/Tests/Unit/gui2/testdareflcore/applicationmodels.test.cpp +++ /dev/null @@ -1,51 +0,0 @@ -// ************************************************************************** // -// -// Reflectometry simulation software prototype -// -//! @license GNU General Public License v3 or higher (see COPYING) -//! @authors see AUTHORS -// -// ************************************************************************** // - -#include "folderbasedtest.h" -#include "google_test.h" -#include "gui2/model/applicationmodels.h" -#include "mvvm/factories/modeldocumentfactory.h" -#include "mvvm/project/project.h" -#include "mvvm/project/project_types.h" - -using namespace ModelView; - -//! Tests of ApplicationModels - -class ApplicationModelsTest : public FolderBasedTest { -public: - ApplicationModelsTest() : FolderBasedTest("test_ApplicationModelsTest") {} - - ~ApplicationModelsTest(); -}; - -ApplicationModelsTest::~ApplicationModelsTest() = default; - -//! Testing that nothing is crashing on project save and load. - -TEST_F(ApplicationModelsTest, saveLoad) -{ - auto project_dir = createEmptyDir("Untitled1"); - - gui2::ApplicationModels models, loadedModels; - - { - ProjectContext context1; - context1.m_models_callback = [&models]() { return models.persistent_models(); }; - Project project1(context1); - project1.save(project_dir); - } - - { - ProjectContext context2; - context2.m_models_callback = [&loadedModels]() { return loadedModels.persistent_models(); }; - Project project2(context2); - project2.load(project_dir); - } -} diff --git a/Tests/Unit/gui2/testdareflcore/datahandler.test.cpp b/Tests/Unit/gui2/testdareflcore/datahandler.test.cpp deleted file mode 100644 index 98d5e20d9c69ac94d401c2e5eb137f9ad062a02c..0000000000000000000000000000000000000000 --- a/Tests/Unit/gui2/testdareflcore/datahandler.test.cpp +++ /dev/null @@ -1,58 +0,0 @@ -// ************************************************************************** // -// -// Reflectometry simulation software prototype -// -//! @license GNU General Public License v3 or higher (see COPYING) -//! @authors see AUTHORS -// -// ************************************************************************** // - -#include "folderbasedtest.h" -#include "gui2/dataloader/datahandler.h" -#include "mvvm/utils/fileutils.h" -#include "test_utils.h" - -using TestUtils::toStringVector; -using namespace gui2; - -class DataHandlerTest : public FolderBasedTest { -public: - DataHandlerTest() : FolderBasedTest("test_DataHandlerTest") {} - ~DataHandlerTest(); -}; - -DataHandlerTest::~DataHandlerTest() = default; - -//! Testing function TrimWhitespace - -TEST_F(DataHandlerTest, updateRawData) -{ - auto file_name1 = TestUtils::CreateTestFile(testPath(), "a.txt", {"aaa bbb\nccc ddd\n"}); - - DataHandler handler; - handler.updateRawData({file_name1}); - - // the data was loaded - EXPECT_EQ(handler.textData(file_name1), toStringVector("aaa bbb", "ccc ddd")); - - // removing file physically from disk - ModelView::Utils::remove(file_name1); - - // Updating to the same data will not change anything. Handler knows nothing about - // the data removed from disk and still keeps the buffer. - - handler.updateRawData({file_name1}); - EXPECT_EQ(handler.textData(file_name1), toStringVector("aaa bbb", "ccc ddd")); - - // adding second file - auto file_name2 = TestUtils::CreateTestFile(testPath(), "b.txt", {"111 222\n333 444\n"}); - handler.updateRawData({file_name1, file_name2}); - - EXPECT_EQ(handler.textData(file_name1), toStringVector("aaa bbb", "ccc ddd")); - EXPECT_EQ(handler.textData(file_name2), toStringVector("111 222", "333 444")); - - // remove file from list - handler.updateRawData({}); - EXPECT_TRUE(handler.textData(file_name1).empty()); - EXPECT_TRUE(handler.textData(file_name2).empty()); -} diff --git a/Tests/Unit/gui2/testdareflcore/dataloader_utils.test.cpp b/Tests/Unit/gui2/testdareflcore/dataloader_utils.test.cpp deleted file mode 100644 index d88b58343bb253fee107de58d1b9b36178bdd445..0000000000000000000000000000000000000000 --- a/Tests/Unit/gui2/testdareflcore/dataloader_utils.test.cpp +++ /dev/null @@ -1,280 +0,0 @@ -// ************************************************************************** // -// -// Reflectometry simulation software prototype -// -//! @license GNU General Public License v3 or higher (see COPYING) -//! @authors see AUTHORS -// -// ************************************************************************** // - -#include "folderbasedtest.h" -#include "gui2/dataloader/dataloader_constants.h" -#include "gui2/dataloader/dataloader_utils.h" -#include "gui2/importdataview/graphimportdata.h" -#include "test_utils.h" -#include <initializer_list> -#include <vector> - -using namespace gui2; -using TestUtils::toStringVector; - -//! Tests of ParseUtils. - -class ParseUtilsTest : public FolderBasedTest { -public: - ParseUtilsTest() : FolderBasedTest("test_ParseUtilsTest") {} - ~ParseUtilsTest(); - - std::vector<std::pair<int, int>> - toPairVector(std::initializer_list<std::pair<int, int>> list = {}) - { - return std::vector<std::pair<int, int>>(list.begin(), list.end()); - } - - std::vector<double> toVector(std::initializer_list<double> args) - { - return std::vector<double>(args.begin(), args.end()); - }; -}; - -ParseUtilsTest::~ParseUtilsTest() = default; - -TEST_F(ParseUtilsTest, LoadASCIIFile) -{ - std::string content = {"abc abc\n 123 456\n"}; - auto file_name = TestUtils::CreateTestFile(testPath(), "a.txt", content); - - auto raw_data = Utils::LoadASCIIFile(file_name); - EXPECT_EQ(raw_data.size(), 2u); - EXPECT_EQ(raw_data[0], std::string("abc abc")); - EXPECT_EQ(raw_data[1], std::string(" 123 456")); -} - -//! Testing local utility function. - -TEST_F(ParseUtilsTest, toStringVector) -{ - std::vector<std::string> expected; - - expected = {}; - EXPECT_EQ(toStringVector(), expected); - - expected = {"a"}; - EXPECT_EQ(toStringVector("a"), expected); - - expected = {"a", "b"}; - EXPECT_EQ(toStringVector("a", "b"), expected); - - expected = {"aaa", "bbb", ""}; - EXPECT_EQ(toStringVector("aaa", "bbb", ""), expected); -} - -//! Testing local utility function. - -TEST_F(ParseUtilsTest, toPairVector) -{ - std::vector<std::pair<int, int>> expected; - - expected = {}; - EXPECT_EQ(toPairVector(), expected); - expected = {{1, 2}}; - EXPECT_EQ(toPairVector({{1, 2}}), expected); - expected = {{1, 2}, {3, 4}}; - EXPECT_EQ(toPairVector({{1, 2}, {3, 4}}), expected); -} - -//! Checking method to expand line numbers -//! "1, 2-4" -> {0, 0}, {1, 3} - -TEST_F(ParseUtilsTest, ExpandLineNumberPattern) -{ - using Utils::ExpandLineNumberPattern; - EXPECT_EQ(ExpandLineNumberPattern(""), toPairVector()); - EXPECT_EQ(ExpandLineNumberPattern(" "), toPairVector()); - EXPECT_EQ(ExpandLineNumberPattern("aaa"), toPairVector()); - EXPECT_EQ(ExpandLineNumberPattern("1"), toPairVector({{1, 1}})); - EXPECT_EQ(ExpandLineNumberPattern(" 1"), toPairVector({{1, 1}})); - EXPECT_EQ(ExpandLineNumberPattern(" 1 "), toPairVector({{1, 1}})); - EXPECT_EQ(ExpandLineNumberPattern("42"), toPairVector({{42, 42}})); - - EXPECT_EQ(ExpandLineNumberPattern("1,1"), toPairVector({{1, 1}, {1, 1}})); - EXPECT_EQ(ExpandLineNumberPattern("1,2"), toPairVector({{1, 1}, {2, 2}})); - EXPECT_EQ(ExpandLineNumberPattern(" 1 , 2 "), toPairVector({{1, 1}, {2, 2}})); - - EXPECT_EQ(ExpandLineNumberPattern("1-1"), toPairVector({{1, 1}})); - EXPECT_EQ(ExpandLineNumberPattern("1-5"), toPairVector({{1, 5}})); - - EXPECT_EQ(ExpandLineNumberPattern("1,2-3"), toPairVector({{1, 1}, {2, 3}})); - EXPECT_EQ(ExpandLineNumberPattern("1, 2-3, 42"), toPairVector({{1, 1}, {2, 3}, {42, 42}})); - EXPECT_EQ(ExpandLineNumberPattern("42, 2-3, 1"), toPairVector({{42, 42}, {2, 3}, {1, 1}})); - - // more wrong patterns - EXPECT_EQ(ExpandLineNumberPattern("1,b"), toPairVector({{1, 1}})); - EXPECT_EQ(ExpandLineNumberPattern("a,1,b"), toPairVector({{1, 1}})); - EXPECT_EQ(ExpandLineNumberPattern("a-2"), toPairVector()); - EXPECT_EQ(ExpandLineNumberPattern("6-5"), toPairVector()); // wrong order -} - -TEST_F(ParseUtilsTest, CreateLineNumberPatternValidator) -{ - using Utils::CreateLineNumberPatternValidator; - - auto is_accepted = CreateLineNumberPatternValidator("1"); - EXPECT_FALSE(is_accepted(0)); - EXPECT_TRUE(is_accepted(1)); - EXPECT_FALSE(is_accepted(2)); - - is_accepted = CreateLineNumberPatternValidator(""); - EXPECT_FALSE(is_accepted(0)); - EXPECT_FALSE(is_accepted(1)); - EXPECT_FALSE(is_accepted(2)); - - is_accepted = CreateLineNumberPatternValidator("1, 2"); - EXPECT_FALSE(is_accepted(0)); - EXPECT_TRUE(is_accepted(1)); - EXPECT_TRUE(is_accepted(2)); - EXPECT_FALSE(is_accepted(3)); - - is_accepted = CreateLineNumberPatternValidator("42, 44-46"); - EXPECT_FALSE(is_accepted(0)); - EXPECT_TRUE(is_accepted(42)); - EXPECT_FALSE(is_accepted(43)); - EXPECT_TRUE(is_accepted(44)); - EXPECT_TRUE(is_accepted(45)); - EXPECT_TRUE(is_accepted(46)); - EXPECT_FALSE(is_accepted(47)); -} - -TEST_F(ParseUtilsTest, CreateLinePrefixValidator) -{ - using Utils::CreateLinePrefixValidator; - - auto is_accepted = CreateLinePrefixValidator(""); - EXPECT_FALSE(is_accepted("")); - EXPECT_FALSE(is_accepted(" ")); - EXPECT_FALSE(is_accepted(" ")); - EXPECT_TRUE(is_accepted("abc")); - EXPECT_TRUE(is_accepted(" abc ")); - - is_accepted = CreateLinePrefixValidator("#"); - EXPECT_FALSE(is_accepted("")); - EXPECT_FALSE(is_accepted(" ")); - EXPECT_FALSE(is_accepted("# abc")); - EXPECT_TRUE(is_accepted("42 ")); -} - -TEST_F(ParseUtilsTest, CreateSeparatorSplitter) -{ - using Utils::CreateSeparatorBasedSplitter; - - auto parse = CreateSeparatorBasedSplitter(","); - EXPECT_EQ(parse("a"), toStringVector("a")); - EXPECT_EQ(parse("a,b"), toStringVector("a", "b")); - EXPECT_EQ(parse("a, b"), toStringVector("a", " b")); // shouldn't we trim white spaces? - EXPECT_EQ(parse(" a, b "), toStringVector("a", " b")); - - EXPECT_EQ(parse("1.0,2.0,3.0"), toStringVector("1.0", "2.0", "3.0")); - EXPECT_EQ(parse("1.0, 2.0, 3.0"), toStringVector("1.0", " 2.0", " 3.0")); - EXPECT_EQ(parse("1.0, 2.0, 3.0,"), toStringVector("1.0", " 2.0", " 3.0", "")); - - parse = CreateSeparatorBasedSplitter(" "); - EXPECT_EQ(parse("a"), toStringVector("a")); - EXPECT_EQ(parse("a b"), toStringVector("a", "b")); - EXPECT_EQ(parse(" a b "), toStringVector("a", "b")); - EXPECT_EQ(parse(" a b "), toStringVector("a", "b")); -} - -TEST_F(ParseUtilsTest, AddHtmlColorTag) -{ - EXPECT_EQ(Utils::AddHtmlColorTag("abc", "x"), "<font color=\"x\">abc</font>"); -} - -TEST_F(ParseUtilsTest, AddHtmlDivTag) -{ - EXPECT_EQ(Utils::AddHtmlDivTag("abc"), "<div>abc</div>"); -} - -TEST_F(ParseUtilsTest, AddHtmlColorTagToParts) -{ - auto parse = Utils::CreateSeparatorBasedSplitter(","); - std::string line("a,b"); - EXPECT_EQ(Utils::AddHtmlColorTagToParts(line, parse(line), "A", "B"), - "<div><font color=\"A\">a</font><span style=\"background-color:B\">,</span><font " - "color=\"A\">b</font></div>"); - - parse = Utils::CreateSeparatorBasedSplitter(" | "); - line = "abc | efg"; - EXPECT_EQ(Utils::AddHtmlColorTagToParts(line, parse(line), "A", "B"), - "<div><font color=\"A\">abc</font><span style=\"background-color:B\"> | </span><font " - "color=\"A\">efg</font></div>"); -} - -TEST_F(ParseUtilsTest, ExtractTwoColumns) -{ - using Utils::ExtractTwoColumns; - - auto result = ExtractTwoColumns({{}}, 0, 0); - EXPECT_EQ(result.first.size(), 0); - EXPECT_EQ(result.second.size(), 0); - - // normal parsing - result = ExtractTwoColumns({{"1.0", "2.0"}, {"3.0", "4.0"}}, 0, 1); - EXPECT_EQ(result.first, toVector({1.0, 3.0})); - EXPECT_EQ(result.second, toVector({2.0, 4.0})); - - result = ExtractTwoColumns({{" 1.0 ", " 2.0 "}, {" 3.0 ", " 4.0 "}}, 0, 1); - EXPECT_EQ(result.first, toVector({1.0, 3.0})); - EXPECT_EQ(result.second, toVector({2.0, 4.0})); - - // partial parsing (nan in input) - result = ExtractTwoColumns({{"---", "2.0"}, {"3.0", "4.0"}}, 0, 1); - EXPECT_EQ(result.first, toVector({3.0})); - EXPECT_EQ(result.second, toVector({4.0})); - - // partial parsing (different length of columns) - result = ExtractTwoColumns({{"1.0", "2.0", "3.0"}, {"4.0", "5.0", "6.0", "7.0"}}, 0, 3); - EXPECT_EQ(result.first, toVector({4.0})); - EXPECT_EQ(result.second, toVector({7.0})); -} - -//! Checks method CreateGraphInfoPairs. - -TEST_F(ParseUtilsTest, CreateGraphInfoPairs) -{ - ColumnInfo col0{0, GUI::Constants::AxisType, "", 0}; - ColumnInfo col1{1, GUI::Constants::IntensityType, "", 0}; - ColumnInfo col2{2, GUI::Constants::IgnoreType, "", 0}; - ColumnInfo col3{3, GUI::Constants::IntensityType, "", 0}; - - std::vector<ColumnInfo> infos = {col0, col1, col2, col3}; - - auto info_pairs = Utils::CreateGraphInfoPairs(infos); - - // if we have one Axis and two Intesity columns, we have to get - // two pairs of info - - ASSERT_EQ(info_pairs.size(), 2); - EXPECT_EQ(info_pairs[0].first.column, 0); - EXPECT_EQ(info_pairs[0].second.column, 1); - EXPECT_EQ(info_pairs[1].first.column, 0); - EXPECT_EQ(info_pairs[1].second.column, 3); -} - -TEST_F(ParseUtilsTest, CreateData) -{ - ColumnInfo col0{0, GUI::Constants::AxisType, "units0", 1.0}; - ColumnInfo col2{2, GUI::Constants::IntensityType, "units2", 2.0}; - - std::vector<std::vector<std::string>> text_data = {{"1.0", "2.0", "3.0"}, - {"4.0", "5.0", "6.0"}, - {"7.0", "8.0", "9.0"}, - {"10.0", "11.0", "12.0"}}; - - auto data = Utils::CreateData(text_data, col0, col2); - - EXPECT_EQ(data.graph_description, ""); - EXPECT_EQ(data.bin_centers, toVector({1.0, 4.0, 7.0, 10.0})); - EXPECT_EQ(data.axis_units, "units0"); - EXPECT_EQ(data.bin_values, toVector({6.0, 12.0, 18.0, 24.0})); - EXPECT_EQ(data.signal_units, "units2"); -} diff --git a/Tests/Unit/gui2/testdareflcore/dataselectionmodel.test.cpp b/Tests/Unit/gui2/testdareflcore/dataselectionmodel.test.cpp deleted file mode 100644 index 3c6b2a87495e7038c2719490973e449663297937..0000000000000000000000000000000000000000 --- a/Tests/Unit/gui2/testdareflcore/dataselectionmodel.test.cpp +++ /dev/null @@ -1,166 +0,0 @@ -// ************************************************************************** // -// -// Reflectometry simulation software prototype -// -//! @license GNU General Public License v3 or higher (see COPYING) -//! @authors see AUTHORS -// -// ************************************************************************** // - -#include "google_test.h" -#include "gui2/importdataview/dataselectionmodel.h" -#include "gui2/importdataview/dataviewmodel.h" -#include "gui2/model/experimentaldataitems.h" -#include "gui2/model/experimentaldatamodel.h" -#include "mvvm/model/modelutils.h" -#include "mvvm/standarditems/graphitem.h" -#include "test_utils.h" -#include <QDebug> - -using namespace gui2; -using namespace ModelView; - -//! Tests of DataSelectionModel. - -class DataSelectionModelTest : public ::testing::Test { -public: - ~DataSelectionModelTest(); - - struct TestData { - ExperimentalDataModel data_model; - DataViewModel view_model{&data_model}; - DataSelectionModel selection_model{&view_model}; - CanvasContainerItem* container{nullptr}; - CanvasItem* canvas0{nullptr}; - GraphItem* graph_c0_a{nullptr}; - GraphItem* graph_c0_b{nullptr}; - CanvasItem* canvas1{nullptr}; - GraphItem* graph_c1_a{nullptr}; - TestData() - { - container = Utils::TopItem<CanvasContainerItem>(&data_model); - canvas0 = data_model.insertItem<CanvasItem>(container); - graph_c0_a = data_model.insertItem<GraphItem>(canvas0); - graph_c0_b = data_model.insertItem<GraphItem>(canvas0); - canvas1 = data_model.insertItem<CanvasItem>(container); - graph_c1_a = data_model.insertItem<GraphItem>(canvas1); - view_model.setRootSessionItem(container); - } - }; -}; - -DataSelectionModelTest::~DataSelectionModelTest() = default; - -//! Initial state of selection model. - -TEST_F(DataSelectionModelTest, initialState) -{ - TestData test_data; - // checking layout of container with test data - EXPECT_EQ(test_data.container->size(), 2); - - // checking that no selection exists - EXPECT_FALSE(test_data.selection_model.hasSelection()); - EXPECT_EQ(test_data.selection_model.activeCanvas(), nullptr); - EXPECT_EQ(test_data.selection_model.selectedGraph(), nullptr); - EXPECT_EQ(test_data.selection_model.selectedCanvas().size(), 0); - EXPECT_EQ(test_data.selection_model.selectedGraphs().size(), 0); -} - -//! Select single canvas and check that it was actually selected. - -TEST_F(DataSelectionModelTest, selectCanvasItem) -{ - TestData test_data; - EXPECT_FALSE(test_data.selection_model.hasSelection()); - - // make canvas0 selected - test_data.selection_model.selectItem(test_data.canvas0); - - EXPECT_TRUE(test_data.selection_model.hasSelection()); - EXPECT_EQ(test_data.selection_model.selectedIndexes().size(), 2); // CanvasItem, ViewEmptyItem - - std::vector<SessionItem*> expected = {test_data.canvas0}; - EXPECT_EQ(test_data.selection_model.selectedItems(), expected); - - // check that selection model reports same canvas as active one - EXPECT_EQ(test_data.selection_model.activeCanvas(), test_data.canvas0); - std::vector<CanvasItem*> expected_canvas{test_data.canvas0}; - EXPECT_EQ(test_data.selection_model.selectedCanvas(), expected_canvas); - - // no graphs selected - EXPECT_EQ(test_data.selection_model.selectedGraph(), nullptr); - EXPECT_EQ(test_data.selection_model.selectedGraphs().size(), 0); -} - -//! Select single graph and check reported selection. - -TEST_F(DataSelectionModelTest, selectGraph) -{ - TestData test_data; - EXPECT_FALSE(test_data.selection_model.hasSelection()); - - // make graph0 selected - test_data.selection_model.selectItem(test_data.graph_c0_a); - - EXPECT_TRUE(test_data.selection_model.hasSelection()); - EXPECT_EQ(test_data.selection_model.selectedIndexes().size(), 2); // GraphItem, LabelItem - - std::vector<SessionItem*> expected = {test_data.graph_c0_a}; - EXPECT_EQ(test_data.selection_model.selectedItems(), expected); - - // method should report parent of graph as active canvas - EXPECT_EQ(test_data.selection_model.activeCanvas(), test_data.canvas0); - - // no canvas selected - EXPECT_EQ(test_data.selection_model.selectedCanvas(), std::vector<CanvasItem*>()); - - // method should report parent of graph as selected canvas - EXPECT_EQ(test_data.selection_model.selectedGraph(), test_data.graph_c0_a); - std::vector<ModelView::GraphItem*> expected_graphs{test_data.graph_c0_a}; - EXPECT_EQ(test_data.selection_model.selectedGraphs(), expected_graphs); -} - -//! Select two graphs and check reported selection. - -TEST_F(DataSelectionModelTest, selectTwoGraphs) -{ - TestData test_data; - EXPECT_FALSE(test_data.selection_model.hasSelection()); - - // make two graphs selected - std::vector<SessionItem*> expected = {test_data.graph_c0_a, test_data.graph_c0_b}; - test_data.selection_model.selectItems(expected); - - EXPECT_TRUE(test_data.selection_model.hasSelection()); - EXPECT_EQ(test_data.selection_model.selectedIndexes().size(), 4); // GraphItem, LabelItem - - EXPECT_EQ(test_data.selection_model.selectedItems(), expected); - - // method should report parent of graph as active canvas - EXPECT_EQ(test_data.selection_model.activeCanvas(), test_data.canvas0); - EXPECT_EQ(test_data.selection_model.selectedCanvas().size(), 0); - - // method should report parent of graph as selected canvas - EXPECT_EQ(test_data.selection_model.selectedGraph(), test_data.graph_c0_a); - std::vector<ModelView::GraphItem*> expected_graphs{test_data.graph_c0_a, test_data.graph_c0_b}; - EXPECT_EQ(test_data.selection_model.selectedGraphs(), expected_graphs); -} - -//! Select two graphs and check reported selection. - -// FIXME Enable test. For that DataSelectionModel should allow to select -// parent+child programmatically. - -// TEST_F(DataSelectionModelTest, selectGraphAndCanvas) -//{ -// TestData test_data; -// EXPECT_FALSE(test_data.selection_model.hasSelection()); - -// // make two graphs selected -// std::vector<SessionItem*> expected = {test_data.graph_c0_a, test_data.canvas0}; -// test_data.selection_model.selectItems(expected); - -// EXPECT_TRUE(test_data.selection_model.hasSelection()); -// EXPECT_EQ(test_data.selection_model.selectedIndexes().size(), 4); // GraphItem, LabelItem -//} diff --git a/Tests/Unit/gui2/testdareflcore/defaultparser.test.cpp b/Tests/Unit/gui2/testdareflcore/defaultparser.test.cpp deleted file mode 100644 index 1fa0d4b379c179b00cf125a2e9049343e30fb4cf..0000000000000000000000000000000000000000 --- a/Tests/Unit/gui2/testdareflcore/defaultparser.test.cpp +++ /dev/null @@ -1,91 +0,0 @@ -// ************************************************************************** // -// -// Reflectometry simulation software prototype -// -//! @license GNU General Public License v3 or higher (see COPYING) -//! @authors see AUTHORS -// -// ************************************************************************** // - -#include "google_test.h" -#include "gui2/dataloader/dataloader_types.h" -#include "gui2/dataloader/defaultparser.h" -#include "test_utils.h" - -using namespace gui2; -using TestUtils::toStringVector; - -//! Test DefaultParser. - -class DefaultParserTest : public ::testing::Test { -public: - ~DefaultParserTest(); - - int parsedDataRowCount(const DefaultParser& parser) { return parser.parsedData().size(); } -}; - -DefaultParserTest::~DefaultParserTest() = default; - -TEST_F(DefaultParserTest, initialState) -{ - DefaultParser parser({}); - - EXPECT_EQ(parser.totalLineCount(), 0); - EXPECT_EQ(parsedDataRowCount(parser), 0); -} - -//! Testing line acceptance with standard parser settings. - -TEST_F(DefaultParserTest, lineAcceptanceStandardParser) -{ - DefaultParser parser({"#", ",", ""}); // prefix, separator, line pattern - - parser.process({"1, 2, 3"}); - EXPECT_EQ(parser.totalLineCount(), 1); - EXPECT_EQ(parsedDataRowCount(parser), 1); - - parser.process({"1, 2, 3", "4, 5, 6"}); - EXPECT_EQ(parser.totalLineCount(), 2); - EXPECT_EQ(parsedDataRowCount(parser), 2); - - parser.process({"# 1, 2, 3"}); - EXPECT_EQ(parser.totalLineCount(), 1); - EXPECT_EQ(parsedDataRowCount(parser), 0); - - parser.process({"#1, 2, 3", "4, 5, 6"}); - EXPECT_EQ(parser.totalLineCount(), 2); - EXPECT_EQ(parsedDataRowCount(parser), 1); - - parser.process({"#1, 2, 3", "4, 5, 6", ""}); - EXPECT_EQ(parser.totalLineCount(), 3); - EXPECT_EQ(parsedDataRowCount(parser), 1); -} - -//! Testing line acceptance with standard parser settings. - -TEST_F(DefaultParserTest, lineAcceptanceNumberPatternParser) -{ - DefaultParser parser({"#", ",", "1-2"}); // prefix, separator, line pattern - - parser.process({"1, 2, 3", "4, 5, 6", "7, 8, 9", "#", ""}); - EXPECT_EQ(parser.totalLineCount(), 5); - EXPECT_EQ(parsedDataRowCount(parser), 1); -} - -TEST_F(DefaultParserTest, parseResults) -{ - DefaultParser parser({"#", ",", ""}); // prefix, separator, line pattern - - parser.process({"1, 2, 3"}); - EXPECT_EQ(parser.parsedData().size(), 1); - EXPECT_EQ(parser.parsedData()[0], toStringVector("1", " 2", " 3")); - - parser.process({"1, 2, 3", "4, 5, 6"}); - EXPECT_EQ(parser.parsedData().size(), 2); - EXPECT_EQ(parser.parsedData()[0], toStringVector("1", " 2", " 3")); - EXPECT_EQ(parser.parsedData()[1], toStringVector("4", " 5", " 6")); - - parser.process({"#1, 2, 3", "4, 5, 6"}); - EXPECT_EQ(parser.parsedData().size(), 1); - EXPECT_EQ(parser.parsedData()[0], toStringVector("4", " 5", " 6")); -} diff --git a/Tests/Unit/gui2/testdareflcore/experimentaldatamodel.test.cpp b/Tests/Unit/gui2/testdareflcore/experimentaldatamodel.test.cpp deleted file mode 100644 index c5b2ae2391121b91e6b2d5c119bb9a1924a20386..0000000000000000000000000000000000000000 --- a/Tests/Unit/gui2/testdareflcore/experimentaldatamodel.test.cpp +++ /dev/null @@ -1,209 +0,0 @@ -// ************************************************************************** // -// -// Reflectometry simulation software prototype -// -//! @license GNU General Public License v3 or higher (see COPYING) -//! @authors see AUTHORS -// -// ************************************************************************** // - -#include "google_test.h" - -#include "gui2/importdataview/graphimportdata.h" -#include "gui2/model/experimentaldataitems.h" -#include "gui2/model/experimentaldatamodel.h" -#include "gui2/model/item_constants.h" -#include "mvvm/model/modelutils.h" -#include "mvvm/standarditems/data1ditem.h" -#include "mvvm/standarditems/graphitem.h" - -using namespace gui2; -using namespace ModelView; - -//! Tests of ExperimentalDataModel. - -class ExperimentalDataModelTest : public ::testing::Test { -public: - ~ExperimentalDataModelTest(); -}; - -ExperimentalDataModelTest::~ExperimentalDataModelTest() = default; - -//! Test the initial state of the model. - -TEST_F(ExperimentalDataModelTest, initialState) -{ - ExperimentalDataModel model; - - ASSERT_TRUE(model.canvasContainer() != nullptr); - EXPECT_EQ(model.canvasContainer()->childrenCount(), 0); - EXPECT_EQ(model.canvasContainer()->modelType(), gui2::GUI::Constants::CanvasContainerItemType); - EXPECT_EQ(model.canvasContainer()->canvasItems().size(), 0); - - ASSERT_TRUE(model.dataContainer() != nullptr); - EXPECT_EQ(model.dataContainer()->childrenCount(), 0); - EXPECT_EQ(model.dataContainer()->modelType(), - gui2::GUI::Constants::ExperimentalDataContainerItemType); - EXPECT_EQ(model.dataContainer()->dataItems().size(), 0); -} - -//! Adding canvas to the model. - -TEST_F(ExperimentalDataModelTest, addCanvas) -{ - ExperimentalDataModel model; - - auto canvas = model.addCanvas(); - ASSERT_TRUE(canvas != nullptr); - EXPECT_EQ(canvas->graphItems().size(), 0); - EXPECT_EQ(canvas->modelType(), gui2::GUI::Constants::CanvasItemType); - EXPECT_EQ(model.canvasContainer()->canvasItems().size(), 1); - EXPECT_EQ(model.canvasContainer()->canvasItems(), std::vector<CanvasItem*>() = {canvas}); -} - -//! Adding graph from the data structure. - -TEST_F(ExperimentalDataModelTest, addGraph) -{ - ExperimentalDataModel model; - std::vector<double> bin_centers{1, 2, 3}; - std::vector<double> bin_values{10, 20, 30}; - - GraphImportData raw_data = {"", bin_centers, "", bin_values, ""}; - - auto canvas = model.addCanvas(); - - // adding graph, it should appear in canvas - auto graph = model.addGraph(raw_data, *canvas); - ASSERT_EQ(canvas->graphItems().size(), 1); - EXPECT_EQ(canvas->graphItems()[0], graph); - - // graph should have values as defined in the raw_data - EXPECT_EQ(graph->binCenters(), bin_centers); - EXPECT_EQ(graph->binValues(), bin_values); - - EXPECT_EQ(model.dataContainer()->childrenCount(), 1); - std::vector<Data1DItem*> expected_items = {graph->dataItem()}; - EXPECT_EQ(model.dataContainer()->dataItems(), expected_items); -} - -//! Removing just added graph. - -TEST_F(ExperimentalDataModelTest, removeGraph) -{ - ExperimentalDataModel model; - std::vector<double> bin_centers{1, 2, 3}; - std::vector<double> bin_values{10, 20, 30}; - - GraphImportData raw_data = {"", bin_centers, "", bin_values, ""}; - - auto canvas = model.addCanvas(); - - // adding graph - auto graph = model.addGraph(raw_data, *canvas); - - // removing graph - model.removeGraph(*graph); - - // should remoive bove graph, and underlying data item - EXPECT_EQ(canvas->graphItems().size(), 0); - EXPECT_EQ(model.dataContainer()->dataItems().size(), 0); -} - -//! Removing middle graph from the collection. - -TEST_F(ExperimentalDataModelTest, removeMiddleGraph) -{ - ExperimentalDataModel model; - std::vector<double> bin_centers{1, 2, 3}; - std::vector<double> bin_values{10, 20, 30}; - - GraphImportData raw_data = {"", bin_centers, "", bin_values, ""}; - - auto canvas = model.addCanvas(); - - // adding graph, it should appear in canvas - auto graph0 = model.addGraph(raw_data, *canvas); - auto graph1 = model.addGraph(raw_data, *canvas); - auto graph2 = model.addGraph(raw_data, *canvas); - - // removing graph - model.removeGraph(*graph1); - - std::vector<GraphItem*> expected_graphs = {graph0, graph2}; - ASSERT_EQ(canvas->graphItems(), expected_graphs); - std::vector<Data1DItem*> expected_items = {graph0->dataItem(), graph2->dataItem()}; - EXPECT_EQ(model.dataContainer()->dataItems(), expected_items); -} - -//! Removing just added graph. - -TEST_F(ExperimentalDataModelTest, removeCanvasWithGraph) -{ - ExperimentalDataModel model; - std::vector<double> bin_centers{1, 2, 3}; - std::vector<double> bin_values{10, 20, 30}; - - GraphImportData raw_data = {"", bin_centers, "", bin_values, ""}; - - auto canvas = model.addCanvas(); - - // adding graph - model.addGraph(raw_data, *canvas); - - // removing graph - model.removeCanvas(*canvas); - - // should remoive bove graph, and underlying data item - EXPECT_EQ(model.dataContainer()->dataItems().size(), 0); - EXPECT_EQ(model.canvasContainer()->canvasItems().size(), 0); -} - -//! Merge single canvas into itself. Nothing should happen. - -TEST_F(ExperimentalDataModelTest, mergeSingleCanvas) -{ - ExperimentalDataModel model; - - GraphImportData raw_data = {"", {1}, "", {10}, ""}; - auto canvas = model.addCanvas(); - auto graph = model.addGraph(raw_data, *canvas); - - // removing graph - model.mergeCanvases(std::vector<CanvasItem*>({canvas})); - - // should remove bove graph, and underlying data item - EXPECT_EQ(model.dataContainer()->dataItems().size(), 1); - EXPECT_EQ(model.canvasContainer()->canvasItems().size(), 1); - EXPECT_EQ(canvas->graphItems(), std::vector<GraphItem*>({graph})); -} - -//! Merge single canvas into itself. Nothing should happen. - -TEST_F(ExperimentalDataModelTest, mergeTwoCanvases) -{ - ExperimentalDataModel model; - - GraphImportData raw_data0 = {"", {1}, "", {10}, ""}; - GraphImportData raw_data1 = {"", {2}, "", {20}, ""}; - GraphImportData raw_data2 = {"", {3}, "", {30}, ""}; - - auto canvas0 = model.addCanvas(); - auto graph0 = model.addGraph(raw_data0, *canvas0); - - auto canvas1 = model.addCanvas(); - auto graph1 = model.addGraph(raw_data1, *canvas1); - auto graph2 = model.addGraph(raw_data2, *canvas1); - - // removing graph - model.mergeCanvases(std::vector<CanvasItem*>({canvas0, canvas1})); - - // should remoive bove graph, and underlying data item - EXPECT_EQ(model.dataContainer()->dataItems().size(), 3); - EXPECT_EQ(model.canvasContainer()->canvasItems(), std::vector<CanvasItem*>({canvas0})); - EXPECT_EQ(canvas0->graphItems(), std::vector<GraphItem*>({graph0, graph1, graph2})); - - EXPECT_EQ(graph0->dataItem()->binCenters(), std::vector<double>({1})); - EXPECT_EQ(graph1->dataItem()->binCenters(), std::vector<double>({2})); - EXPECT_EQ(graph2->dataItem()->binCenters(), std::vector<double>({3})); -} diff --git a/Tests/Unit/gui2/testdareflcore/importdataeditoractions.test.cpp b/Tests/Unit/gui2/testdareflcore/importdataeditoractions.test.cpp deleted file mode 100644 index f387502d57e96b2ebfc25d5f5620a000f79e3db6..0000000000000000000000000000000000000000 --- a/Tests/Unit/gui2/testdareflcore/importdataeditoractions.test.cpp +++ /dev/null @@ -1,105 +0,0 @@ -// ************************************************************************** // -// -// Reflectometry simulation software prototype -// -//! @license GNU General Public License v3 or higher (see COPYING) -//! @authors see AUTHORS -// -// ************************************************************************** // - -#include "google_test.h" -#include "gui2/importdataview/dataselectionmodel.h" -#include "gui2/importdataview/dataviewmodel.h" -#include "gui2/importdataview/graphimportdata.h" -#include "gui2/importdataview/importdataeditoractions.h" -#include "gui2/model/experimentaldataitems.h" -#include "gui2/model/experimentaldatamodel.h" -#include "mvvm/model/comboproperty.h" -#include "mvvm/model/modelutils.h" -#include "mvvm/standarditems/graphitem.h" -#include "mvvm/standarditems/plottableitems.h" -#include "test_utils.h" - -using namespace gui2; -using namespace ModelView; - -//! Tests of ImportDataEditorActions. - -class ImportDataEditorActionsTest : public ::testing::Test { -public: - ~ImportDataEditorActionsTest(); - - struct TestData { - ExperimentalDataModel data_model; - DataViewModel view_model{&data_model}; - DataSelectionModel selection_model{&view_model}; - CanvasItem* canvas0{nullptr}; - ModelView::GraphItem* graph0{nullptr}; - ModelView::GraphItem* graph1{nullptr}; - ImportDataEditorActions actions{&data_model}; - TestData() - { - canvas0 = data_model.addCanvas(); - - GraphImportData raw_data = {"", {42}, "", {42}, ""}; - graph0 = data_model.addGraph(raw_data, *canvas0); - graph1 = data_model.addGraph(raw_data, *canvas0); - - view_model.setRootSessionItem(data_model.canvasContainer()); - actions.setSelectionModel(&selection_model); - } - }; -}; - -ImportDataEditorActionsTest::~ImportDataEditorActionsTest() = default; - -//! Checks onAddCanvas. - -TEST_F(ImportDataEditorActionsTest, onAddCanvas) -{ - ExperimentalDataModel model; - ImportDataEditorActions actions(&model); - - EXPECT_EQ(model.canvasContainer()->canvasItems().size(), 0); - actions.onAddCanvas(); - EXPECT_EQ(model.canvasContainer()->canvasItems().size(), 1); -} - -//! Checks onAddCanvas. - -TEST_F(ImportDataEditorActionsTest, onDeleteItem) -{ - TestData test_data; - EXPECT_EQ(test_data.data_model.canvasContainer()->canvasItems().size(), 1); - EXPECT_EQ(test_data.data_model.dataContainer()->dataItems().size(), 2); - - test_data.selection_model.selectItem(test_data.canvas0); - - test_data.actions.onDeleteItem(); - - EXPECT_EQ(test_data.data_model.canvasContainer()->canvasItems().size(), 0); - EXPECT_EQ(test_data.data_model.dataContainer()->dataItems().size(), 0); -} - -//! Checks line style change on selection changed. - -TEST_F(ImportDataEditorActionsTest, onSelectionChanged) -{ - TestData test_data; - - test_data.selection_model.selectItem(test_data.graph0); - - auto pen0 = test_data.graph0->penItem(); - auto pen1 = test_data.graph1->penItem(); - - auto pencombo0 = pen0->property<ModelView::ComboProperty>(ModelView::PenItem::P_STYLE); - auto pencombo1 = pen1->property<ModelView::ComboProperty>(ModelView::PenItem::P_STYLE); - EXPECT_EQ(pencombo0.currentIndex(), 2); // correspond to dashed line (i.e. selected) - EXPECT_EQ(pencombo1.currentIndex(), 1); // correspond to solid line - - test_data.selection_model.selectItem(test_data.graph1); - pencombo0 = pen0->property<ModelView::ComboProperty>(ModelView::PenItem::P_STYLE); - pencombo1 = pen1->property<ModelView::ComboProperty>(ModelView::PenItem::P_STYLE); - EXPECT_EQ(pencombo0.currentIndex(), 1); // correspond to solid line - EXPECT_EQ(pencombo1.currentIndex(), 2); // correspond to dashed line (i.e. selected) -} diff --git a/Tests/Unit/gui2/testdareflcore/importtableheader.test.cpp b/Tests/Unit/gui2/testdareflcore/importtableheader.test.cpp deleted file mode 100644 index 41786f125ad4c99d2b2cf1f8d9bffc0208fb5c5e..0000000000000000000000000000000000000000 --- a/Tests/Unit/gui2/testdareflcore/importtableheader.test.cpp +++ /dev/null @@ -1,116 +0,0 @@ -// ************************************************************************** // -// -// Reflectometry simulation software prototype -// -//! @license GNU General Public License v3 or higher (see COPYING) -//! @authors see AUTHORS -// -// ************************************************************************** // - -#include "google_test.h" -#include "gui2/dataloader/dataloader_constants.h" -#include "gui2/dataloader/dataloader_types.h" -#include "gui2/dataloader/importtableheader.h" -#include "mvvm/model/comboproperty.h" -#include "test_utils.h" - -using namespace gui2; - -//! Test the data column item -class ImportTableHeaderTest : public ::testing::Test { -public: - ~ImportTableHeaderTest(); -}; - -ImportTableHeaderTest::~ImportTableHeaderTest() = default; - -TEST_F(ImportTableHeaderTest, initialStateTwoColumn) -{ - const int column_count{2}; - ImportTableHeader header(column_count); - - EXPECT_EQ(header.columnCount(), column_count); - EXPECT_EQ(header.rowCount(), ImportTableHeader::MAX); - EXPECT_EQ(header.columnInfo().size(), column_count); - - // first column is by default represents Axis - EXPECT_EQ(header.columnInfo()[0].column, 0); - EXPECT_EQ(header.columnInfo()[0].type_name, GUI::Constants::AxisType); - EXPECT_EQ(header.columnInfo()[0].units, std::string("a.u.")); - EXPECT_EQ(header.columnInfo()[0].multiplier, 1.0); - - // second column is by default represents Intensity - EXPECT_EQ(header.columnInfo()[1].column, 1); - EXPECT_EQ(header.columnInfo()[1].type_name, GUI::Constants::IntensityType); - EXPECT_EQ(header.columnInfo()[1].units, std::string("a.u.")); - EXPECT_EQ(header.columnInfo()[1].multiplier, 1.0); -} - -TEST_F(ImportTableHeaderTest, initialStateThreeColumn) -{ - const int column_count{3}; - ImportTableHeader header(column_count); - - EXPECT_EQ(header.columnCount(), column_count); - EXPECT_EQ(header.rowCount(), ImportTableHeader::MAX); - EXPECT_EQ(header.columnInfo().size(), column_count); - - // first column is by default represents Axis - EXPECT_EQ(header.columnInfo()[0].column, 0); - EXPECT_EQ(header.columnInfo()[0].type_name, GUI::Constants::AxisType); - EXPECT_EQ(header.columnInfo()[0].units, std::string("a.u.")); - EXPECT_EQ(header.columnInfo()[0].multiplier, 1.0); - - // second column is by default represents Intensity - EXPECT_EQ(header.columnInfo()[1].column, 1); - EXPECT_EQ(header.columnInfo()[1].type_name, GUI::Constants::IntensityType); - EXPECT_EQ(header.columnInfo()[1].units, std::string("a.u.")); - EXPECT_EQ(header.columnInfo()[1].multiplier, 1.0); - - // second column is by default represents Intensity - EXPECT_EQ(header.columnInfo()[2].column, 2); - EXPECT_EQ(header.columnInfo()[2].type_name, GUI::Constants::IgnoreType); - EXPECT_EQ(header.columnInfo()[2].units, std::string("a.u.")); - EXPECT_EQ(header.columnInfo()[2].multiplier, 1.0); -} - -TEST_F(ImportTableHeaderTest, rowName) -{ - const int column_count{2}; - ImportTableHeader header(column_count); - - ASSERT_EQ(header.rowCount(), 3); - EXPECT_EQ(header.rowName(0), "Type"); - EXPECT_EQ(header.rowName(1), "Unit"); - EXPECT_EQ(header.rowName(2), "Multiplier"); -} - -TEST_F(ImportTableHeaderTest, setData) -{ - const int column_count{2}; - ImportTableHeader header(column_count); - - EXPECT_EQ(header.columnCount(), column_count); - EXPECT_EQ(header.rowCount(), ImportTableHeader::MAX); - EXPECT_EQ(header.columnInfo().size(), column_count); - - const std::vector<std::string> typeNames = { - GUI::Constants::AxisType, GUI::Constants::IntensityType, GUI::Constants::IgnoreType}; - auto combo = ModelView::ComboProperty::createFrom(typeNames); - combo.setValue(GUI::Constants::IgnoreType); - - header.setData(ImportTableHeader::TYPE, 0, QVariant::fromValue(combo)); - header.setData(ImportTableHeader::MULTIPLIER, 0, QVariant::fromValue(2.0)); - - // first column is by default represents Axis - EXPECT_EQ(header.columnInfo()[0].column, 0); - EXPECT_EQ(header.columnInfo()[0].type_name, GUI::Constants::IgnoreType); - EXPECT_EQ(header.columnInfo()[0].units, std::string("a.u.")); - EXPECT_EQ(header.columnInfo()[0].multiplier, 2.0); - - // second column is by default represents Intensity - EXPECT_EQ(header.columnInfo()[1].column, 1); - EXPECT_EQ(header.columnInfo()[1].type_name, GUI::Constants::IntensityType); - EXPECT_EQ(header.columnInfo()[1].units, std::string("a.u.")); - EXPECT_EQ(header.columnInfo()[1].multiplier, 1.0); -} diff --git a/Tests/Unit/gui2/testdareflcore/instrumentitems.test.cpp b/Tests/Unit/gui2/testdareflcore/instrumentitems.test.cpp deleted file mode 100644 index 60d5b936c8f345f49f15b850e44160f7e24af2d5..0000000000000000000000000000000000000000 --- a/Tests/Unit/gui2/testdareflcore/instrumentitems.test.cpp +++ /dev/null @@ -1,59 +0,0 @@ -// ************************************************************************** // -// -// Reflectometry simulation software prototype -// -//! @license GNU General Public License v3 or higher (see COPYING) -//! @authors see AUTHORS -// -// ************************************************************************** // - -#include "google_test.h" -#include "gui2/model/experimentaldataitems.h" -#include "gui2/model/instrumentitems.h" -#include "gui2/model/instrumentmodel.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/standarditems/axisitems.h" -#include "mvvm/standarditems/data1ditem.h" -#include "mvvm/standarditems/graphitem.h" - -using namespace gui2; -using namespace ModelView; - -//! Tests of ExperimentalDataModel. - -class InstrumentItemsTest : public ::testing::Test { -public: - ~InstrumentItemsTest(); -}; - -InstrumentItemsTest::~InstrumentItemsTest() = default; - -TEST_F(InstrumentItemsTest, experimentalScanItemInitialState) -{ - ExperimentalScanItem item; - EXPECT_EQ(item.graphItem(), nullptr); - EXPECT_TRUE(item.qScanValues().empty()); -} - -TEST_F(InstrumentItemsTest, experimentalScanGetValues) -{ - InstrumentModel model; - - // preparing DataItem - auto data_item = model.insertItem<Data1DItem>(); - std::vector<double> expected_content = {1.0, 2.0, 3.0}; - std::vector<double> expected_centers = {0.5, 1.5, 2.5}; - data_item->setAxis<FixedBinAxisItem>(3, 0.0, 3.0); - data_item->setValues(expected_content); - - // preparing GraphItem - auto graph_item = model.insertItem<GraphItem>(); - graph_item->setDataItem(data_item); - - // preparing ScanItem - auto scan_item = model.insertItem<ExperimentalScanItem>(); - scan_item->setGraphItem(graph_item); - - EXPECT_EQ(scan_item->graphItem(), graph_item); - EXPECT_EQ(scan_item->qScanValues(), expected_centers); -} diff --git a/Tests/Unit/gui2/testdareflcore/layereditoractions.test.cpp b/Tests/Unit/gui2/testdareflcore/layereditoractions.test.cpp deleted file mode 100644 index ac7a232a1b4111a39fc543a712cfba9b8c23fc99..0000000000000000000000000000000000000000 --- a/Tests/Unit/gui2/testdareflcore/layereditoractions.test.cpp +++ /dev/null @@ -1,242 +0,0 @@ -// ************************************************************************** // -// -// Reflectometry simulation software prototype -// -//! @license GNU General Public License v3 or higher (see COPYING) -//! @authors see AUTHORS -// -// ************************************************************************** // - -#include "google_test.h" -#include "gui2/layereditor/layereditoractions.h" -#include "gui2/layereditor/layerselectionmodel.h" -#include "gui2/layereditor/layerviewmodel.h" -#include "gui2/model/item_constants.h" -#include "gui2/model/sampleitems.h" -#include "gui2/model/samplemodel.h" -#include "mvvm/viewmodel/standardviewitems.h" -#include "mvvm/viewmodel/viewmodelutils.h" -#include "test_utils.h" -#include <QDebug> - -using namespace gui2; -using namespace ModelView; - -//! Tests of LayerEditorActions. - -class LayerEditorActionsTest : public ::testing::Test { -public: - ~LayerEditorActionsTest(); - - //! Test data representing MultiLayer with two layers and all machinery around: - //! ViewModel, SelectionModel and actions. - - struct TestData { - SampleModel sample_model; - LayerViewModel view_model{&sample_model}; - LayerSelectionModel selection_model{&view_model}; - LayerEditorActions actions; - SessionItem* multilayer{nullptr}; - SessionItem* top{nullptr}; - SessionItem* bottom{nullptr}; - TestData() - { - actions.setModel(&sample_model); - actions.setSelectionModel(&selection_model); - multilayer = sample_model.insertItem<MultiLayerItem>(); - top = sample_model.insertItem<LayerItem>(multilayer); - bottom = sample_model.insertItem<LayerItem>(multilayer); - view_model.setRootSessionItem(multilayer); - } - }; -}; - -LayerEditorActionsTest::~LayerEditorActionsTest() = default; - -//! Checking initial data for testing. - -TEST_F(LayerEditorActionsTest, initialState) -{ - TestData test_data; - - // checking layout of multilayer - auto layers = test_data.multilayer->getItems(MultiLayerItem::T_LAYERS); - EXPECT_EQ(layers.size(), 2); - EXPECT_EQ(layers.at(0), test_data.top); - EXPECT_EQ(layers.at(1), test_data.bottom); - - // checking, that there are no layers selected - EXPECT_EQ(test_data.selection_model.selectedItems(), std::vector<SessionItem*>()); -} - -//! Adds new layer after selected layer. - -TEST_F(LayerEditorActionsTest, addNewLayerAfterSelection) -{ - TestData test_data; - - // selecting top layer - test_data.selection_model.selectItem(test_data.top); - std::vector<SessionItem*> expected = {test_data.top}; - EXPECT_EQ(test_data.selection_model.selectedItems(), expected); - - // layout - auto ml_index = QModelIndex(); - auto top_index = test_data.view_model.index(0, 0, ml_index); - auto bottom_index = test_data.view_model.index(1, 0, ml_index); - EXPECT_EQ(test_data.view_model.rootItem()->item(), test_data.multilayer); - EXPECT_EQ(test_data.view_model.itemFromIndex(top_index)->item(), - test_data.top->getItem(LayerItem::P_NAME)); - EXPECT_EQ(test_data.view_model.itemFromIndex(bottom_index)->item(), - test_data.bottom->getItem(LayerItem::P_NAME)); - - // adding new layer after selection - test_data.actions.onAddLayer(); - - top_index = test_data.view_model.index(0, 0, ml_index); - bottom_index = test_data.view_model.index(2, 0, ml_index); - EXPECT_EQ(test_data.view_model.itemFromIndex(top_index)->item(), - test_data.top->getItem(LayerItem::P_NAME)); - EXPECT_EQ(test_data.view_model.itemFromIndex(bottom_index)->item(), - test_data.bottom->getItem(LayerItem::P_NAME)); - - // checking layout of multilayer - auto layers = test_data.multilayer->getItems(MultiLayerItem::T_LAYERS); - EXPECT_EQ(layers.size(), 3); - EXPECT_EQ(layers.at(0), test_data.top); - EXPECT_EQ(layers.at(2), test_data.bottom); - - // checking layout of viewmodel - - // checking, that new layer is selected - expected = {layers.at(1)}; - EXPECT_EQ(test_data.selection_model.selectedItems(), expected); -} - -//! Adds new multi-layer after selected layer. - -TEST_F(LayerEditorActionsTest, addNewMultiLayerAfterSelection) -{ - TestData test_data; - - // selecting top layer - test_data.selection_model.selectItem(test_data.top); - - // adding new layer after selection - test_data.actions.onAddMultiLayer(); - - // checking layout of multilayer - auto layers = test_data.multilayer->getItems(MultiLayerItem::T_LAYERS); - EXPECT_EQ(layers.size(), 3); - EXPECT_EQ(layers.at(0), test_data.top); - EXPECT_EQ(layers.at(2), test_data.bottom); - - // checking that layer was added - EXPECT_EQ(layers.at(1)->modelType(), gui2::GUI::Constants::MultiLayerItemType); - auto sublayers = layers.at(1)->getItems(MultiLayerItem::T_LAYERS); - EXPECT_EQ(sublayers.size(), 2); - - // checking, that new layer is selected - std::vector<SessionItem*> expected = {layers.at(1)}; - EXPECT_EQ(test_data.selection_model.selectedItems(), expected); -} - -//! Adds new layer when no selection exists. - -TEST_F(LayerEditorActionsTest, addNewLayerNoSelection) -{ - TestData test_data; - - // adding new layer when no selection exist - test_data.actions.onAddLayer(); - - // checking layout of multilayer - auto layers = test_data.multilayer->getItems(MultiLayerItem::T_LAYERS); - EXPECT_EQ(layers.size(), 3); - EXPECT_EQ(layers.at(0), test_data.top); - EXPECT_EQ(layers.at(1), test_data.bottom); - - // checking, that new layer is selected - std::vector<SessionItem*> expected = {layers.at(2)}; - EXPECT_EQ(test_data.selection_model.selectedItems(), expected); -} - -//! Adds new layer after selected layer. - -TEST_F(LayerEditorActionsTest, onRemoveLayer) -{ - TestData test_data; - - // selecting top layer - test_data.selection_model.selectItem(test_data.top); - - // removing selected top layer - test_data.actions.onRemove(); - - // checking layout of multilayer - auto layers = test_data.multilayer->getItems(MultiLayerItem::T_LAYERS); - EXPECT_EQ(layers.size(), 1); - EXPECT_EQ(layers.at(0), test_data.bottom); - - // checking, that next layer beneath is selected - std::vector<SessionItem*> expected = {test_data.bottom}; - EXPECT_EQ(test_data.selection_model.selectedItems(), expected); -} - -//! Move one layer up. - -TEST_F(LayerEditorActionsTest, onMoveUp) -{ - TestData test_data; - - // selecting bottom layer - test_data.selection_model.selectItem(test_data.bottom); - - // moving selected bottom layer up - test_data.actions.onMoveUp(); - - // checking layout of multilayer - auto layers = test_data.multilayer->getItems(MultiLayerItem::T_LAYERS); - EXPECT_EQ(layers.size(), 2); - EXPECT_EQ(layers.at(0), test_data.bottom); - EXPECT_EQ(layers.at(1), test_data.top); - - // checking, that former bottom layer is stil selected - std::vector<SessionItem*> expected = {test_data.bottom}; - EXPECT_EQ(test_data.selection_model.selectedItems(), expected); - - // moving up once again, nothing should change - test_data.actions.onMoveUp(); - EXPECT_EQ(layers.at(0), test_data.bottom); - EXPECT_EQ(layers.at(1), test_data.top); - EXPECT_EQ(test_data.selection_model.selectedItems(), expected); -} - -//! Move one layer up. - -TEST_F(LayerEditorActionsTest, onMoveDown) -{ - TestData test_data; - - // selecting top layer - test_data.selection_model.selectItem(test_data.top); - - // moving selected top layer down - test_data.actions.onMoveDown(); - - // checking layout of multilayer - auto layers = test_data.multilayer->getItems(MultiLayerItem::T_LAYERS); - EXPECT_EQ(layers.size(), 2); - EXPECT_EQ(layers.at(0), test_data.bottom); - EXPECT_EQ(layers.at(1), test_data.top); - - // checking, that former top layer is stil selected - std::vector<SessionItem*> expected = {test_data.top}; - EXPECT_EQ(test_data.selection_model.selectedItems(), expected); - - // moving down once again, nothing should change - test_data.actions.onMoveDown(); - EXPECT_EQ(layers.at(0), test_data.bottom); - EXPECT_EQ(layers.at(1), test_data.top); - EXPECT_EQ(test_data.selection_model.selectedItems(), expected); -} diff --git a/Tests/Unit/gui2/testdareflcore/layerelements.test.cpp b/Tests/Unit/gui2/testdareflcore/layerelements.test.cpp deleted file mode 100644 index c4f24808599f22f5e18600714f1d1ff6cab00383..0000000000000000000000000000000000000000 --- a/Tests/Unit/gui2/testdareflcore/layerelements.test.cpp +++ /dev/null @@ -1,1011 +0,0 @@ -// ************************************************************************** // -// -// Reflectometry simulation software prototype -// -//! @license GNU General Public License v3 or higher (see COPYING) -//! @authors see AUTHORS -// -// ************************************************************************** // - -#include "google_test.h" - -#include "gui2/model/materialmodel.h" -#include "gui2/model/samplemodel.h" -#include "gui2/sldeditor/graphicsscene.h" -#include "gui2/sldeditor/handleelementview.h" -#include "gui2/sldeditor/layerelementcontroller.h" -#include "gui2/sldeditor/layerelementitem.h" -#include "gui2/sldeditor/roughnesselementview.h" -#include "gui2/sldeditor/segmentelementview.h" -#include "gui2/sldeditor/sldelementmodel.h" -#include "mvvm/viewmodel/viewmodelutils.h" -#include "test_utils.h" - -#include <QColor> -#include <QGraphicsSceneMouseEvent> -#include <QSignalSpy> - -using namespace gui2; -using namespace ModelView; - -class LayerElementControllerFriend : public LayerElementController { -public: - LayerElementControllerFriend(LayerElementItem* item) : LayerElementController(item){}; - QRectF pubSideSegmentRect() const { return sideSegmentRect(); }; - QRectF pubTopSegmentRect() const { return topSegmentRect(); }; - QRectF pubFirstSegmentHandleRect() const { return firstSegmentHandleRect(); }; - QRectF pubSecondSegmentHandleRect() const { return secondSegmentHandleRect(); }; - QPainterPath pubLeftRoughnessPath() const { return leftRoughnessPath(); }; - QPainterPath pubRightRoughnessPath() const { return rightRoughnessPath(); }; - QRectF pubLeftRoughnessHandleRect() const { return leftRoughnessHandleRect(); }; - QRectF pubRightRoughnessHandleRect() const { return rightRoughnessHandleRect(); }; -}; - -class SegmentElementViewFriend : public SegmentElementView { -public: - SegmentElementViewFriend() : SegmentElementView(){}; - QRectF rectangle() const { return m_rectangle; }; - QPen pen() const { return m_pen; }; - QBrush brush() const { return m_brush; }; -}; - -class HandleElementViewFriend : public HandleElementView { -public: - HandleElementViewFriend() : HandleElementView(){}; - QRectF rectangle() const { return m_rectangle; }; - QPen pen() const { return m_pen; }; - QBrush brush() const { return m_brush; }; -}; - -class RoughnessElementViewFriend : public RoughnessElementView { -public: - RoughnessElementViewFriend() : RoughnessElementView(){}; - QPainterPath leftPath() const { return m_left_path; }; - QPainterPath rightPath() const { return m_right_path; }; - QPen pen() const { return m_pen; }; - QBrush brush() const { return m_brush; }; -}; - -//! Tests of LayerViewController. -class LayerElementTest : public ::testing::Test { -public: - ~LayerElementTest(); - struct TestData { - LayerElementItem* exposed_layer_item{nullptr}; - LayerElementControllerFriend* exposed_controller{nullptr}; - - SampleModel* sample_model{nullptr}; - MaterialModel* material_model{nullptr}; - SLDElementModel* view_model{nullptr}; - - LayerElementItem* above_layer_item{nullptr}; - LayerElementItem* middle_layer_item{nullptr}; - LayerElementItem* below_layer_item{nullptr}; - - LayerElementController* above_controller{nullptr}; - LayerElementController* middle_controller{nullptr}; - LayerElementController* below_controller{nullptr}; - - GraphicsScene* scene{nullptr}; - - TestData() - { - exposed_layer_item = new LayerElementItem(); - exposed_controller = new LayerElementControllerFriend(exposed_layer_item); - - sample_model = new SampleModel(); - view_model = new SLDElementModel(); - above_layer_item = view_model->addLayer(); - middle_layer_item = view_model->addLayer(); - below_layer_item = view_model->addLayer(); - - // FIXME multiple memory leakages - above_controller = new LayerElementController(above_layer_item); - middle_controller = new LayerElementController(middle_layer_item); - below_controller = new LayerElementController(below_layer_item); - - scene = new GraphicsScene(); - } - }; -}; - -LayerElementTest::~LayerElementTest() = default; - -//! Test the creation of the controller - -TEST_F(LayerElementTest, initialstate) -{ - TestData test_data; - - //! Check the layer item system init - EXPECT_NE(nullptr, test_data.middle_controller->layerElementItem()); - - //! Check the layer system init - EXPECT_EQ(nullptr, test_data.middle_controller->layerAbove()); - EXPECT_EQ(nullptr, test_data.middle_controller->layerBelow()); - - //! Check the segment system init - EXPECT_EQ(nullptr, test_data.middle_controller->topSegment()); - EXPECT_EQ(nullptr, test_data.middle_controller->sideSegment()); - - //! Check the scene init - EXPECT_EQ(nullptr, test_data.middle_controller->scene()); - - //! Check the handles init - EXPECT_EQ(nullptr, test_data.middle_controller->firstSegmentHandle()); - EXPECT_EQ(nullptr, test_data.middle_controller->secondSegmentHandle()); - - //! Check the roughness init - EXPECT_EQ(nullptr, test_data.middle_controller->roughness()); - - //! Check the roughness handles init - EXPECT_EQ(nullptr, test_data.middle_controller->leftRoughnessHandle()); - EXPECT_EQ(nullptr, test_data.middle_controller->rightRoughnessHandle()); -} - -TEST_F(LayerElementTest, autopopulate) -{ - TestData test_data; - test_data.middle_controller->autoPopulate(); - - //! Check the layer item system init - EXPECT_NE(nullptr, test_data.middle_controller->layerElementItem()); - - //! Check the layer system init - EXPECT_EQ(nullptr, test_data.middle_controller->layerAbove()); - EXPECT_EQ(nullptr, test_data.middle_controller->layerBelow()); - - //! Check the segment system init - EXPECT_NE(nullptr, test_data.middle_controller->topSegment()); - EXPECT_NE(nullptr, test_data.middle_controller->sideSegment()); - - //! Check the scene init - EXPECT_EQ(nullptr, test_data.middle_controller->scene()); - - //! Check the handles init - EXPECT_NE(nullptr, test_data.middle_controller->firstSegmentHandle()); - EXPECT_NE(nullptr, test_data.middle_controller->secondSegmentHandle()); - - //! Check the roughness init - EXPECT_NE(nullptr, test_data.middle_controller->roughness()); - - //! Check the roughness handles init - EXPECT_NE(nullptr, test_data.middle_controller->leftRoughnessHandle()); - EXPECT_NE(nullptr, test_data.middle_controller->rightRoughnessHandle()); -} - -TEST_F(LayerElementTest, addremoveabovebelow) -{ - TestData test_data; - - EXPECT_EQ(nullptr, test_data.above_controller->layerAbove()); - EXPECT_EQ(nullptr, test_data.above_controller->layerBelow()); - EXPECT_EQ(nullptr, test_data.middle_controller->layerAbove()); - EXPECT_EQ(nullptr, test_data.middle_controller->layerBelow()); - EXPECT_EQ(nullptr, test_data.below_controller->layerAbove()); - EXPECT_EQ(nullptr, test_data.below_controller->layerBelow()); - - test_data.middle_controller->setLayerAbove(test_data.above_controller); - EXPECT_EQ(nullptr, test_data.above_controller->layerAbove()); - EXPECT_EQ(test_data.middle_controller, test_data.above_controller->layerBelow()); - EXPECT_EQ(test_data.above_controller, test_data.middle_controller->layerAbove()); - EXPECT_EQ(nullptr, test_data.middle_controller->layerBelow()); - EXPECT_EQ(nullptr, test_data.below_controller->layerAbove()); - EXPECT_EQ(nullptr, test_data.below_controller->layerBelow()); - - test_data.middle_controller->setLayerBelow(test_data.below_controller); - EXPECT_EQ(nullptr, test_data.above_controller->layerAbove()); - EXPECT_EQ(test_data.middle_controller, test_data.above_controller->layerBelow()); - EXPECT_EQ(test_data.above_controller, test_data.middle_controller->layerAbove()); - EXPECT_EQ(test_data.below_controller, test_data.middle_controller->layerBelow()); - EXPECT_EQ(test_data.middle_controller, test_data.below_controller->layerAbove()); - EXPECT_EQ(nullptr, test_data.below_controller->layerBelow()); - - test_data.middle_controller->unsetLayerAbove(); - EXPECT_EQ(nullptr, test_data.above_controller->layerAbove()); - EXPECT_EQ(nullptr, test_data.above_controller->layerBelow()); - EXPECT_EQ(nullptr, test_data.middle_controller->layerAbove()); - EXPECT_EQ(test_data.below_controller, test_data.middle_controller->layerBelow()); - EXPECT_EQ(test_data.middle_controller, test_data.below_controller->layerAbove()); - EXPECT_EQ(nullptr, test_data.below_controller->layerBelow()); - - test_data.middle_controller->unsetLayerBelow(); - EXPECT_EQ(nullptr, test_data.above_controller->layerAbove()); - EXPECT_EQ(nullptr, test_data.above_controller->layerBelow()); - EXPECT_EQ(nullptr, test_data.middle_controller->layerAbove()); - EXPECT_EQ(nullptr, test_data.middle_controller->layerBelow()); - EXPECT_EQ(nullptr, test_data.below_controller->layerAbove()); - EXPECT_EQ(nullptr, test_data.below_controller->layerBelow()); -} - -TEST_F(LayerElementTest, testgeometriesupdate) -{ - TestData test_data; - - // Grab the item to change the properties - LayerElementItem* item = test_data.exposed_controller->layerElementItem(); - - double side_thickness = 5.; - double top_thickness = 5.; - double handle_radius = 5.; - double r_handle_radius = 5.; - double roughness = 5.; - double pos = 10.; - double width = 20.; - double height = 30.; - - item->setProperty(LayerElementItem::P_X_POS, pos); - item->setProperty(LayerElementItem::P_WIDTH, width); - item->setProperty(LayerElementItem::P_HEIGHT, height); - item->setProperty(LayerElementItem::P_ROUGHNESS, roughness); - item->setProperty(LayerElementItem::P_SIDE_THICKNESS, side_thickness); - item->setProperty(LayerElementItem::P_TOP_THICKNESS, top_thickness); - item->setProperty(LayerElementItem::P_HANDLE_RADIUS, handle_radius); - item->setProperty(LayerElementItem::P_R_HANDLE_RADIUS, r_handle_radius); - - // Init rectangle vars - QRectF side_rect; - QRectF top_rect; - QRectF first_handle_rect; - QRectF second_handle_rect; - QPainterPath left_roughness_path; - QPainterPath right_roughness_path; - QRectF left_roughness_handle_rec; - QRectF right_roughness_handle_rec; - - // #############################################################################s - // Check initial state - side_rect = test_data.exposed_controller->pubSideSegmentRect(); - top_rect = test_data.exposed_controller->pubTopSegmentRect(); - first_handle_rect = test_data.exposed_controller->pubFirstSegmentHandleRect(); - second_handle_rect = test_data.exposed_controller->pubSecondSegmentHandleRect(); - left_roughness_path = test_data.exposed_controller->pubLeftRoughnessPath(); - right_roughness_path = test_data.exposed_controller->pubRightRoughnessPath(); - left_roughness_handle_rec = test_data.exposed_controller->pubLeftRoughnessHandleRect(); - right_roughness_handle_rec = test_data.exposed_controller->pubRightRoughnessHandleRect(); - - EXPECT_DOUBLE_EQ(pos - side_thickness / 2., side_rect.x()); - EXPECT_DOUBLE_EQ(0., side_rect.y()); - EXPECT_DOUBLE_EQ(side_thickness, side_rect.width()); - EXPECT_DOUBLE_EQ(height, side_rect.height()); - - EXPECT_DOUBLE_EQ(pos, top_rect.x()); - EXPECT_DOUBLE_EQ(height - top_thickness / 2., top_rect.y()); - EXPECT_DOUBLE_EQ(width, top_rect.width()); - EXPECT_DOUBLE_EQ(top_thickness, top_rect.height()); - - EXPECT_DOUBLE_EQ(pos - handle_radius, first_handle_rect.x()); - EXPECT_DOUBLE_EQ(-handle_radius, first_handle_rect.y()); - EXPECT_DOUBLE_EQ(2 * handle_radius, first_handle_rect.width()); - EXPECT_DOUBLE_EQ(2 * handle_radius, first_handle_rect.height()); - - EXPECT_DOUBLE_EQ(pos - handle_radius, second_handle_rect.x()); - EXPECT_DOUBLE_EQ(height - handle_radius, second_handle_rect.y()); - EXPECT_DOUBLE_EQ(2 * handle_radius, second_handle_rect.width()); - EXPECT_DOUBLE_EQ(2 * handle_radius, second_handle_rect.height()); - - EXPECT_DOUBLE_EQ(pos - roughness, left_roughness_path.boundingRect().x()); - EXPECT_DOUBLE_EQ(0., left_roughness_path.boundingRect().y()); - EXPECT_DOUBLE_EQ(roughness, left_roughness_path.boundingRect().width()); - EXPECT_DOUBLE_EQ(height, left_roughness_path.boundingRect().height()); - - EXPECT_DOUBLE_EQ(pos, right_roughness_path.boundingRect().x()); - EXPECT_DOUBLE_EQ(0., right_roughness_path.boundingRect().y()); - EXPECT_DOUBLE_EQ(roughness, right_roughness_path.boundingRect().width()); - EXPECT_DOUBLE_EQ(height, right_roughness_path.boundingRect().height()); - - EXPECT_DOUBLE_EQ(pos - roughness - r_handle_radius, left_roughness_handle_rec.x()); - EXPECT_DOUBLE_EQ(height / 2 - r_handle_radius, left_roughness_handle_rec.y()); - EXPECT_DOUBLE_EQ(2 * r_handle_radius, left_roughness_handle_rec.width()); - EXPECT_DOUBLE_EQ(2 * r_handle_radius, left_roughness_handle_rec.height()); - - EXPECT_DOUBLE_EQ(pos + roughness - r_handle_radius, right_roughness_handle_rec.x()); - EXPECT_DOUBLE_EQ(height / 2 - r_handle_radius, right_roughness_handle_rec.y()); - EXPECT_DOUBLE_EQ(2 * r_handle_radius, right_roughness_handle_rec.width()); - EXPECT_DOUBLE_EQ(2 * r_handle_radius, right_roughness_handle_rec.height()); - - // #############################################################################s - // Check x move - pos = 22.; - item->setProperty(LayerElementItem::P_X_POS, pos); - side_rect = test_data.exposed_controller->pubSideSegmentRect(); - top_rect = test_data.exposed_controller->pubTopSegmentRect(); - first_handle_rect = test_data.exposed_controller->pubFirstSegmentHandleRect(); - second_handle_rect = test_data.exposed_controller->pubSecondSegmentHandleRect(); - left_roughness_path = test_data.exposed_controller->pubLeftRoughnessPath(); - right_roughness_path = test_data.exposed_controller->pubRightRoughnessPath(); - left_roughness_handle_rec = test_data.exposed_controller->pubLeftRoughnessHandleRect(); - right_roughness_handle_rec = test_data.exposed_controller->pubRightRoughnessHandleRect(); - - EXPECT_DOUBLE_EQ(pos - side_thickness / 2., side_rect.x()); - EXPECT_DOUBLE_EQ(0., side_rect.y()); - EXPECT_DOUBLE_EQ(side_thickness, side_rect.width()); - EXPECT_DOUBLE_EQ(height, side_rect.height()); - - EXPECT_DOUBLE_EQ(pos, top_rect.x()); - EXPECT_DOUBLE_EQ(height - top_thickness / 2., top_rect.y()); - EXPECT_DOUBLE_EQ(width, top_rect.width()); - EXPECT_DOUBLE_EQ(top_thickness, top_rect.height()); - - EXPECT_DOUBLE_EQ(pos - handle_radius, first_handle_rect.x()); - EXPECT_DOUBLE_EQ(-handle_radius, first_handle_rect.y()); - EXPECT_DOUBLE_EQ(2 * handle_radius, first_handle_rect.width()); - EXPECT_DOUBLE_EQ(2 * handle_radius, first_handle_rect.height()); - - EXPECT_DOUBLE_EQ(pos - handle_radius, second_handle_rect.x()); - EXPECT_DOUBLE_EQ(height - handle_radius, second_handle_rect.y()); - EXPECT_DOUBLE_EQ(2 * handle_radius, second_handle_rect.width()); - EXPECT_DOUBLE_EQ(2 * handle_radius, second_handle_rect.height()); - - EXPECT_DOUBLE_EQ(pos - roughness, left_roughness_path.boundingRect().x()); - EXPECT_DOUBLE_EQ(0., left_roughness_path.boundingRect().y()); - EXPECT_DOUBLE_EQ(roughness, left_roughness_path.boundingRect().width()); - EXPECT_DOUBLE_EQ(height, left_roughness_path.boundingRect().height()); - - EXPECT_DOUBLE_EQ(pos, right_roughness_path.boundingRect().x()); - EXPECT_DOUBLE_EQ(0., right_roughness_path.boundingRect().y()); - EXPECT_DOUBLE_EQ(roughness, right_roughness_path.boundingRect().width()); - EXPECT_DOUBLE_EQ(height, right_roughness_path.boundingRect().height()); - - EXPECT_DOUBLE_EQ(pos - roughness - r_handle_radius, left_roughness_handle_rec.x()); - EXPECT_DOUBLE_EQ(height / 2 - r_handle_radius, left_roughness_handle_rec.y()); - EXPECT_DOUBLE_EQ(2 * r_handle_radius, left_roughness_handle_rec.width()); - EXPECT_DOUBLE_EQ(2 * r_handle_radius, left_roughness_handle_rec.height()); - - EXPECT_DOUBLE_EQ(pos + roughness - r_handle_radius, right_roughness_handle_rec.x()); - EXPECT_DOUBLE_EQ(height / 2 - r_handle_radius, right_roughness_handle_rec.y()); - EXPECT_DOUBLE_EQ(2 * r_handle_radius, right_roughness_handle_rec.width()); - EXPECT_DOUBLE_EQ(2 * r_handle_radius, right_roughness_handle_rec.height()); - - // #############################################################################s - // Check width change - width = 22.; - item->setProperty(LayerElementItem::P_WIDTH, width); - side_rect = test_data.exposed_controller->pubSideSegmentRect(); - top_rect = test_data.exposed_controller->pubTopSegmentRect(); - first_handle_rect = test_data.exposed_controller->pubFirstSegmentHandleRect(); - second_handle_rect = test_data.exposed_controller->pubSecondSegmentHandleRect(); - left_roughness_path = test_data.exposed_controller->pubLeftRoughnessPath(); - right_roughness_path = test_data.exposed_controller->pubRightRoughnessPath(); - left_roughness_handle_rec = test_data.exposed_controller->pubLeftRoughnessHandleRect(); - right_roughness_handle_rec = test_data.exposed_controller->pubRightRoughnessHandleRect(); - - EXPECT_DOUBLE_EQ(pos - side_thickness / 2., side_rect.x()); - EXPECT_DOUBLE_EQ(0., side_rect.y()); - EXPECT_DOUBLE_EQ(side_thickness, side_rect.width()); - EXPECT_DOUBLE_EQ(height, side_rect.height()); - - EXPECT_DOUBLE_EQ(pos, top_rect.x()); - EXPECT_DOUBLE_EQ(height - top_thickness / 2., top_rect.y()); - EXPECT_DOUBLE_EQ(width, top_rect.width()); - EXPECT_DOUBLE_EQ(top_thickness, top_rect.height()); - - EXPECT_DOUBLE_EQ(pos - handle_radius, first_handle_rect.x()); - EXPECT_DOUBLE_EQ(-handle_radius, first_handle_rect.y()); - EXPECT_DOUBLE_EQ(2 * handle_radius, first_handle_rect.width()); - EXPECT_DOUBLE_EQ(2 * handle_radius, first_handle_rect.height()); - - EXPECT_DOUBLE_EQ(pos - handle_radius, second_handle_rect.x()); - EXPECT_DOUBLE_EQ(height - handle_radius, second_handle_rect.y()); - EXPECT_DOUBLE_EQ(2 * handle_radius, second_handle_rect.width()); - EXPECT_DOUBLE_EQ(2 * handle_radius, second_handle_rect.height()); - - EXPECT_DOUBLE_EQ(pos - roughness, left_roughness_path.boundingRect().x()); - EXPECT_DOUBLE_EQ(0., left_roughness_path.boundingRect().y()); - EXPECT_DOUBLE_EQ(roughness, left_roughness_path.boundingRect().width()); - EXPECT_DOUBLE_EQ(height, left_roughness_path.boundingRect().height()); - - EXPECT_DOUBLE_EQ(pos, right_roughness_path.boundingRect().x()); - EXPECT_DOUBLE_EQ(0., right_roughness_path.boundingRect().y()); - EXPECT_DOUBLE_EQ(roughness, right_roughness_path.boundingRect().width()); - EXPECT_DOUBLE_EQ(height, right_roughness_path.boundingRect().height()); - - EXPECT_DOUBLE_EQ(pos - roughness - r_handle_radius, left_roughness_handle_rec.x()); - EXPECT_DOUBLE_EQ(height / 2 - r_handle_radius, left_roughness_handle_rec.y()); - EXPECT_DOUBLE_EQ(2 * r_handle_radius, left_roughness_handle_rec.width()); - EXPECT_DOUBLE_EQ(2 * r_handle_radius, left_roughness_handle_rec.height()); - - EXPECT_DOUBLE_EQ(pos + roughness - r_handle_radius, right_roughness_handle_rec.x()); - EXPECT_DOUBLE_EQ(height / 2 - r_handle_radius, right_roughness_handle_rec.y()); - EXPECT_DOUBLE_EQ(2 * r_handle_radius, right_roughness_handle_rec.width()); - EXPECT_DOUBLE_EQ(2 * r_handle_radius, right_roughness_handle_rec.height()); - - // #############################################################################s - // Check heigh change - height = 35.; - item->setProperty(LayerElementItem::P_HEIGHT, height); - side_rect = test_data.exposed_controller->pubSideSegmentRect(); - top_rect = test_data.exposed_controller->pubTopSegmentRect(); - first_handle_rect = test_data.exposed_controller->pubFirstSegmentHandleRect(); - second_handle_rect = test_data.exposed_controller->pubSecondSegmentHandleRect(); - left_roughness_path = test_data.exposed_controller->pubLeftRoughnessPath(); - right_roughness_path = test_data.exposed_controller->pubRightRoughnessPath(); - left_roughness_handle_rec = test_data.exposed_controller->pubLeftRoughnessHandleRect(); - right_roughness_handle_rec = test_data.exposed_controller->pubRightRoughnessHandleRect(); - - EXPECT_DOUBLE_EQ(pos - side_thickness / 2., side_rect.x()); - EXPECT_DOUBLE_EQ(0., side_rect.y()); - EXPECT_DOUBLE_EQ(side_thickness, side_rect.width()); - EXPECT_DOUBLE_EQ(height, side_rect.height()); - - EXPECT_DOUBLE_EQ(pos, top_rect.x()); - EXPECT_DOUBLE_EQ(height - top_thickness / 2., top_rect.y()); - EXPECT_DOUBLE_EQ(width, top_rect.width()); - EXPECT_DOUBLE_EQ(top_thickness, top_rect.height()); - - EXPECT_DOUBLE_EQ(pos - handle_radius, first_handle_rect.x()); - EXPECT_DOUBLE_EQ(-handle_radius, first_handle_rect.y()); - EXPECT_DOUBLE_EQ(2 * handle_radius, first_handle_rect.width()); - EXPECT_DOUBLE_EQ(2 * handle_radius, first_handle_rect.height()); - - EXPECT_DOUBLE_EQ(pos - handle_radius, second_handle_rect.x()); - EXPECT_DOUBLE_EQ(height - handle_radius, second_handle_rect.y()); - EXPECT_DOUBLE_EQ(2 * handle_radius, second_handle_rect.width()); - EXPECT_DOUBLE_EQ(2 * handle_radius, second_handle_rect.height()); - - EXPECT_DOUBLE_EQ(pos - roughness, left_roughness_path.boundingRect().x()); - EXPECT_DOUBLE_EQ(0., left_roughness_path.boundingRect().y()); - EXPECT_DOUBLE_EQ(roughness, left_roughness_path.boundingRect().width()); - EXPECT_DOUBLE_EQ(height, left_roughness_path.boundingRect().height()); - - EXPECT_DOUBLE_EQ(pos, right_roughness_path.boundingRect().x()); - EXPECT_DOUBLE_EQ(0., right_roughness_path.boundingRect().y()); - EXPECT_DOUBLE_EQ(roughness, right_roughness_path.boundingRect().width()); - EXPECT_DOUBLE_EQ(height, right_roughness_path.boundingRect().height()); - - EXPECT_DOUBLE_EQ(pos - roughness - r_handle_radius, left_roughness_handle_rec.x()); - EXPECT_DOUBLE_EQ(height / 2 - r_handle_radius, left_roughness_handle_rec.y()); - EXPECT_DOUBLE_EQ(2 * r_handle_radius, left_roughness_handle_rec.width()); - EXPECT_DOUBLE_EQ(2 * r_handle_radius, left_roughness_handle_rec.height()); - - EXPECT_DOUBLE_EQ(pos + roughness - r_handle_radius, right_roughness_handle_rec.x()); - EXPECT_DOUBLE_EQ(height / 2 - r_handle_radius, right_roughness_handle_rec.y()); - EXPECT_DOUBLE_EQ(2 * r_handle_radius, right_roughness_handle_rec.width()); - EXPECT_DOUBLE_EQ(2 * r_handle_radius, right_roughness_handle_rec.height()); -} - -TEST_F(LayerElementTest, testviewsupdate) -{ - TestData test_data; - - // Connect the controller to the model - test_data.middle_controller->connectToModel(); - - // Set the segments - auto side_segment = new SegmentElementViewFriend(); - auto top_segment = new SegmentElementViewFriend(); - test_data.middle_controller->setSideSegment(side_segment); - test_data.middle_controller->setTopSegment(top_segment); - - // Set the handles - auto first_handle = new HandleElementViewFriend(); - auto second_handle = new HandleElementViewFriend(); - test_data.middle_controller->setSegmentHandles(first_handle, second_handle); - - // Set the roughness view item - auto roughness_view = new RoughnessElementViewFriend(); - test_data.middle_controller->setRoughness(roughness_view); - - // Set the roughness handles - auto left_handle = new HandleElementViewFriend(); - auto right_handle = new HandleElementViewFriend(); - test_data.middle_controller->setRoughnessHandles(left_handle, right_handle); - - // Grab the item to change the properties - LayerElementItem* item = test_data.middle_controller->layerElementItem(); - - double side_thickness = 5.; - double top_thickness = 5.; - double handle_radius = 5.; - double r_handle_radius = 5.; - double roughness = 5.; - double pos = 10.; - double width = 20.; - double height = 30.; - - item->setProperty(LayerElementItem::P_X_POS, pos); - item->setProperty(LayerElementItem::P_WIDTH, width); - item->setProperty(LayerElementItem::P_HEIGHT, height); - item->setProperty(LayerElementItem::P_ROUGHNESS, roughness); - item->setProperty(LayerElementItem::P_SIDE_THICKNESS, side_thickness); - item->setProperty(LayerElementItem::P_TOP_THICKNESS, top_thickness); - item->setProperty(LayerElementItem::P_HANDLE_RADIUS, handle_radius); - item->setProperty(LayerElementItem::P_R_HANDLE_RADIUS, r_handle_radius); - - // Init rectangle vars - QRectF side_rect; - QRectF top_rect; - QRectF first_handle_rect; - QRectF second_handle_rect; - QPainterPath left_roughness_path; - QPainterPath right_roughness_path; - QRectF left_roughness_handle_rec; - QRectF right_roughness_handle_rec; - - // #############################################################################s - // Check initial state - side_rect = side_segment->rectangle(); - top_rect = top_segment->rectangle(); - first_handle_rect = first_handle->rectangle(); - second_handle_rect = second_handle->rectangle(); - left_roughness_path = roughness_view->leftPath(); - right_roughness_path = roughness_view->rightPath(); - left_roughness_handle_rec = left_handle->rectangle(); - right_roughness_handle_rec = right_handle->rectangle(); - - EXPECT_DOUBLE_EQ(pos - side_thickness / 2., side_rect.x()); - EXPECT_DOUBLE_EQ(0., side_rect.y()); - EXPECT_DOUBLE_EQ(side_thickness, side_rect.width()); - EXPECT_DOUBLE_EQ(height, side_rect.height()); - - EXPECT_DOUBLE_EQ(pos, top_rect.x()); - EXPECT_DOUBLE_EQ(height - top_thickness / 2., top_rect.y()); - EXPECT_DOUBLE_EQ(width, top_rect.width()); - EXPECT_DOUBLE_EQ(top_thickness, top_rect.height()); - - EXPECT_DOUBLE_EQ(pos - handle_radius, first_handle_rect.x()); - EXPECT_DOUBLE_EQ(-handle_radius, first_handle_rect.y()); - EXPECT_DOUBLE_EQ(2 * handle_radius, first_handle_rect.width()); - EXPECT_DOUBLE_EQ(2 * handle_radius, first_handle_rect.height()); - - EXPECT_DOUBLE_EQ(pos - handle_radius, second_handle_rect.x()); - EXPECT_DOUBLE_EQ(height - handle_radius, second_handle_rect.y()); - EXPECT_DOUBLE_EQ(2 * handle_radius, second_handle_rect.width()); - EXPECT_DOUBLE_EQ(2 * handle_radius, second_handle_rect.height()); - - EXPECT_DOUBLE_EQ(pos - roughness, left_roughness_path.boundingRect().x()); - EXPECT_DOUBLE_EQ(0., left_roughness_path.boundingRect().y()); - EXPECT_DOUBLE_EQ(roughness, left_roughness_path.boundingRect().width()); - EXPECT_DOUBLE_EQ(height, left_roughness_path.boundingRect().height()); - - EXPECT_DOUBLE_EQ(pos, right_roughness_path.boundingRect().x()); - EXPECT_DOUBLE_EQ(0., right_roughness_path.boundingRect().y()); - EXPECT_DOUBLE_EQ(roughness, right_roughness_path.boundingRect().width()); - EXPECT_DOUBLE_EQ(height, right_roughness_path.boundingRect().height()); - - EXPECT_DOUBLE_EQ(pos - roughness - r_handle_radius, left_roughness_handle_rec.x()); - EXPECT_DOUBLE_EQ(height / 2 - r_handle_radius, left_roughness_handle_rec.y()); - EXPECT_DOUBLE_EQ(2 * r_handle_radius, left_roughness_handle_rec.width()); - EXPECT_DOUBLE_EQ(2 * r_handle_radius, left_roughness_handle_rec.height()); - - EXPECT_DOUBLE_EQ(pos + roughness - r_handle_radius, right_roughness_handle_rec.x()); - EXPECT_DOUBLE_EQ(height / 2 - r_handle_radius, right_roughness_handle_rec.y()); - EXPECT_DOUBLE_EQ(2 * r_handle_radius, right_roughness_handle_rec.width()); - EXPECT_DOUBLE_EQ(2 * r_handle_radius, right_roughness_handle_rec.height()); - - // #############################################################################s - // Test change of position - pos = 22.; - item->setProperty(LayerElementItem::P_X_POS, pos); - top_rect = top_segment->rectangle(); - side_rect = side_segment->rectangle(); - first_handle_rect = first_handle->rectangle(); - second_handle_rect = second_handle->rectangle(); - left_roughness_path = roughness_view->leftPath(); - right_roughness_path = roughness_view->rightPath(); - left_roughness_handle_rec = left_handle->rectangle(); - right_roughness_handle_rec = right_handle->rectangle(); - - EXPECT_DOUBLE_EQ(pos - side_thickness / 2., side_rect.x()); - EXPECT_DOUBLE_EQ(0., side_rect.y()); - EXPECT_DOUBLE_EQ(side_thickness, side_rect.width()); - EXPECT_DOUBLE_EQ(height, side_rect.height()); - - EXPECT_DOUBLE_EQ(pos, top_rect.x()); - EXPECT_DOUBLE_EQ(height - top_thickness / 2., top_rect.y()); - EXPECT_DOUBLE_EQ(width, top_rect.width()); - EXPECT_DOUBLE_EQ(top_thickness, top_rect.height()); - - EXPECT_DOUBLE_EQ(pos - handle_radius, first_handle_rect.x()); - EXPECT_DOUBLE_EQ(-handle_radius, first_handle_rect.y()); - EXPECT_DOUBLE_EQ(2 * handle_radius, first_handle_rect.width()); - EXPECT_DOUBLE_EQ(2 * handle_radius, first_handle_rect.height()); - - EXPECT_DOUBLE_EQ(pos - handle_radius, second_handle_rect.x()); - EXPECT_DOUBLE_EQ(height - handle_radius, second_handle_rect.y()); - EXPECT_DOUBLE_EQ(2 * handle_radius, second_handle_rect.width()); - EXPECT_DOUBLE_EQ(2 * handle_radius, second_handle_rect.height()); - - EXPECT_DOUBLE_EQ(pos - roughness, left_roughness_path.boundingRect().x()); - EXPECT_DOUBLE_EQ(0., left_roughness_path.boundingRect().y()); - EXPECT_DOUBLE_EQ(roughness, left_roughness_path.boundingRect().width()); - EXPECT_DOUBLE_EQ(height, left_roughness_path.boundingRect().height()); - - EXPECT_DOUBLE_EQ(pos, right_roughness_path.boundingRect().x()); - EXPECT_DOUBLE_EQ(0., right_roughness_path.boundingRect().y()); - EXPECT_DOUBLE_EQ(roughness, right_roughness_path.boundingRect().width()); - EXPECT_DOUBLE_EQ(height, right_roughness_path.boundingRect().height()); - - EXPECT_DOUBLE_EQ(pos - roughness - r_handle_radius, left_roughness_handle_rec.x()); - EXPECT_DOUBLE_EQ(height / 2 - r_handle_radius, left_roughness_handle_rec.y()); - EXPECT_DOUBLE_EQ(2 * r_handle_radius, left_roughness_handle_rec.width()); - EXPECT_DOUBLE_EQ(2 * r_handle_radius, left_roughness_handle_rec.height()); - - EXPECT_DOUBLE_EQ(pos + roughness - r_handle_radius, right_roughness_handle_rec.x()); - EXPECT_DOUBLE_EQ(height / 2 - r_handle_radius, right_roughness_handle_rec.y()); - EXPECT_DOUBLE_EQ(2 * r_handle_radius, right_roughness_handle_rec.width()); - EXPECT_DOUBLE_EQ(2 * r_handle_radius, right_roughness_handle_rec.height()); - - // #############################################################################s - // Test change of width - width = 22.; - item->setProperty(LayerElementItem::P_WIDTH, width); - top_rect = top_segment->rectangle(); - side_rect = side_segment->rectangle(); - first_handle_rect = first_handle->rectangle(); - second_handle_rect = second_handle->rectangle(); - left_roughness_path = roughness_view->leftPath(); - right_roughness_path = roughness_view->rightPath(); - left_roughness_handle_rec = left_handle->rectangle(); - right_roughness_handle_rec = right_handle->rectangle(); - - EXPECT_DOUBLE_EQ(pos - side_thickness / 2., side_rect.x()); - EXPECT_DOUBLE_EQ(0., side_rect.y()); - EXPECT_DOUBLE_EQ(side_thickness, side_rect.width()); - EXPECT_DOUBLE_EQ(height, side_rect.height()); - - EXPECT_DOUBLE_EQ(pos, top_rect.x()); - EXPECT_DOUBLE_EQ(height - top_thickness / 2., top_rect.y()); - EXPECT_DOUBLE_EQ(width, top_rect.width()); - EXPECT_DOUBLE_EQ(top_thickness, top_rect.height()); - - EXPECT_DOUBLE_EQ(pos - handle_radius, first_handle_rect.x()); - EXPECT_DOUBLE_EQ(-handle_radius, first_handle_rect.y()); - EXPECT_DOUBLE_EQ(2 * handle_radius, first_handle_rect.width()); - EXPECT_DOUBLE_EQ(2 * handle_radius, first_handle_rect.height()); - - EXPECT_DOUBLE_EQ(pos - handle_radius, second_handle_rect.x()); - EXPECT_DOUBLE_EQ(height - handle_radius, second_handle_rect.y()); - EXPECT_DOUBLE_EQ(2 * handle_radius, second_handle_rect.width()); - EXPECT_DOUBLE_EQ(2 * handle_radius, second_handle_rect.height()); - - EXPECT_DOUBLE_EQ(pos - roughness, left_roughness_path.boundingRect().x()); - EXPECT_DOUBLE_EQ(0., left_roughness_path.boundingRect().y()); - EXPECT_DOUBLE_EQ(roughness, left_roughness_path.boundingRect().width()); - EXPECT_DOUBLE_EQ(height, left_roughness_path.boundingRect().height()); - - EXPECT_DOUBLE_EQ(pos, right_roughness_path.boundingRect().x()); - EXPECT_DOUBLE_EQ(0., right_roughness_path.boundingRect().y()); - EXPECT_DOUBLE_EQ(roughness, right_roughness_path.boundingRect().width()); - EXPECT_DOUBLE_EQ(height, right_roughness_path.boundingRect().height()); - - EXPECT_DOUBLE_EQ(pos - roughness - r_handle_radius, left_roughness_handle_rec.x()); - EXPECT_DOUBLE_EQ(height / 2 - r_handle_radius, left_roughness_handle_rec.y()); - EXPECT_DOUBLE_EQ(2 * r_handle_radius, left_roughness_handle_rec.width()); - EXPECT_DOUBLE_EQ(2 * r_handle_radius, left_roughness_handle_rec.height()); - - EXPECT_DOUBLE_EQ(pos + roughness - r_handle_radius, right_roughness_handle_rec.x()); - EXPECT_DOUBLE_EQ(height / 2 - r_handle_radius, right_roughness_handle_rec.y()); - EXPECT_DOUBLE_EQ(2 * r_handle_radius, right_roughness_handle_rec.width()); - EXPECT_DOUBLE_EQ(2 * r_handle_radius, right_roughness_handle_rec.height()); - - // #############################################################################s - // Test propagation change of height - height = 35.; - item->setProperty(LayerElementItem::P_HEIGHT, height); - top_rect = top_segment->rectangle(); - side_rect = side_segment->rectangle(); - first_handle_rect = first_handle->rectangle(); - second_handle_rect = second_handle->rectangle(); - left_roughness_path = roughness_view->leftPath(); - right_roughness_path = roughness_view->rightPath(); - left_roughness_handle_rec = left_handle->rectangle(); - right_roughness_handle_rec = right_handle->rectangle(); - - EXPECT_DOUBLE_EQ(pos - side_thickness / 2., side_rect.x()); - EXPECT_DOUBLE_EQ(0., side_rect.y()); - EXPECT_DOUBLE_EQ(side_thickness, side_rect.width()); - EXPECT_DOUBLE_EQ(height, side_rect.height()); - - EXPECT_DOUBLE_EQ(pos, top_rect.x()); - EXPECT_DOUBLE_EQ(height - top_thickness / 2., top_rect.y()); - EXPECT_DOUBLE_EQ(width, top_rect.width()); - EXPECT_DOUBLE_EQ(top_thickness, top_rect.height()); - - EXPECT_DOUBLE_EQ(pos - handle_radius, first_handle_rect.x()); - EXPECT_DOUBLE_EQ(-handle_radius, first_handle_rect.y()); - EXPECT_DOUBLE_EQ(2 * handle_radius, first_handle_rect.width()); - EXPECT_DOUBLE_EQ(2 * handle_radius, first_handle_rect.height()); - - EXPECT_DOUBLE_EQ(pos - handle_radius, second_handle_rect.x()); - EXPECT_DOUBLE_EQ(height - handle_radius, second_handle_rect.y()); - EXPECT_DOUBLE_EQ(2 * handle_radius, second_handle_rect.width()); - EXPECT_DOUBLE_EQ(2 * handle_radius, second_handle_rect.height()); - - EXPECT_DOUBLE_EQ(pos - roughness, left_roughness_path.boundingRect().x()); - EXPECT_DOUBLE_EQ(0., left_roughness_path.boundingRect().y()); - EXPECT_DOUBLE_EQ(roughness, left_roughness_path.boundingRect().width()); - EXPECT_DOUBLE_EQ(height, left_roughness_path.boundingRect().height()); - - EXPECT_DOUBLE_EQ(pos, right_roughness_path.boundingRect().x()); - EXPECT_DOUBLE_EQ(0., right_roughness_path.boundingRect().y()); - EXPECT_DOUBLE_EQ(roughness, right_roughness_path.boundingRect().width()); - EXPECT_DOUBLE_EQ(height, right_roughness_path.boundingRect().height()); - - EXPECT_DOUBLE_EQ(pos - roughness - r_handle_radius, left_roughness_handle_rec.x()); - EXPECT_DOUBLE_EQ(height / 2 - r_handle_radius, left_roughness_handle_rec.y()); - EXPECT_DOUBLE_EQ(2 * r_handle_radius, left_roughness_handle_rec.width()); - EXPECT_DOUBLE_EQ(2 * r_handle_radius, left_roughness_handle_rec.height()); - - EXPECT_DOUBLE_EQ(pos + roughness - r_handle_radius, right_roughness_handle_rec.x()); - EXPECT_DOUBLE_EQ(height / 2 - r_handle_radius, right_roughness_handle_rec.y()); - EXPECT_DOUBLE_EQ(2 * r_handle_radius, right_roughness_handle_rec.width()); - EXPECT_DOUBLE_EQ(2 * r_handle_radius, right_roughness_handle_rec.height()); -} - -TEST_F(LayerElementTest, testscene) -{ - TestData test_data; - - // Set and test the scene - test_data.middle_controller->setScene(test_data.scene); - EXPECT_EQ(test_data.scene, test_data.middle_controller->scene()); - - // Connect the controller to the model - test_data.middle_controller->connectToModel(); - - // Set the segments - auto side_segment_middle = new SegmentElementViewFriend(); - auto top_segment_middle = new SegmentElementViewFriend(); - test_data.middle_controller->setSideSegment(side_segment_middle); - test_data.middle_controller->setTopSegment(top_segment_middle); - - // Set the handles - auto first_handle = new HandleElementViewFriend(); - auto second_handle = new HandleElementViewFriend(); - test_data.middle_controller->setSegmentHandles(first_handle, second_handle); - - // Test automatic scene placement - EXPECT_EQ(test_data.scene, side_segment_middle->scene()); - EXPECT_EQ(test_data.scene, top_segment_middle->scene()); - - // Test scene removal - test_data.middle_controller->unsetScene(); - EXPECT_EQ(nullptr, side_segment_middle->scene()); - EXPECT_EQ(nullptr, top_segment_middle->scene()); - - // Test scene placement - test_data.middle_controller->setScene(test_data.scene); - EXPECT_EQ(test_data.scene, side_segment_middle->scene()); - EXPECT_EQ(test_data.scene, top_segment_middle->scene()); -} - -TEST_F(LayerElementTest, testpropagation) -{ - TestData test_data; - - auto adapter = test_data.scene->sceneAdapter(); - - // Set the scenes - test_data.above_controller->setScene(test_data.scene); - test_data.middle_controller->setScene(test_data.scene); - test_data.below_controller->setScene(test_data.scene); - - // Connect controller to the model - test_data.above_controller->connectToModel(); - test_data.middle_controller->connectToModel(); - test_data.below_controller->connectToModel(); - - // Set the associated ids (will be model ids afterwards) - test_data.above_controller->setSampleItemId("above"); - test_data.middle_controller->setSampleItemId("middle"); - test_data.below_controller->setSampleItemId("below"); - - // Set the layer above up - auto side_segment_above = new SegmentElementViewFriend(); - auto top_segment_above = new SegmentElementViewFriend(); - test_data.above_controller->setSideSegment(side_segment_above); - test_data.above_controller->setTopSegment(top_segment_above); - auto first_handle_above = new HandleElementViewFriend(); - auto second_handle_above = new HandleElementViewFriend(); - test_data.above_controller->setSegmentHandles(first_handle_above, second_handle_above); - auto roughness_view_above = new RoughnessElementViewFriend(); - test_data.middle_controller->setRoughness(roughness_view_above); - auto left_handle_above = new HandleElementViewFriend(); - auto right_handle_above = new HandleElementViewFriend(); - test_data.above_controller->setRoughnessHandles(left_handle_above, right_handle_above); - - // Set the middle layer up - auto side_segment_middle = new SegmentElementViewFriend(); - auto top_segment_middle = new SegmentElementViewFriend(); - test_data.middle_controller->setSideSegment(side_segment_middle); - test_data.middle_controller->setTopSegment(top_segment_middle); - auto first_handle_middle = new HandleElementViewFriend(); - auto second_handle_middle = new HandleElementViewFriend(); - test_data.middle_controller->setSegmentHandles(first_handle_middle, second_handle_middle); - auto roughness_view_middle = new RoughnessElementViewFriend(); - test_data.middle_controller->setRoughness(roughness_view_middle); - auto left_handle_middle = new HandleElementViewFriend(); - auto right_handle_middle = new HandleElementViewFriend(); - test_data.middle_controller->setRoughnessHandles(left_handle_middle, right_handle_middle); - - // Set the layer below up - auto side_segment_below = new SegmentElementViewFriend(); - auto top_segment_below = new SegmentElementViewFriend(); - test_data.below_controller->setSideSegment(side_segment_below); - test_data.below_controller->setTopSegment(top_segment_below); - auto first_handle_below = new HandleElementViewFriend(); - auto second_handle_below = new HandleElementViewFriend(); - test_data.below_controller->setSegmentHandles(first_handle_below, second_handle_below); - auto roughness_view_below = new RoughnessElementViewFriend(); - test_data.below_controller->setRoughness(roughness_view_below); - auto left_handle_below = new HandleElementViewFriend(); - auto right_handle_below = new HandleElementViewFriend(); - test_data.below_controller->setRoughnessHandles(left_handle_below, right_handle_below); - - // Set the layer relationships - test_data.middle_controller->setLayerAbove(test_data.above_controller); - test_data.middle_controller->setLayerBelow(test_data.below_controller); - - // Get the items of each layer - LayerElementItem* item_above = test_data.above_controller->layerElementItem(); - LayerElementItem* item_middle = test_data.middle_controller->layerElementItem(); - LayerElementItem* item_below = test_data.below_controller->layerElementItem(); - - // #############################################################################s - // Test propagation for the contruction - EXPECT_DOUBLE_EQ(0., item_above->property<double>(LayerElementItem::P_X_POS)); - EXPECT_DOUBLE_EQ(10., item_above->property<double>(LayerElementItem::P_WIDTH)); - EXPECT_DOUBLE_EQ(10., item_middle->property<double>(LayerElementItem::P_X_POS)); - EXPECT_DOUBLE_EQ(10., item_middle->property<double>(LayerElementItem::P_WIDTH)); - EXPECT_DOUBLE_EQ(20., item_below->property<double>(LayerElementItem::P_X_POS)); - EXPECT_DOUBLE_EQ(10., item_below->property<double>(LayerElementItem::P_WIDTH)); - - // #############################################################################s - // Test signaling for property changes - QSignalSpy spy_ctr_above_width(test_data.above_controller, - &LayerElementController::widthChanged); - QSignalSpy spy_ctr_middle_height(test_data.middle_controller, - &LayerElementController::heightChanged); - QSignalSpy spy_ctr_middle_roughness(test_data.middle_controller, - &LayerElementController::roughnessChanged); - - auto mouse_move_event = new QGraphicsSceneMouseEvent(); - QList<QVariant> move_arguments; - - // Try standard x move - mouse_move_event->setPos(QPointF(adapter->toSceneX(-8), adapter->toSceneY(0))); - side_segment_middle->mouseMoveEvent(mouse_move_event); - move_arguments = spy_ctr_above_width.takeLast(); - - EXPECT_EQ(move_arguments.at(0).value<std::string>(), "above"); - EXPECT_DOUBLE_EQ(move_arguments.at(1).value<double>(), 8); - EXPECT_DOUBLE_EQ(8., item_above->property<double>(LayerElementItem::P_WIDTH)); - EXPECT_DOUBLE_EQ(8., item_middle->property<double>(LayerElementItem::P_X_POS)); - EXPECT_DOUBLE_EQ(3., first_handle_middle->rectangle().x()); - EXPECT_DOUBLE_EQ(5., first_handle_middle->rectangle().y()); - EXPECT_DOUBLE_EQ(3., second_handle_middle->rectangle().x()); - EXPECT_DOUBLE_EQ(5., second_handle_middle->rectangle().y()); - - move_arguments = spy_ctr_middle_roughness.takeLast(); - EXPECT_EQ(move_arguments.at(0).value<std::string>(), "middle"); - EXPECT_DOUBLE_EQ(move_arguments.at(1).value<double>(), 4); - EXPECT_DOUBLE_EQ(4, item_middle->property<double>(LayerElementItem::P_ROUGHNESS)); - - // Try limit x move - mouse_move_event->setPos(QPointF(adapter->toSceneX(1), adapter->toSceneY(0))); - side_segment_middle->mouseMoveEvent(mouse_move_event); - - move_arguments = spy_ctr_above_width.takeLast(); - EXPECT_EQ(move_arguments.at(0).value<std::string>(), "above"); - EXPECT_DOUBLE_EQ(move_arguments.at(1).value<double>(), 0); - EXPECT_DOUBLE_EQ(0, item_above->property<double>(LayerElementItem::P_WIDTH)); - EXPECT_DOUBLE_EQ(0, item_middle->property<double>(LayerElementItem::P_X_POS)); - EXPECT_DOUBLE_EQ(-5, first_handle_middle->rectangle().x()); - EXPECT_DOUBLE_EQ(5., first_handle_middle->rectangle().y()); - EXPECT_DOUBLE_EQ(-5, second_handle_middle->rectangle().x()); - EXPECT_DOUBLE_EQ(5., second_handle_middle->rectangle().y()); - - // Try standard x move - mouse_move_event->setPos(QPointF(adapter->toSceneX(-10), adapter->toSceneY(0))); - side_segment_middle->mouseMoveEvent(mouse_move_event); - move_arguments = spy_ctr_above_width.takeLast(); - - EXPECT_EQ(move_arguments.at(0).value<std::string>(), "above"); - EXPECT_DOUBLE_EQ(move_arguments.at(1).value<double>(), 10); - EXPECT_DOUBLE_EQ(10., item_above->property<double>(LayerElementItem::P_WIDTH)); - EXPECT_DOUBLE_EQ(10., item_middle->property<double>(LayerElementItem::P_X_POS)); - EXPECT_DOUBLE_EQ(5., first_handle_middle->rectangle().x()); - EXPECT_DOUBLE_EQ(5., first_handle_middle->rectangle().y()); - EXPECT_DOUBLE_EQ(5., second_handle_middle->rectangle().x()); - EXPECT_DOUBLE_EQ(5., second_handle_middle->rectangle().y()); - - // Try standard y move - mouse_move_event->setPos(QPointF(adapter->toSceneX(0), adapter->toSceneY(8))); - top_segment_middle->mouseMoveEvent(mouse_move_event); - move_arguments = spy_ctr_middle_height.takeLast(); - - EXPECT_EQ(move_arguments.at(0).value<std::string>(), "middle"); - EXPECT_DOUBLE_EQ(move_arguments.at(1).value<double>(), 8); - EXPECT_DOUBLE_EQ(8., item_middle->property<double>(LayerElementItem::P_HEIGHT)); - EXPECT_DOUBLE_EQ(5., first_handle_middle->rectangle().x()); - EXPECT_DOUBLE_EQ(5., first_handle_middle->rectangle().y()); - EXPECT_DOUBLE_EQ(5., second_handle_middle->rectangle().x()); - EXPECT_DOUBLE_EQ(3., second_handle_middle->rectangle().y()); - - // Try limit y move - mouse_move_event->setPos(QPointF(adapter->toSceneX(-0), adapter->toSceneY(-1))); - top_segment_middle->mouseMoveEvent(mouse_move_event); - move_arguments = spy_ctr_middle_height.takeLast(); - - EXPECT_EQ(move_arguments.at(0).value<std::string>(), "middle"); - EXPECT_EQ(move_arguments.at(1).value<double>(), 0); - EXPECT_DOUBLE_EQ(0, item_middle->property<double>(LayerElementItem::P_HEIGHT)); - EXPECT_DOUBLE_EQ(5., first_handle_middle->rectangle().x()); - EXPECT_DOUBLE_EQ(5., first_handle_middle->rectangle().y()); - EXPECT_DOUBLE_EQ(5., second_handle_middle->rectangle().x()); - EXPECT_DOUBLE_EQ(-5., second_handle_middle->rectangle().y()); - - // Try standard y move - mouse_move_event->setPos(QPointF(adapter->toSceneX(0), adapter->toSceneY(10))); - top_segment_middle->mouseMoveEvent(mouse_move_event); - move_arguments = spy_ctr_middle_height.takeLast(); - - EXPECT_EQ(move_arguments.at(0).value<std::string>(), "middle"); - EXPECT_DOUBLE_EQ(move_arguments.at(1).value<double>(), 10); - EXPECT_DOUBLE_EQ(10., item_middle->property<double>(LayerElementItem::P_HEIGHT)); - EXPECT_DOUBLE_EQ(5., first_handle_middle->rectangle().x()); - EXPECT_DOUBLE_EQ(5., first_handle_middle->rectangle().y()); - EXPECT_DOUBLE_EQ(5., second_handle_middle->rectangle().x()); - EXPECT_DOUBLE_EQ(5., second_handle_middle->rectangle().y()); - - // Try standard roughness move left handle - mouse_move_event->setPos(QPointF(adapter->toSceneX(-7), adapter->toSceneY(0))); - left_handle_middle->mouseMoveEvent(mouse_move_event); - - move_arguments = spy_ctr_middle_roughness.takeLast(); - EXPECT_EQ(move_arguments.at(0).value<std::string>(), "middle"); - EXPECT_DOUBLE_EQ(move_arguments.at(1).value<double>(), 3.); - EXPECT_DOUBLE_EQ(3., item_middle->property<double>(LayerElementItem::P_ROUGHNESS)); - - // Try limit roughness move left handle - mouse_move_event->setPos(QPointF(adapter->toSceneX(-2), adapter->toSceneY(0))); - left_handle_middle->mouseMoveEvent(mouse_move_event); - - move_arguments = spy_ctr_middle_roughness.takeLast(); - EXPECT_EQ(move_arguments.at(0).value<std::string>(), "middle"); - EXPECT_DOUBLE_EQ(move_arguments.at(1).value<double>(), 5.); - EXPECT_DOUBLE_EQ(5., item_middle->property<double>(LayerElementItem::P_ROUGHNESS)); - - // Try standard roughness move left handle - mouse_move_event->setPos(QPointF(adapter->toSceneX(-8), adapter->toSceneY(0))); - left_handle_middle->mouseMoveEvent(mouse_move_event); - - move_arguments = spy_ctr_middle_roughness.takeLast(); - EXPECT_EQ(move_arguments.at(0).value<std::string>(), "middle"); - EXPECT_FLOAT_EQ(move_arguments.at(1).value<double>(), 2.); // DOUBLE_EQ not enough under Windows - EXPECT_FLOAT_EQ(2., item_middle->property<double>(LayerElementItem::P_ROUGHNESS)); - - // Try standard roughness move right handle - mouse_move_event->setPos(QPointF(adapter->toSceneX(-13), adapter->toSceneY(0))); - right_handle_middle->mouseMoveEvent(mouse_move_event); - - move_arguments = spy_ctr_middle_roughness.takeLast(); - EXPECT_EQ(move_arguments.at(0).value<std::string>(), "middle"); - EXPECT_DOUBLE_EQ(move_arguments.at(1).value<double>(), 3.); - EXPECT_DOUBLE_EQ(3., item_middle->property<double>(LayerElementItem::P_ROUGHNESS)); - - // Try limit roughness move right handle - mouse_move_event->setPos(QPointF(adapter->toSceneX(-8), adapter->toSceneY(0))); - right_handle_middle->mouseMoveEvent(mouse_move_event); - - move_arguments = spy_ctr_middle_roughness.takeLast(); - EXPECT_EQ(move_arguments.at(0).value<std::string>(), "middle"); - EXPECT_DOUBLE_EQ(move_arguments.at(1).value<double>(), 0); - EXPECT_DOUBLE_EQ(0, item_middle->property<double>(LayerElementItem::P_ROUGHNESS)); - - // Try standard roughness move right handle - mouse_move_event->setPos(QPointF(adapter->toSceneX(-13), adapter->toSceneY(0))); - right_handle_middle->mouseMoveEvent(mouse_move_event); - - move_arguments = spy_ctr_middle_roughness.takeLast(); - EXPECT_EQ(move_arguments.at(0).value<std::string>(), "middle"); - EXPECT_DOUBLE_EQ(move_arguments.at(1).value<double>(), 3); - EXPECT_DOUBLE_EQ(3, item_middle->property<double>(LayerElementItem::P_ROUGHNESS)); -} -TEST_F(LayerElementTest, moveelements) -{ - TestData test_data; - test_data.middle_controller->setLayerAbove(test_data.above_controller); - test_data.middle_controller->setLayerBelow(test_data.below_controller); -} diff --git a/Tests/Unit/gui2/testdareflcore/layeritems.test.cpp b/Tests/Unit/gui2/testdareflcore/layeritems.test.cpp deleted file mode 100644 index 873fbff78a07eaa779e75025636df234490caec1..0000000000000000000000000000000000000000 --- a/Tests/Unit/gui2/testdareflcore/layeritems.test.cpp +++ /dev/null @@ -1,83 +0,0 @@ -// ************************************************************************** // -// -// Reflectometry simulation software prototype -// -//! @license GNU General Public License v3 or higher (see COPYING) -//! @authors see AUTHORS -// -// ************************************************************************** // - -#include "google_test.h" -#include "gui2/model/sampleitems.h" -#include "gui2/model/samplemodel.h" -#include "test_utils.h" - -using namespace gui2; -using namespace ModelView; - -//! Test layer items. - -class LayerItemsTest : public ::testing::Test { -public: - ~LayerItemsTest(); -}; - -LayerItemsTest::~LayerItemsTest() = default; - -//! Checks that layers in multilayer have proper appearance of "thickness" property. -//! Top and bottom layers should have "thickness" always disabled. - -// FIXME restore testing of thickness and roughness appearance for top and bottom layers -// FIXME together with layeritems.cpp - -TEST_F(LayerItemsTest, layerAppearanceTwoLayerSystem) -{ - SampleModel model; - - auto multilayer = model.insertItem<MultiLayerItem>(); - - auto top = model.insertItem<LayerItem>(multilayer); - auto bottom = model.insertItem<LayerItem>(multilayer); - - // check appearance of thickness properties - EXPECT_FALSE(top->getItem(LayerItem::P_THICKNESS)->isEnabled()); - EXPECT_FALSE(bottom->getItem(LayerItem::P_THICKNESS)->isEnabled()); - - // check that thickness of top and bottom layer is 0. - EXPECT_EQ(top->property<double>(LayerItem::P_THICKNESS), 0.0); - EXPECT_EQ(bottom->property<double>(LayerItem::P_THICKNESS), 0.0); -} - -TEST_F(LayerItemsTest, layerAppearanceThreeLayerSystem) -{ - SampleModel model; - - auto multilayer = model.insertItem<MultiLayerItem>(); - - auto top = model.insertItem<LayerItem>(multilayer); - auto middle = model.insertItem<LayerItem>(multilayer); - auto bottom = model.insertItem<LayerItem>(multilayer); - - // check appearance of thickness properties - EXPECT_FALSE(top->getItem(LayerItem::P_THICKNESS)->isEnabled()); - EXPECT_TRUE(middle->getItem(LayerItem::P_THICKNESS)->isEnabled()); - EXPECT_FALSE(bottom->getItem(LayerItem::P_THICKNESS)->isEnabled()); - - middle->setProperty(LayerItem::P_THICKNESS, 42.0); - - // moving middle layer on top - model.moveItem(middle, multilayer, {MultiLayerItem::T_LAYERS, 0}); - - auto new_top = middle; - auto new_middle = top; - auto new_bottom = bottom; - - EXPECT_FALSE(new_top->getItem(LayerItem::P_THICKNESS)->isEnabled()); - EXPECT_TRUE(new_middle->getItem(LayerItem::P_THICKNESS)->isEnabled()); - EXPECT_FALSE(new_bottom->getItem(LayerItem::P_THICKNESS)->isEnabled()); - - // check the value of thickness - EXPECT_EQ(new_top->property<double>(LayerItem::P_THICKNESS), 0.0); // was reset during move - EXPECT_EQ(new_middle->property<double>(LayerItem::P_THICKNESS), 0.0); - EXPECT_EQ(new_bottom->property<double>(LayerItem::P_THICKNESS), 0.0); -} diff --git a/Tests/Unit/gui2/testdareflcore/layerselectionmodel.test.cpp b/Tests/Unit/gui2/testdareflcore/layerselectionmodel.test.cpp deleted file mode 100644 index 323ebe29bf9939c2a41bc72feb712990643ceba8..0000000000000000000000000000000000000000 --- a/Tests/Unit/gui2/testdareflcore/layerselectionmodel.test.cpp +++ /dev/null @@ -1,127 +0,0 @@ -// ************************************************************************** // -// -// Reflectometry simulation software prototype -// -//! @license GNU General Public License v3 or higher (see COPYING) -//! @authors see AUTHORS -// -// ************************************************************************** // - -#include "google_test.h" -#include "gui2/layereditor/layerselectionmodel.h" -#include "gui2/layereditor/layerviewmodel.h" -#include "gui2/model/sampleitems.h" -#include "gui2/model/samplemodel.h" -#include "mvvm/viewmodel/viewmodelutils.h" -#include "test_utils.h" - -using namespace gui2; -using namespace ModelView; - -//! Tests of LayerSelectionModel. - -class LayerSelectionModelTest : public ::testing::Test { -public: - ~LayerSelectionModelTest(); - - struct TestData { - SampleModel sample_model; - LayerViewModel view_model{&sample_model}; - LayerSelectionModel selection_model{&view_model}; - SessionItem* multilayer{nullptr}; - SessionItem* top{nullptr}; - SessionItem* bottom{nullptr}; - TestData() - { - multilayer = sample_model.insertItem<MultiLayerItem>(); - top = sample_model.insertItem<LayerItem>(multilayer); - bottom = sample_model.insertItem<LayerItem>(multilayer); - view_model.setRootSessionItem(multilayer); - } - }; -}; - -LayerSelectionModelTest::~LayerSelectionModelTest() = default; - -//! Layout of LayerViewModel for two layer system. - -TEST_F(LayerSelectionModelTest, initialState) -{ - TestData test_data; - EXPECT_FALSE(test_data.selection_model.hasSelection()); - - // checking layout of multilayer - auto layers = test_data.multilayer->getItems(MultiLayerItem::T_LAYERS); - EXPECT_EQ(layers.size(), 2); - EXPECT_EQ(layers.at(0), test_data.top); - EXPECT_EQ(layers.at(1), test_data.bottom); -} - -TEST_F(LayerSelectionModelTest, selectLayerItem) -{ - TestData test_data; - - // selecting top layer - test_data.selection_model.selectItem(test_data.top); - EXPECT_TRUE(test_data.selection_model.hasSelection()); - // 4 indexes should be selected: name, nr, material, thickness, sigma - EXPECT_EQ(test_data.selection_model.selectedIndexes().size(), 5); - - // checking back that top layer is selected - std::vector<SessionItem*> expected = {test_data.top}; - EXPECT_EQ(test_data.selection_model.selectedItems(), expected); - - // selecting bottom layer - test_data.selection_model.selectItem(test_data.bottom); - EXPECT_TRUE(test_data.selection_model.hasSelection()); - // 4 indexes should be selected: name, nr, material, thickness, sigma - EXPECT_EQ(test_data.selection_model.selectedIndexes().size(), 5); - - // checking back that top layer is selected - expected = {test_data.bottom}; - EXPECT_EQ(test_data.selection_model.selectedItems(), expected); -} - -TEST_F(LayerSelectionModelTest, selectLayerItems) -{ - TestData test_data; - - std::vector<ModelView::SessionItem*> to_select{test_data.top, test_data.bottom}; - test_data.selection_model.selectItems(to_select); - - // selecting top layer - EXPECT_TRUE(test_data.selection_model.hasSelection()); - - EXPECT_EQ(test_data.selection_model.selectedIndexes().size(), 10); // two rows of cells - - // checking back that top layer is selected - std::vector<SessionItem*> expected = to_select; - EXPECT_EQ(test_data.selection_model.selectedItems(), expected); -} - -//! Checking selection of MultiLayer items - -TEST_F(LayerSelectionModelTest, selectMultiLayerItem) -{ - TestData test_data; - - // adding new MultiLayer between top and bottom layer - auto new_ml = test_data.sample_model.insertItem<MultiLayerItem>(test_data.multilayer, - {MultiLayerItem::T_LAYERS, 1}); - - // checking layout - auto layers = test_data.multilayer->getItems(MultiLayerItem::T_LAYERS); - EXPECT_EQ(layers.size(), 3); - EXPECT_EQ(layers.at(0), test_data.top); - EXPECT_EQ(layers.at(1), new_ml); - EXPECT_EQ(layers.at(2), test_data.bottom); - - // selecting new multi-layer - test_data.selection_model.selectItem(new_ml); - - EXPECT_TRUE(test_data.selection_model.hasSelection()); - EXPECT_EQ(test_data.selection_model.selectedIndexes().size(), 5); - - std::vector<SessionItem*> expected = {new_ml}; - EXPECT_EQ(test_data.selection_model.selectedItems(), expected); -} diff --git a/Tests/Unit/gui2/testdareflcore/layerviewmodel.test.cpp b/Tests/Unit/gui2/testdareflcore/layerviewmodel.test.cpp deleted file mode 100644 index 85c1edcabeac021f5c201df8445470b5fb0e7f59..0000000000000000000000000000000000000000 --- a/Tests/Unit/gui2/testdareflcore/layerviewmodel.test.cpp +++ /dev/null @@ -1,160 +0,0 @@ -// ************************************************************************** // -// -// Reflectometry simulation software prototype -// -//! @license GNU General Public License v3 or higher (see COPYING) -//! @authors see AUTHORS -// -// ************************************************************************** // - -#include "google_test.h" -#include "gui2/layereditor/layerviewmodel.h" -#include "gui2/model/sampleitems.h" -#include "gui2/model/samplemodel.h" -#include "mvvm/viewmodel/viewmodelutils.h" -#include "test_utils.h" -#include <QSignalSpy> - -using namespace gui2; -using namespace ModelView; - -//! Tests of LayerViewModel. - -class LayerViewModelTest : public ::testing::Test { -public: - ~LayerViewModelTest(); -}; - -LayerViewModelTest::~LayerViewModelTest() = default; - -TEST_F(LayerViewModelTest, initialState) -{ - SampleModel model; - LayerViewModel viewmodel(&model); - - EXPECT_EQ(viewmodel.rowCount(), 0); - EXPECT_EQ(viewmodel.columnCount(), 0); -} - -//! Checks signals while inserting LayerItem in empty model - -TEST_F(LayerViewModelTest, insertLayer) -{ - SampleModel model; - LayerViewModel viewmodel(&model); - - QSignalSpy spyRowsInserted(&viewmodel, &LayerViewModel::rowsInserted); - QSignalSpy spyColumnsInserted(&viewmodel, &LayerViewModel::columnsInserted); - QSignalSpy spyRowsRemoved(&viewmodel, &LayerViewModel::rowsRemoved); - QSignalSpy spyColumnsRemoved(&viewmodel, &LayerViewModel::columnsRemoved); - - auto layer = model.insertItem<LayerItem>(); - EXPECT_EQ(viewmodel.rowCount(), 1); - EXPECT_EQ(viewmodel.columnCount(), 5); - - // checking ::rowInserted - EXPECT_EQ(spyRowsInserted.count(), 1); - QList<QVariant> arguments = spyRowsInserted.takeFirst(); - EXPECT_EQ(arguments.size(), 3); // QModelIndex &parent, int first, int last - EXPECT_EQ(arguments.at(0).value<QModelIndex>(), QModelIndex()); - EXPECT_EQ(arguments.at(1).value<int>(), 0); - EXPECT_EQ(arguments.at(2).value<int>(), 0); - - // checking ::columnInserted - EXPECT_EQ(spyColumnsInserted.count(), 0); - - // checking ::spyRowsRemoved - EXPECT_EQ(spyColumnsInserted.count(), 0); - - // checking ::spyRowsRemoved - EXPECT_EQ(spyColumnsRemoved.count(), 0); - - // checking layout of ViewModel - QModelIndexList selection = {viewmodel.index(0, 0), viewmodel.index(0, 1), - viewmodel.index(0, 2), viewmodel.index(0, 3)}; - - std::vector<SessionItem*> expected = {layer->getItem(LayerItem::P_NAME), nullptr, - layer->getItem(LayerItem::P_MATERIAL), - layer->getItem(LayerItem::P_THICKNESS)}; - EXPECT_EQ(Utils::ItemsFromIndex(selection), expected); -} - -//! Checks signals while inserting MultiLayerItem in empty model. - -TEST_F(LayerViewModelTest, inserMultitLayer) -{ - SampleModel model; - LayerViewModel viewmodel(&model); - - QSignalSpy spyRowsInserted(&viewmodel, &LayerViewModel::rowsInserted); - QSignalSpy spyColumnsInserted(&viewmodel, &LayerViewModel::columnsInserted); - QSignalSpy spyRowsRemoved(&viewmodel, &LayerViewModel::rowsRemoved); - QSignalSpy spyColumnsRemoved(&viewmodel, &LayerViewModel::columnsRemoved); - - auto multilayer = model.insertItem<MultiLayerItem>(); - EXPECT_EQ(viewmodel.rowCount(), 1); - EXPECT_EQ(viewmodel.columnCount(), 5); - - // checking ::rowInserted - EXPECT_EQ(spyRowsInserted.count(), 1); - QList<QVariant> arguments = spyRowsInserted.takeFirst(); - EXPECT_EQ(arguments.size(), 3); // QModelIndex &parent, int first, int last - EXPECT_EQ(arguments.at(0).value<QModelIndex>(), QModelIndex()); - EXPECT_EQ(arguments.at(1).value<int>(), 0); - EXPECT_EQ(arguments.at(2).value<int>(), 0); - - // checking ::columnInserted - EXPECT_EQ(spyColumnsInserted.count(), 0); - - // checking ::spyRowsRemoved - EXPECT_EQ(spyColumnsInserted.count(), 0); - - // checking ::spyRowsRemoved - EXPECT_EQ(spyColumnsRemoved.count(), 0); - - // checking layout of ViewModel - QModelIndexList selection = {viewmodel.index(0, 0), viewmodel.index(0, 1), - viewmodel.index(0, 2), viewmodel.index(0, 3)}; - - std::vector<SessionItem*> expected = {multilayer->getItem(MultiLayerItem::P_NAME), - multilayer->getItem(MultiLayerItem::P_NREPETITIONS), - nullptr, nullptr}; - EXPECT_EQ(Utils::ItemsFromIndex(selection), expected); - - // adding layer to the multilayer - QModelIndex mlIndex = viewmodel.index(0, 0); - model.insertItem<LayerItem>(multilayer); - EXPECT_EQ(viewmodel.rowCount(mlIndex), 1); - EXPECT_EQ(viewmodel.columnCount(mlIndex), 5); -} - -//! Layout of LayerViewModel for two layer system. - -TEST_F(LayerViewModelTest, twoLayerSystem) -{ - SampleModel model; - auto multilayer = model.insertItem<MultiLayerItem>(); - auto top = model.insertItem<LayerItem>(multilayer); - auto bottom = model.insertItem<LayerItem>(multilayer); - - LayerViewModel viewmodel(&model); - viewmodel.setRootSessionItem(multilayer); - - EXPECT_EQ(viewmodel.rowCount(), 2); - EXPECT_EQ(viewmodel.columnCount(), 5); // name, Nr, material, thickness, sigma - - // check indexes in first row and their correspondence to top-layer related items - QModelIndexList selection = {viewmodel.index(0, 0), viewmodel.index(0, 1), - viewmodel.index(0, 2), viewmodel.index(0, 3)}; - std::vector<SessionItem*> expected = {top->getItem(LayerItem::P_NAME), nullptr, - top->getItem(LayerItem::P_MATERIAL), - top->getItem(LayerItem::P_THICKNESS)}; - EXPECT_EQ(Utils::ItemsFromIndex(selection), expected); - - // check indexes in first row and their correspondence to bottom-layer related items - selection = {viewmodel.index(1, 0), viewmodel.index(1, 1), viewmodel.index(1, 2), - viewmodel.index(1, 3)}; - expected = {bottom->getItem(LayerItem::P_NAME), nullptr, bottom->getItem(LayerItem::P_MATERIAL), - bottom->getItem(LayerItem::P_THICKNESS)}; - EXPECT_EQ(Utils::ItemsFromIndex(selection), expected); -} diff --git a/Tests/Unit/gui2/testdareflcore/materialprofile.test.cpp b/Tests/Unit/gui2/testdareflcore/materialprofile.test.cpp deleted file mode 100644 index c22972a544bc80623badcf1ac1ee9305f533e5da..0000000000000000000000000000000000000000 --- a/Tests/Unit/gui2/testdareflcore/materialprofile.test.cpp +++ /dev/null @@ -1,77 +0,0 @@ -// ************************************************************************** // -// -// Reflectometry simulation software prototype -// -//! @license GNU General Public License v3 or higher (see COPYING) -//! @authors see AUTHORS -// -// ************************************************************************** // - -#include "google_test.h" -#include "gui2/quicksimeditor/materialprofile.h" - -using namespace gui2; - -//! Tests utility functions from MaterialProfile namespace. - -class MaterialProfileTest : public ::testing::Test { -public: - ~MaterialProfileTest(); -}; - -MaterialProfileTest::~MaterialProfileTest() = default; - -TEST_F(MaterialProfileTest, GenerateZValues) -{ - auto values = MaterialProfile::GenerateZValues(0, -2.0, 4.0); - EXPECT_EQ(values.size(), 0); - - values = MaterialProfile::GenerateZValues(1, -2.0, 4.0); - EXPECT_EQ(values, std::vector<double>{-2.0}); - - values = MaterialProfile::GenerateZValues(2, -2.0, 4.0); - EXPECT_EQ(values, (std::vector<double>{-2.0, 4.0})); - - values = MaterialProfile::GenerateZValues(3, -2.0, 4.0); - EXPECT_EQ(values, (std::vector<double>{-2.0, 1.0, 4.0})); - - values = MaterialProfile::GenerateZValues(3, -15.0, 5.0); - EXPECT_EQ(values, (std::vector<double>{-15.0, -5.0, 5.0})); -} - -TEST_F(MaterialProfileTest, DefaultMaterialProfileLimits) -{ - SliceData air{{0.0, 0.0}, 0.0, 0.0}; - SliceData substrate{{2e-06, 0.0}, 0.0, 0.0}; - multislice_t multislice = {air, substrate}; - - auto [xmin, xmax] = MaterialProfile::DefaultMaterialProfileLimits(multislice); - EXPECT_EQ(xmin, -10.0); - EXPECT_EQ(xmax, 10.0); -} - -TEST_F(MaterialProfileTest, TwoLayersProfile) -{ - SliceData air{{0.0, 0.0}, 0.0, 0.0}; - SliceData substrate{{2e-06, 0.0}, 0.0, 0.0}; - multislice_t multislice = {air, substrate}; - - auto values = MaterialProfile::CalculateProfile(multislice, 2, -10.0, 10.0); - ASSERT_EQ(values.size(), 2); - EXPECT_DOUBLE_EQ(values[0].real(), substrate.material.real()); - EXPECT_DOUBLE_EQ(values[1].real(), air.material.real()); -} - -TEST_F(MaterialProfileTest, ThreeLayersProfile) -{ - SliceData air{{0.0, 0.0}, 0.0, 0.0}; - SliceData ni{{9e-06, 0.0}, 10.0, 0.0}; - SliceData substrate{{2e-06, 0.0}, 0.0, 0.0}; - multislice_t multislice = {air, ni, substrate}; - - auto values = MaterialProfile::CalculateProfile(multislice, 3, -15.0, 5.0); - ASSERT_EQ(values.size(), 3); - EXPECT_DOUBLE_EQ(values[0].real(), substrate.material.real()); - EXPECT_DOUBLE_EQ(values[1].real(), ni.material.real()); - EXPECT_DOUBLE_EQ(values[2].real(), air.material.real()); -} diff --git a/Tests/Unit/gui2/testdareflcore/modelutils.test.cpp b/Tests/Unit/gui2/testdareflcore/modelutils.test.cpp deleted file mode 100644 index 9b77f259465a6105e91a67865849f0aa7c804552..0000000000000000000000000000000000000000 --- a/Tests/Unit/gui2/testdareflcore/modelutils.test.cpp +++ /dev/null @@ -1,67 +0,0 @@ -// ************************************************************************** // -// -// Reflectometry simulation software prototype -// -//! @license GNU General Public License v3 or higher (see COPYING) -//! @authors see AUTHORS -// -// ************************************************************************** // - -#include "google_test.h" -#include "gui2/model/modelutils.h" -#include "mvvm/standarditems/axisitems.h" -#include "mvvm/standarditems/data1ditem.h" - -using namespace ModelView; - -//! Tests of Utils namespace functions. - -class ModelUtilsTest : public ::testing::Test { -public: - ~ModelUtilsTest(); -}; - -ModelUtilsTest::~ModelUtilsTest() = default; - -//! Testing CreateDiffVector helper method. - -TEST_F(ModelUtilsTest, CreateDiffVector) -{ - std::vector<double> a{1.0, 2.0}; - std::vector<double> b{1.0, 4.0, 3.0}; - - auto result = gui2::Utils::CreateDiffVector(a, b); - EXPECT_EQ(result.size(), 2u); - EXPECT_DOUBLE_EQ(result[0], 0.0); - EXPECT_DOUBLE_EQ(result[1], 2.0 * (2.0 - 4.0) / (2.0 + 4.0)); -} - -//! Testing SetDifference helper method. - -TEST_F(ModelUtilsTest, SetDifference) -{ - Data1DItem item1; - item1.setAxis<FixedBinAxisItem>(3, 0.0, 3.0); - Data1DItem item2; - item2.setAxis<FixedBinAxisItem>(3, 0.0, 3.0); - - std::vector<double> values1{1.0, 2.0, 3.0}; - std::vector<double> values2{1.0, 4.0, -3.0}; - item1.setValues(values1); - item2.setValues(values2); - - Data1DItem diff; - diff.setAxis<FixedBinAxisItem>(3, 0.0, 3.0); - gui2::Utils::SetDifference(&item1, &item2, &diff); - - std::vector<double> expected_centers = {0.5, 1.5, 2.5}; - EXPECT_EQ(diff.binCenters(), expected_centers); - auto values = diff.binValues(); - - EXPECT_EQ(values.size(), 3u); - - auto diff_func = [](auto a, auto b) { return 2.0 * (a - b) / (a + b); }; - EXPECT_FLOAT_EQ(values[0], diff_func(values1[0], values2[0])); - EXPECT_FLOAT_EQ(values[1], diff_func(values1[1], values2[1])); - EXPECT_FLOAT_EQ(values[2], 0.0); // division by zero -} diff --git a/Tests/Unit/gui2/testdareflcore/quicksimutils.test.cpp b/Tests/Unit/gui2/testdareflcore/quicksimutils.test.cpp deleted file mode 100644 index 9fb703d14d7ad72f0f343b35e0512703433a7225..0000000000000000000000000000000000000000 --- a/Tests/Unit/gui2/testdareflcore/quicksimutils.test.cpp +++ /dev/null @@ -1,218 +0,0 @@ -// ************************************************************************** // -// -// Reflectometry simulation software prototype -// -//! @license GNU General Public License v3 or higher (see COPYING) -//! @authors see AUTHORS -// -// ************************************************************************** // - -#include "google_test.h" -#include "gui2/model/materialitems.h" -#include "gui2/model/materialmodel.h" -#include "gui2/model/sampleitems.h" -#include "gui2/model/samplemodel.h" -#include "gui2/quicksimeditor/quicksimutils.h" -#include "mvvm/model/externalproperty.h" -#include "mvvm/model/itempool.h" -#include <QColor> -#include <tuple> - -using namespace gui2; -using namespace ModelView; - -namespace { -//! Helper function to set layer's parameters. -void setup_layer(LayerItem* layer, double thickness, double sigma, SLDMaterialItem* material) -{ - layer->setProperty(LayerItem::P_THICKNESS, thickness); - auto roughness = layer->item<RoughnessItem>(LayerItem::P_ROUGHNESS); - roughness->setProperty(RoughnessItem::P_SIGMA, sigma); - layer->setProperty(LayerItem::P_MATERIAL, material->external_property()); -} - -} // namespace - -//! Tests of QuickSimUtils namespace functions. - -class QuickSimUtilsTest : public ::testing::Test { -public: - //! Helper container with testing data. - struct TestData { - std::shared_ptr<ItemPool> item_pool; - SampleModel sample_model; - MaterialModel material_model; - gui2::MultiLayerItem* multilayer{nullptr}; - TestData() - : item_pool(std::make_shared<ItemPool>()) - , sample_model(item_pool) - , material_model(item_pool) - { - multilayer = sample_model.insertItem<gui2::MultiLayerItem>(); - } - - //! Add layer to given multilayer models. At the same time corresponding material will - //! be added to MaterialModel and the Layer will be linked to it. - void addLayer(gui2::MultiLayerItem* _multilayer, double thickness, double sigma, - complex_t sld) - { - auto material = material_model.insertItem<SLDMaterialItem>(); - material->set_properties("gold", QColor(), sld.real(), sld.imag()); - auto layer = sample_model.insertItem<LayerItem>(_multilayer); - setup_layer(layer, thickness, sigma, material); - } - - void addLayer(gui2::MultiLayerItem* _multilayer, - const std::tuple<double, double, complex_t>& info) - { - auto [thickness, sigma, sld] = info; - addLayer(_multilayer, thickness, sigma, sld); - } - }; - - ~QuickSimUtilsTest(); -}; - -QuickSimUtilsTest::~QuickSimUtilsTest() = default; - -//! Testing helper structure. - -TEST_F(QuickSimUtilsTest, testData) -{ - TestData test_data; - - // creating single layer - double thickness{42.0}; - double sigma{43.0}; - complex_t sld{1.0, 2.0}; - test_data.addLayer(test_data.multilayer, thickness, sigma, sld); - - // checking that layer got necessary parameters - auto layer = test_data.multilayer->item<LayerItem>(gui2::MultiLayerItem::T_LAYERS); - EXPECT_EQ(layer->property<double>(LayerItem::P_THICKNESS), thickness); - auto roughness = layer->item<RoughnessItem>(LayerItem::P_ROUGHNESS); - EXPECT_EQ(roughness->property<double>(RoughnessItem::P_SIGMA), sigma); - - // checking that layer is linked to material with necessary parameters - auto material_property = layer->property<ExternalProperty>(LayerItem::P_MATERIAL); - auto material = test_data.sample_model.findItem(material_property.identifier()); - EXPECT_EQ(material->property<double>(SLDMaterialItem::P_SLD_REAL), sld.real()); - EXPECT_EQ(material->property<double>(SLDMaterialItem::P_SLD_IMAG), sld.imag()); -} - -//! Multi-slice of empty MultiLayer. - -TEST_F(QuickSimUtilsTest, emptySlice) -{ - SampleModel model; - auto multilayer = model.insertItem<gui2::MultiLayerItem>(); - auto multislice = gui2::Utils::CreateMultiSlice(*multilayer); - EXPECT_EQ(multislice.size(), 0); -} - -//! Multi-slice of MultiLayer with single layer without material. - -TEST_F(QuickSimUtilsTest, layerSlice) -{ - SampleModel model; - auto multilayer = model.insertItem<gui2::MultiLayerItem>(); - model.insertItem<LayerItem>(multilayer); - auto multislice = gui2::Utils::CreateMultiSlice(*multilayer); - - ASSERT_EQ(multislice.size(), 1); - EXPECT_EQ(multislice[0].material.real(), 0.0); - EXPECT_EQ(multislice[0].material.imag(), 0.0); - EXPECT_EQ(multislice[0].thickness, 0.0); - EXPECT_EQ(multislice[0].sigma, 0.0); -} - -//! Multi-slice of MultiLayer with single layer with defined material and roughness. - -TEST_F(QuickSimUtilsTest, definedLayerSlice) -{ - TestData test_data; - - // initializing MaterialModel with single material - const double thickness{42.0}; - const double sigma{43.0}; - const complex_t sld{1.0, 2.0}; - - // adding layer - test_data.addLayer(test_data.multilayer, thickness, sigma, sld); - - // creating multi slice - auto multislice = gui2::Utils::CreateMultiSlice(*test_data.multilayer); - - ASSERT_EQ(multislice.size(), 1); - EXPECT_EQ(multislice[0].material.real(), sld.real()); - EXPECT_EQ(multislice[0].material.imag(), sld.imag()); - EXPECT_EQ(multislice[0].thickness, thickness); - EXPECT_EQ(multislice[0].sigma, sigma); -} - -//! Multi-slice of MultiLayer with three layers. - -TEST_F(QuickSimUtilsTest, threeLayerSlices) -{ - TestData test_data; - - // initializing MaterialModel with single material - using layer_info = std::tuple<double, double, complex_t>; // thickness, sigma, material - std::vector<layer_info> layer_data = { - {0.0, 0.0, {11, 12}}, {42.0, 10.0, {13, 14}}, {0.0, 0.0, {15, 16}}}; - for (auto [thickness, sigma, sld] : layer_data) - test_data.addLayer(test_data.multilayer, thickness, sigma, sld); - - auto multislice = gui2::Utils::CreateMultiSlice(*test_data.multilayer); - - ASSERT_EQ(multislice.size(), 3); - int index(0); - for (auto [thickness, sigma, sld] : layer_data) { - EXPECT_EQ(multislice[index].material.real(), sld.real()); - EXPECT_EQ(multislice[index].material.imag(), sld.imag()); - EXPECT_EQ(multislice[index].thickness, thickness); - EXPECT_EQ(multislice[index].sigma, sigma); - ++index; - } -} - -//! Slice for MultiLayer containing air, repeated bi-layer and substrate. - -TEST_F(QuickSimUtilsTest, nestedMultiLayerSlice) -{ - TestData test_data; - - // preparing layer data - using layer_info = std::tuple<double, double, complex_t>; // thickness, sigma, material - layer_info air = {0.0, 0.0, {0.0, 0.0}}; - const int repetition_count = 2; - layer_info ti_layer = {20.0, 10.0, {-1.9493e-06, 0.0}}; - layer_info ni_layer = {80.0, 10.0, {9.4245e-06, 0.0}}; - layer_info substrate = {0.0, 10.0, {2.0704e-06, 0.0}}; - - // adding air layer - test_data.addLayer(test_data.multilayer, air); - // adding nested multilayer with content repetition - auto multilayer = test_data.multilayer; - auto nested_multilayer = test_data.sample_model.insertItem<gui2::MultiLayerItem>(multilayer); - nested_multilayer->setProperty(gui2::MultiLayerItem::P_NREPETITIONS, repetition_count); - test_data.addLayer(nested_multilayer, ti_layer); - test_data.addLayer(nested_multilayer, ni_layer); - // adding substrate - test_data.addLayer(test_data.multilayer, substrate); - - auto multislice = gui2::Utils::CreateMultiSlice(*test_data.multilayer); - ASSERT_EQ(multislice.size(), 6); - - // expected slice content - const std::vector<layer_info> layer_data = {air, ti_layer, ni_layer, - ti_layer, ni_layer, substrate}; - int index(0); - for (auto [thickness, sigma, sld] : layer_data) { - EXPECT_EQ(multislice[index].material.real(), sld.real()); - EXPECT_EQ(multislice[index].material.imag(), sld.imag()); - EXPECT_EQ(multislice[index].thickness, thickness); - EXPECT_EQ(multislice[index].sigma, sigma); - ++index; - } -} diff --git a/Tests/Unit/gui2/testdareflcore/sldelementcontroller.test.cpp b/Tests/Unit/gui2/testdareflcore/sldelementcontroller.test.cpp deleted file mode 100644 index cddb11af9b7e5755df6810dbac18b432f4509da1..0000000000000000000000000000000000000000 --- a/Tests/Unit/gui2/testdareflcore/sldelementcontroller.test.cpp +++ /dev/null @@ -1,101 +0,0 @@ -// ************************************************************************** // -// -// Reflectometry simulation software prototype -// -//! @license GNU General Public License v3 or higher (see COPYING) -//! @authors see AUTHORS -// -// ************************************************************************** // - -#include "google_test.h" - -#include "gui2/model/materialmodel.h" -#include "gui2/model/sampleitems.h" -#include "gui2/model/samplemodel.h" -#include "gui2/sldeditor/graphicsscene.h" -#include "gui2/sldeditor/layerelementcontroller.h" -#include "gui2/sldeditor/sldelementcontroller.cpp" -#include "gui2/sldeditor/sldelementmodel.h" -#include "test_utils.h" -#include <QGraphicsScene> - -using namespace gui2; -using namespace ModelView; - -class SLDElementControllerTest : public ::testing::Test { -public: - ~SLDElementControllerTest(); - - struct TestData { - MaterialModel* p_material_model{nullptr}; - SampleModel* p_sample_model{nullptr}; - SLDElementModel* p_sld_model{nullptr}; - GraphicsScene* p_scene_item{nullptr}; - SLDElementController* p_element_controller{nullptr}; - MultiLayerItem* multilayer{nullptr}; - LayerItem* top{nullptr}; - LayerItem* middle{nullptr}; - LayerItem* bottom{nullptr}; - - TestData() - { - p_material_model = new MaterialModel(); - p_sample_model = new SampleModel(); - p_sld_model = new SLDElementModel(); - p_scene_item = new GraphicsScene(); - p_element_controller = new SLDElementController(p_material_model, p_sample_model, - p_sld_model, p_scene_item); - - multilayer = p_sample_model->insertItem<MultiLayerItem>(); - - top = p_sample_model->insertItem<LayerItem>(multilayer); - middle = p_sample_model->insertItem<LayerItem>(multilayer); - bottom = p_sample_model->insertItem<LayerItem>(multilayer); - } - }; -}; - -SLDElementControllerTest::~SLDElementControllerTest() = default; - -TEST_F(SLDElementControllerTest, testInit) -{ - TestData test_data; - - EXPECT_EQ(1, test_data.p_sample_model->rootItem()->childrenCount()); - EXPECT_EQ(5, test_data.p_sample_model->rootItem()->children().at(0)->childrenCount()); - EXPECT_EQ(3, test_data.p_sld_model->rootItem()->childrenCount()); -} - -TEST_F(SLDElementControllerTest, testInsertRemoveLayer) -{ - TestData test_data; - - auto new_item = test_data.p_sample_model->insertItem<LayerItem>( - test_data.p_sample_model->rootItem()->children().at(0)); - - EXPECT_EQ(1, test_data.p_sample_model->rootItem()->childrenCount()); - EXPECT_EQ(6, test_data.p_sample_model->rootItem()->children().at(0)->childrenCount()); - EXPECT_EQ(4, test_data.p_sld_model->rootItem()->childrenCount()); - - test_data.p_sample_model->removeItem(new_item->parent(), - new_item->parent()->tagRowOfItem(new_item)); - EXPECT_EQ(1, test_data.p_sample_model->rootItem()->childrenCount()); - EXPECT_EQ(5, test_data.p_sample_model->rootItem()->children().at(0)->childrenCount()); - EXPECT_EQ(3, test_data.p_sld_model->rootItem()->childrenCount()); -} - -TEST_F(SLDElementControllerTest, testClearAllLayer) -{ - TestData test_data; - - test_data.p_sample_model->removeItem(test_data.top->parent(), - test_data.top->parent()->tagRowOfItem(test_data.top)); - test_data.p_sample_model->removeItem( - test_data.middle->parent(), test_data.middle->parent()->tagRowOfItem(test_data.middle)); - test_data.p_sample_model->removeItem( - test_data.bottom->parent(), test_data.bottom->parent()->tagRowOfItem(test_data.bottom)); - - EXPECT_EQ(1, test_data.p_sample_model->rootItem()->childrenCount()); - EXPECT_EQ(2, test_data.p_sample_model->rootItem()->children().at(0)->childrenCount()); - EXPECT_EQ(0, test_data.p_sld_model->rootItem()->childrenCount()); -} diff --git a/gui2/CMakeLists.txt b/gui2/CMakeLists.txt deleted file mode 100644 index b15a94ebabc1b3ac3e16ce326edaa33784ba2ae9..0000000000000000000000000000000000000000 --- a/gui2/CMakeLists.txt +++ /dev/null @@ -1,34 +0,0 @@ -set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/cmake/modules) - -include(configuration) - -set(library_name dareflcore) - -add_library(${library_name} SHARED "") - -# -- Generate header for export -- - -set(export_filename ${DAREFL_AUTOGEN_DIR}/darefl_export.h) -generate_export_header(${library_name} EXPORT_FILE_NAME ${export_filename}) - -add_subdirectory(dataloader) -add_subdirectory(importdataview) -add_subdirectory(layereditor) -add_subdirectory(mainwindow) -add_subdirectory(materialeditor) -add_subdirectory(model) -add_subdirectory(quicksimeditor) -add_subdirectory(resources) -add_subdirectory(settingsview) -add_subdirectory(sldeditor) -add_subdirectory(welcomeview) - -target_link_libraries(${library_name} PUBLIC MVVM::View Qt5::Core Qt5::Gui Qt5::Widgets - ${BornAgainCore_LIBRARY}) -target_include_directories(${library_name} PUBLIC - $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/..> - $<BUILD_INTERFACE:${DAREFL_AUTOGEN_DIR}>) - -set(executable_name bornagain2) -add_executable(${executable_name} main.cpp) -target_link_libraries(${executable_name} PRIVATE dareflcore) diff --git a/gui2/cmake/modules/ClangFormat.cmake b/gui2/cmake/modules/ClangFormat.cmake deleted file mode 100644 index eb89dcd4018555679704ab4c72b6ee97e031ba8b..0000000000000000000000000000000000000000 --- a/gui2/cmake/modules/ClangFormat.cmake +++ /dev/null @@ -1,46 +0,0 @@ -# Copyright Tomas Zeman 2019. -# Distributed under the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) - -function(clangformat_setup) - if(NOT CLANGFORMAT_EXECUTABLE) - set(CLANGFORMAT_EXECUTABLE clang-format) - endif() - - if(NOT EXISTS ${CLANGFORMAT_EXECUTABLE}) - find_program(clangformat_executable_tmp ${CLANGFORMAT_EXECUTABLE}) - if(clangformat_executable_tmp) - set(CLANGFORMAT_EXECUTABLE ${clangformat_executable_tmp}) - unset(clangformat_executable_tmp) - else() - message(FATAL_ERROR "ClangFormat: ${CLANGFORMAT_EXECUTABLE} not found! Aborting") - endif() - endif() - - foreach(clangformat_source ${ARGV}) - get_filename_component(clangformat_source ${clangformat_source} ABSOLUTE) - list(APPEND clangformat_sources ${clangformat_source}) - endforeach() - - add_custom_target(${PROJECT_NAME}_clangformat - COMMAND - ${CLANGFORMAT_EXECUTABLE} - -style=file - -i - ${clangformat_sources} - COMMENT - "Formating with ${CLANGFORMAT_EXECUTABLE} ..." - ) - - if(TARGET clangformat) - add_dependencies(clangformat ${PROJECT_NAME}_clangformat) - else() - add_custom_target(clangformat DEPENDS ${PROJECT_NAME}_clangformat) - endif() -endfunction() - -function(target_clangformat_setup target) - get_target_property(target_sources ${target} SOURCES) - clangformat_setup(${target_sources}) -endfunction() diff --git a/gui2/cmake/modules/CodeTools.cmake b/gui2/cmake/modules/CodeTools.cmake deleted file mode 100644 index ec991ff40bd90df0dfe67b665462909d97041f84..0000000000000000000000000000000000000000 --- a/gui2/cmake/modules/CodeTools.cmake +++ /dev/null @@ -1,18 +0,0 @@ -# Collection of functions to set-up code beautification and analysis -include(ClangFormat) - -# List of targets for project code beautification. -set(BEAUTIFICATION_TARGETS dareflcore testdareflcore) - -# Defines new target for 'clangformat' to beautify whole project. -# Use 'make clangformat' or 'cmake --build . --target clangformat' to beautify the code. -# Beautification settings are located in .clang-format in project directory. - -function(project_clangformat_setup) - set(all_sources) - foreach(target ${BEAUTIFICATION_TARGETS}) - get_target_property(target_sources ${target} SOURCES) - list(APPEND all_sources ${target_sources}) - endforeach() - clangformat_setup(${all_sources}) -endfunction() diff --git a/gui2/cmake/modules/configuration.cmake b/gui2/cmake/modules/configuration.cmake deleted file mode 100644 index c9c486a157434c5cdc060fb67218c8935c6a91c9..0000000000000000000000000000000000000000 --- a/gui2/cmake/modules/configuration.cmake +++ /dev/null @@ -1,59 +0,0 @@ -# ----------------------------------------------------------------------------- -# Modules -# ----------------------------------------------------------------------------- - -include(CTest) -include(CodeTools) -include(GenerateExportHeader) -include(GNUInstallDirs) - -# ----------------------------------------------------------------------------- -# Variables -# ----------------------------------------------------------------------------- - -get_filename_component(DAREFL_PROJECT_DIR "${CMAKE_CURRENT_LIST_DIR}/../.." ABSOLUTE) - -set(DAREFL_TESTOUTPUT_DIR ${CMAKE_BINARY_DIR}/test_output_darefl) - -# ----------------------------------------------------------------------------- -# Directories -# ----------------------------------------------------------------------------- - -set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) - -file(MAKE_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}) -file(MAKE_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) -file(MAKE_DIRECTORY ${DAREFL_TESTOUTPUT_DIR}) - -# directory for autogenerated configs -set(DAREFL_AUTOGEN_DIR ${CMAKE_BINARY_DIR}/autogen/darefl) -file(MAKE_DIRECTORY ${DAREFL_AUTOGEN_DIR}) - -# ----------------------------------------------------------------------------- -# Dependencies -# ----------------------------------------------------------------------------- - -set(CMAKE_AUTOMOC ON) -set(CMAKE_AUTORCC ON) - -find_package(Qt5 5.12 COMPONENTS Widgets Core Gui PrintSupport REQUIRED) -find_package(Threads) - -get_target_property(Qt5Widgets_location Qt5::Widgets LOCATION_Release) -message(STATUS " Qt5 libraries : ${Qt5Widgets_LIBRARIES} ${Qt5Widgets_location}") -message(STATUS " Qt5 Includes : ${Qt5Widgets_INCLUDE_DIRS}") - -# ----------------------------------------------------------------------------- -# Generating config files -# ----------------------------------------------------------------------------- - -configure_file(${DAREFL_PROJECT_DIR}/cmake/scripts/testconfig.h.in ${DAREFL_AUTOGEN_DIR}/testconfig.h @ONLY) - -# ----------------------------------------------------------------------------- -# Compile options -# ----------------------------------------------------------------------------- - -add_compile_options($<$<CXX_COMPILER_ID:MSVC>:/MP>) diff --git a/gui2/cmake/scripts/testconfig.h.in b/gui2/cmake/scripts/testconfig.h.in deleted file mode 100644 index 659c78455ee78a3753a9dc5ea4325499cd750c5d..0000000000000000000000000000000000000000 --- a/gui2/cmake/scripts/testconfig.h.in +++ /dev/null @@ -1,29 +0,0 @@ -// ************************************************************************** // -// -// Model-view-view-model framework for large GUI applications -// -//! @license GNU General Public License v3 or higher (see COPYING) -//! @authors see AUTHORS -// -// ************************************************************************** // - -#ifndef SCRIPTS_TESTCONFIG_H -#define SCRIPTS_TESTCONFIG_H - -#include <string> - -//! Provides build time information for unit tests. -//! Automatically generated by CMake from testconfig.h.in - -namespace TestConfig { - -inline std::string CMakeSourceDir() { return "@CMAKE_SOURCE_DIR@"; } -inline std::string CMakeBinaryDir() { return "@CMAKE_BINARY_DIR@"; } -inline std::string TestOutputDir() { return "@DAREFL_TESTOUTPUT_DIR@"; } -inline std::string ProjectSourceDir() { return "@DAREFL_PROJECT_DIR@"; } -inline std::string TestData() { return "@DAREFL_PROJECT_DIR@/tests/data"; } - -} - -#endif - diff --git a/gui2/core/CMakeLists.txt b/gui2/core/CMakeLists.txt deleted file mode 100644 index 93a834d6bb987a91d45814e8e302359549232700..0000000000000000000000000000000000000000 --- a/gui2/core/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -target_sources(${library_name} PRIVATE - app_constants.h -) diff --git a/gui2/core/app_constants.h b/gui2/core/app_constants.h deleted file mode 100644 index 2429462b7fb62b701fa9955b98d2fa378b29b7bb..0000000000000000000000000000000000000000 --- a/gui2/core/app_constants.h +++ /dev/null @@ -1,33 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/core/app_constants.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_CORE_APP_CONSTANTS_H -#define BORNAGAIN_GUI2_CORE_APP_CONSTANTS_H - -#include <QString> - -namespace gui2::Constants { - -//! Constants for QSettings. - -const QString DataLoaderGroupKey = "dataloader"; -const QString ParserPropertyGroupKey = "parserproperty"; - -//! Initial state of some widgets. - -const inline bool live_simulation_default_on = false; - -} // namespace gui2::Constants - -#endif // BORNAGAIN_GUI2_CORE_APP_CONSTANTS_H diff --git a/gui2/dataloader/CMakeLists.txt b/gui2/dataloader/CMakeLists.txt deleted file mode 100644 index 4ca2dd3d64dc6f28298c8af66fc7afafe2f5e54e..0000000000000000000000000000000000000000 --- a/gui2/dataloader/CMakeLists.txt +++ /dev/null @@ -1,32 +0,0 @@ -target_sources(${library_name} PRIVATE - datahandler.cpp - datahandler.h - dataloader_constants.h - dataloader_types.h - dataloader_utils.cpp - dataloader_utils.h - dataloaderdialog.cpp - dataloaderdialog.h - dataloadertoolbar.cpp - dataloadertoolbar.h - defaultparser.cpp - defaultparser.h - importfilewidget.cpp - importfilewidget.h - importtableheader.cpp - importtableheader.h - importtablemodel.cpp - importtablemodel.h - importtablewidget.cpp - importtablewidget.h - importtextview.cpp - importtextview.h - loaderpreviewpanel.cpp - loaderpreviewpanel.h - loaderselectorpanel.cpp - loaderselectorpanel.h - parserinterface.h - parserpropertywidget.cpp - parserpropertywidget.h -) - diff --git a/gui2/dataloader/datahandler.cpp b/gui2/dataloader/datahandler.cpp deleted file mode 100644 index 6603f326851341d56e04c7e8428d71c1119beec5..0000000000000000000000000000000000000000 --- a/gui2/dataloader/datahandler.cpp +++ /dev/null @@ -1,54 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/dataloader/datahandler.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/dataloader/datahandler.h" -#include "gui2/dataloader/dataloader_utils.h" -#include "mvvm/utils/containerutils.h" -#include <iostream> - -namespace gui2 { - -//! Load raw data from the list of files, if it was not loaded yet. -//! Remove data which is not present. - -void DataHandler::updateRawData(const std::vector<std::string>& file_names) -{ - for (const auto& file_name : file_names) - if (auto it = m_raw_data.find(file_name); it == m_raw_data.end()) - loadFile(file_name); - - for (auto it = m_raw_data.begin(); it != m_raw_data.end(); /* no increment */) { - if (ModelView::Utils::Contains(file_names, it->first)) - it++; - else - m_raw_data.erase(it++); - } -} - -//! Returns raw text data representing content of the file with given name. - -std::vector<std::string> DataHandler::textData(const std::string& file_name) -{ - auto it = m_raw_data.find(file_name); - return it != m_raw_data.end() ? it->second : std::vector<std::string>(); -} - -//! Load file with given name. File is assumed to be ASCII. - -void DataHandler::loadFile(const std::string& file_name) -{ - m_raw_data[file_name] = Utils::LoadASCIIFile(file_name); -} - -} // namespace gui2 diff --git a/gui2/dataloader/datahandler.h b/gui2/dataloader/datahandler.h deleted file mode 100644 index 9d2251c6d3cda51a5f942e1038f8db4a0a5f7945..0000000000000000000000000000000000000000 --- a/gui2/dataloader/datahandler.h +++ /dev/null @@ -1,45 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/dataloader/datahandler.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_DATALOADER_DATAHANDLER_H -#define BORNAGAIN_GUI2_DATALOADER_DATAHANDLER_H - -#include "darefl_export.h" -#include <map> -#include <string> -#include <vector> - -namespace gui2 { - -//! Handles raw data during the life time of DataHandlerDialog. -//! Loads the data from multiple ASCII files and stores in a buffer of strings. - -class DAREFLCORE_EXPORT DataHandler { -public: - DataHandler() = default; - - void updateRawData(const std::vector<std::string>& file_names); - - std::vector<std::string> textData(const std::string& file_name); - -private: - void loadFile(const std::string& file_name); - - //!< correspondence of file name to the raw data in the file (i.e. all strings) - std::map<std::string, std::vector<std::string>> m_raw_data; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_DATALOADER_DATAHANDLER_H diff --git a/gui2/dataloader/dataloader_constants.h b/gui2/dataloader/dataloader_constants.h deleted file mode 100644 index 9417c1739e6725a14ea5277d340d2a468989c020..0000000000000000000000000000000000000000 --- a/gui2/dataloader/dataloader_constants.h +++ /dev/null @@ -1,29 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/dataloader/dataloader_constants.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_DATALOADER_DATALOADER_CONSTANTS_H -#define BORNAGAIN_GUI2_DATALOADER_DATALOADER_CONSTANTS_H - -#include <string> -#include <vector> - -namespace gui2::Constants { - -const std::string AxisType = "Axis"; -const std::string IntensityType = "Intensity"; -const std::string IgnoreType = "Ignore"; - -} // namespace gui2::Constants - -#endif // BORNAGAIN_GUI2_DATALOADER_DATALOADER_CONSTANTS_H diff --git a/gui2/dataloader/dataloader_types.h b/gui2/dataloader/dataloader_types.h deleted file mode 100644 index b98b456a846bf692ceeca205e526d690b48d7dc1..0000000000000000000000000000000000000000 --- a/gui2/dataloader/dataloader_types.h +++ /dev/null @@ -1,54 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/dataloader/dataloader_types.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_DATALOADER_DATALOADER_TYPES_H -#define BORNAGAIN_GUI2_DATALOADER_DATALOADER_TYPES_H - -#include "darefl_export.h" -#include <functional> -#include <string> -#include <vector> - -namespace gui2 { - -//! Parser options to process multi column ASCII files. - -struct DAREFLCORE_EXPORT - ParserOptions { // #import Here the options for the default parser are defined - std::string m_header_prefix = "#"; //!< prefix denoting header line - std::string m_separator = " "; //!< column separator - std::string m_skip_index_pattern; //!< pattern denoting line to skip (i.e. '1,10-12,42') -}; - -//! Info about the column as defined by the user via ImportTableWidget. - -struct DAREFLCORE_EXPORT ColumnInfo { - int column{-1}; - std::string type_name; - std::string units; - double multiplier{0.0}; -}; - -//! Function to define if given index satisfies criteria. -using accept_int_t = std::function<bool(int)>; - -//! Function to define if given string should be accepted for further consideration. -using accept_string_t = std::function<bool(const std::string& line)>; - -//! Function to define line splitter according to some criteria. -using line_splitter_t = std::function<std::vector<std::string>(const std::string& line)>; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_DATALOADER_DATALOADER_TYPES_H diff --git a/gui2/dataloader/dataloader_utils.cpp b/gui2/dataloader/dataloader_utils.cpp deleted file mode 100644 index 83d351e0983b30c1be728beff8d486e71a8047ae..0000000000000000000000000000000000000000 --- a/gui2/dataloader/dataloader_utils.cpp +++ /dev/null @@ -1,221 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/dataloader/dataloader_utils.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/dataloader/dataloader_utils.h" -#include "gui2/dataloader/dataloader_constants.h" -#include "gui2/importdataview/graphimportdata.h" -#include "mvvm/utils/stringutils.h" -#include <algorithm> -#include <fstream> - -namespace gui2 { - -namespace { - -//! Returns true if given pair of values can represent range -bool isRepresentRange(const std::optional<int>& v0, const std::optional<int>& v1) -{ - if (v0.has_value() && v1.has_value()) - return v0.value() > 0 && v1.value() > 0 && v0.value() <= v1.value(); - return false; -} - -//! Finds in vector of ColumnInfo all columns of given type and returns it as a new vector. -std::vector<ColumnInfo> columnsForType(const std::vector<ColumnInfo>& input, - const std::string& columnType) -{ - std::vector<ColumnInfo> result; - std::copy_if(input.begin(), input.end(), std::back_inserter(result), - [columnType](auto x) { return x.type_name == columnType; }); - return result; -} - -} // namespace - -std::vector<std::string> Utils::LoadASCIIFile(const std::string& file_name) -{ - std::vector<std::string> result; - - std::ifstream file(file_name); - if (!file.is_open()) - throw std::ios_base::failure("Unable to open file '" + file_name + "'"); - for (std::string line; getline(file, line);) - result.emplace_back(line); - return result; -} - -std::vector<std::pair<int, int>> Utils::ExpandLineNumberPattern(const std::string& pattern) -{ - std::vector<std::pair<int, int>> result; - - // splitting "1, 2-3" first on comma-separated tokens - for (const auto& token : ModelView::Utils::SplitString(pattern, ",")) { - auto parts = ModelView::Utils::SplitString(token, "-"); - // splitting on dash-separared tokens - if (!parts.empty()) { - // if no "-" is present, make from "1" a pair {1, 1} - // if "-" is present, make from "1-2" a pair {1,2} - auto conv0 = ModelView::Utils::StringToInteger(parts[0]); - auto conv1 = parts.size() > 1 ? ModelView::Utils::StringToInteger(parts[1]) : conv0; - if (isRepresentRange(conv0, conv1)) - result.push_back({conv0.value(), conv1.value()}); - } - } - - return result; -} - -accept_int_t Utils::CreateLineNumberPatternValidator(const std::string& pattern) -{ - std::vector<std::pair<int, int>> expanded_pattern = Utils::ExpandLineNumberPattern(pattern); - auto result = [expanded_pattern](int line_number) { - for (auto pair : expanded_pattern) { - if (line_number >= pair.first && line_number <= pair.second) - return true; - } - return false; - }; - return result; -} - -accept_string_t Utils::CreateLinePrefixValidator(const std::string& prefix_to_exclude) -{ - auto result = [prefix_to_exclude](const std::string& line) { - // line contains spaces only - if (line.empty() || line.find_first_not_of(' ') == std::string::npos) - return false; - // line starts from pattern - return line.find_first_of(prefix_to_exclude) == 0 ? false : true; - }; - return result; -} - -line_splitter_t Utils::CreateSeparatorBasedSplitter(const std::string& separator) -{ - if (separator.empty()) - throw std::runtime_error("Error, empty separator."); - - bool is_space_only_separator = separator.find_first_not_of(' ') == std::string::npos; - auto result = [separator, is_space_only_separator](const std::string& line) { - std::vector<std::string> values; - std::string trimmed = ModelView::Utils::TrimWhitespace(line); - if (is_space_only_separator) - trimmed = ModelView::Utils::RemoveRepeatedSpaces(trimmed); - return ModelView::Utils::SplitString(trimmed, separator); - }; - return result; -} - -std::string Utils::AddHtmlDivTag(const std::string& line) -{ - const std::string open_div = "<div>"; - const std::string close_div = "</div>"; - std::string result; - return open_div + line + close_div; -} - -std::string Utils::AddHtmlColorTag(const std::string& line, const std::string& color) -{ - const std::string open_tag = "<font color=\"" + color + "\">"; - const std::string close_tag = "</font>"; - std::string result; - return open_tag + line + close_tag; -} - -std::string Utils::AddHtmlBackgroundTag(const std::string& line, const std::string& color) -{ - const std::string open_tag = "<span style=\"background-color:" + color + "\">"; - const std::string close_tag = "</span>"; - std::string result; - return open_tag + line + close_tag; -} - -std::string Utils::AddHtmlColorTagToParts(const std::string& line, - const std::vector<std::string>& parts, - const std::string& color_parts, - const std::string& color_rest) -{ - std::string result; - std::string_view view(line); - - if (parts.empty()) - return AddHtmlDivTag(AddHtmlColorTag(line, color_rest)); - - for (auto part : parts) { - auto it = view.find_first_of(part); - if (it > 0) - result.append(AddHtmlBackgroundTag(std::string(view.substr(0, it)), color_rest)); - result.append(AddHtmlColorTag(part, color_parts)); - view.remove_prefix(it + part.size()); - } - return AddHtmlDivTag(result); -} - -std::pair<std::vector<double>, std::vector<double>> -Utils::ExtractTwoColumns(const std::vector<std::vector<std::string>>& text_data, size_t col1, - size_t col2) -{ - std::vector<double> vec1, vec2; - for (const auto& row : text_data) { - if (col1 < row.size() && col2 < row.size()) { - auto val1 = ModelView::Utils::StringToDouble(row[col1]); - auto val2 = ModelView::Utils::StringToDouble(row[col2]); - if (val1.has_value() && val2.has_value()) { - vec1.push_back(val1.value()); - vec2.push_back(val2.value()); - } - } - } - - return std::make_pair(std::move(vec1), std::move(vec2)); -} - -std::vector<std::pair<ColumnInfo, ColumnInfo>> -Utils::CreateGraphInfoPairs(const std::vector<ColumnInfo>& column_info) -{ - std::vector<std::pair<ColumnInfo, ColumnInfo>> result; - - auto axis_columns = columnsForType(column_info, GUI::Constants::AxisType); - auto intensity_columns = columnsForType(column_info, GUI::Constants::IntensityType); - - if (axis_columns.size() != 1) - throw std::runtime_error("There must be exactly one column with AxisType selected."); - - for (const auto& intensity_info : intensity_columns) - result.push_back(std::make_pair(axis_columns.back(), intensity_info)); - - return result; -} - -GraphImportData Utils::CreateData(const std::vector<std::vector<std::string>>& text_data, - const ColumnInfo& axis, const ColumnInfo& intensity) -{ - GraphImportData result; - - auto [axis_values, intensity_values] = - Utils::ExtractTwoColumns(text_data, axis.column, intensity.column); - - std::transform(intensity_values.begin(), intensity_values.end(), intensity_values.begin(), - [&intensity](auto x) { return x * intensity.multiplier; }); - - result.bin_centers = axis_values; - result.axis_units = axis.units; - - result.bin_values = intensity_values; - result.signal_units = intensity.units; - - return result; -} - -} // namespace gui2 diff --git a/gui2/dataloader/dataloader_utils.h b/gui2/dataloader/dataloader_utils.h deleted file mode 100644 index 34e85ed3561f5e3e1651111b34440cc4ebd14ae1..0000000000000000000000000000000000000000 --- a/gui2/dataloader/dataloader_utils.h +++ /dev/null @@ -1,85 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/dataloader/dataloader_utils.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_DATALOADER_DATALOADER_UTILS_H -#define BORNAGAIN_GUI2_DATALOADER_DATALOADER_UTILS_H - -#include "gui2/dataloader/dataloader_types.h" - -namespace gui2 { - -struct GraphImportData; - -namespace Utils { - -//! Loads ASCII file, returns it in the form of vector of strings. -DAREFLCORE_EXPORT std::vector<std::string> LoadASCIIFile(const std::string& file_name); - -//! Expands string representing line number pattern to inclusive pairs of line numbers. -//! "1" will be expanded to { {1, 1} }, "1, 3-5" will be expanded to { {1, 1}, {3, 5} } -DAREFLCORE_EXPORT std::vector<std::pair<int, int>> -ExpandLineNumberPattern(const std::string& pattern); - -//! Creates a callback to define if given line number satisfies line number pattern. -//! "1, 4-6" will accept numbers {1, 4, 5, 6} and will refuse all others. -DAREFLCORE_EXPORT accept_int_t CreateLineNumberPatternValidator(const std::string& pattern); - -//! Creates a callback to define if given line has a valid content for further parsing. -//! Empty lines and lines starting from a given prefix will be excluded. -DAREFLCORE_EXPORT accept_string_t CreateLinePrefixValidator(const std::string& prefix_to_exclude); - -//! Creates line splitter based on separator. -DAREFLCORE_EXPORT line_splitter_t CreateSeparatorBasedSplitter(const std::string& separator); - -//! Returns string representing original 'line' wrapped in 'div' tag. -DAREFLCORE_EXPORT std::string AddHtmlDivTag(const std::string& line); - -//! Returns string representing original 'line' wrapped in html color tag. -DAREFLCORE_EXPORT std::string AddHtmlColorTag(const std::string& line, const std::string& color); - -//! Returns string representing original 'line' wrapped in 'div' tag. -DAREFLCORE_EXPORT std::string AddHtmlBackgroundTag(const std::string& line, - const std::string& color); - -//! Returns string representing original 'line', where 'parts' are surrounded with color tag. -DAREFLCORE_EXPORT std::string AddHtmlColorTagToParts(const std::string& line, - const std::vector<std::string>& parts, - const std::string& color_parts, - const std::string& color_rest); - -//! Extracts double values from two columns of a string array. -//! The row must be valid: string value must represent single double for both target columns, -//! rows should have enough columns. If a row is invalid, it will be skipped, so resulting arrays -//! have always the same length. - -DAREFLCORE_EXPORT std::pair<std::vector<double>, std::vector<double>> -ExtractTwoColumns(const std::vector<std::vector<std::string>>& text_data, size_t col1, size_t col2); - -//! Pack ColumnInfo into pairs representing {AxisType, IntensityType}. -//! For the moment we expect that only one column with AxisType exists. Number of intensity columns -//! can be arbitrary. - -DAREFLCORE_EXPORT std::vector<std::pair<ColumnInfo, ColumnInfo>> -CreateGraphInfoPairs(const std::vector<ColumnInfo>& column_info); - -//! Creates structure from text data. - -DAREFLCORE_EXPORT GraphImportData CreateData(const std::vector<std::vector<std::string>>& text_data, - const ColumnInfo& axis, const ColumnInfo& intensity); - -} // namespace Utils - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_DATALOADER_DATALOADER_UTILS_H diff --git a/gui2/dataloader/dataloaderdialog.cpp b/gui2/dataloader/dataloaderdialog.cpp deleted file mode 100644 index d8cac1f89372dd20307e55abc7e9f5c8f8f5f5ae..0000000000000000000000000000000000000000 --- a/gui2/dataloader/dataloaderdialog.cpp +++ /dev/null @@ -1,286 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/dataloader/dataloaderdialog.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/dataloader/dataloaderdialog.h" -#include "gui2/core/app_constants.h" -#include "gui2/dataloader/datahandler.h" -#include "gui2/dataloader/dataloader_types.h" -#include "gui2/dataloader/dataloader_utils.h" -#include "gui2/dataloader/dataloadertoolbar.h" -#include "gui2/dataloader/loaderpreviewpanel.h" -#include "gui2/dataloader/loaderselectorpanel.h" -#include "gui2/dataloader/parserinterface.h" -#include "mvvm/utils/fileutils.h" -#include "mvvm/widgets/widgetutils.h" -#include <QApplication> -#include <QDebug> -#include <QDialogButtonBox> -#include <QKeyEvent> -#include <QMessageBox> -#include <QPushButton> -#include <QSettings> -#include <QSplitter> -#include <QVBoxLayout> -#include <sstream> - -namespace gui2 { - -namespace { - -//! Wraps user method in try/catch and invoke it. -//! Provides busy-sign while executing, and warning dialog on exception catch. -template <typename T> void invoke_and_catch(T method) -{ - QApplication::setOverrideCursor(Qt::WaitCursor); - try { - std::invoke(method); - QApplication::restoreOverrideCursor(); - } catch (const std::exception& ex) { - QApplication::restoreOverrideCursor(); - QMessageBox msgBox; - - QString message = - QString("Exception was thrown while trying to load files\n\n%1").arg(ex.what()); - msgBox.setText(message); - msgBox.setIcon(msgBox.Critical); - msgBox.exec(); - } -} - -const QString dialogsize_key = "dialogsize"; -const QString splittersize_key = "splittersize"; - -const QString dialogsize_setting_name() -{ - return GUI::Constants::DataLoaderGroupKey + "/" + dialogsize_key; -} - -const QString splittersize_setting_name() -{ - return GUI::Constants::DataLoaderGroupKey + "/" + splittersize_key; -} - -//! Returns string representing import summary: filename and columns used for import. - -std::string createImportDescription(const QString& file_name, const ColumnInfo& axis_info, - const ColumnInfo& intensity_info) -{ - std::ostringstream ostr; - ostr << "file: '" << ModelView::Utils::WithTildeHomePath(file_name).toStdString() << "', "; - ostr << "columns: (" << axis_info.column << ", " << intensity_info.column << ")"; - return ostr.str(); -} - -} // namespace - -DataLoaderDialog::DataLoaderDialog(QWidget* parent) - : QDialog(parent) - , m_toolBar(new DataLoaderToolBar) - , m_selectorPanel(new LoaderSelectorPanel) - , m_previewPanel(new LoaderPreviewPanel) - , m_splitter(new QSplitter) - , m_dataHandler(std::make_unique<DataHandler>()) -{ - m_splitter->setChildrenCollapsible(false); - m_splitter->addWidget(m_selectorPanel); - m_splitter->addWidget(m_previewPanel); - - auto button_box = new QDialogButtonBox; - auto button = button_box->addButton("Import data", QDialogButtonBox::AcceptRole); - button->setAutoDefault(false); - button->setDefault(false); - - button = button_box->addButton("Cancel", QDialogButtonBox::RejectRole); - button->setAutoDefault(false); - button->setDefault(false); - - connect(button_box, &QDialogButtonBox::accepted, this, &DataLoaderDialog::accept); - connect(button_box, &QDialogButtonBox::rejected, this, &DataLoaderDialog::reject); - - auto layout = new QVBoxLayout(this); - layout->addWidget(m_toolBar); - layout->addWidget(m_splitter); - layout->addWidget(button_box); - - initConnections(); - setWindowTitle("Data import dialog"); - - readSettings(); -} - -DataLoaderDialog::~DataLoaderDialog() -{ - writeSettings(); -} - -//! Returns the result of whole parsing. - -std::vector<GraphImportData> DataLoaderDialog::graphImportData() const -{ - return m_graphImportData; -} - -//! Set list of target canvas to define entr where to import. - -void DataLoaderDialog::setTargetCanvas(const std::vector<std::string>& canvas_names, - int current_index) -{ - m_selectorPanel->setTargetCanvas(ModelView::Utils::toStringList(canvas_names), current_index); -} - -//! Returns index of target canvas for graph import. - -int DataLoaderDialog::targetCanvasIndex() const -{ - return m_selectorPanel->targetCanvasIndex(); -} - -//! Invokes file selector dialog. - -void DataLoaderDialog::invokeFileSelectorDialog() -{ - m_selectorPanel->onAddFilesRequest(); -} - -QStringList DataLoaderDialog::fileNames() const -{ - return m_selectorPanel->fileNames(); -} - -//! Make dialog intact to enter-key to handle it by LoadSelectorPanel. - -void DataLoaderDialog::keyPressEvent(QKeyEvent* event) -{ - if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) - return; - QDialog::keyPressEvent(event); -} - -void DataLoaderDialog::accept() -{ - invoke_and_catch([this]() { onParseAllRequest(); }); - - QDialog::accept(); - close(); -} - -//! Loads ASCII data from all files in a list. - -void DataLoaderDialog::onLoadFilesRequest() -{ - auto update_raw_data = [this]() { - m_dataHandler->updateRawData( - ModelView::Utils::fromStringList(m_selectorPanel->fileNames())); - }; - invoke_and_catch(update_raw_data); -} - -//! Show content of selected file in text/table views. - -void DataLoaderDialog::onShowFilePreviewRequest() -{ - auto selected_files = m_selectorPanel->selectedFileNames(); - if (selected_files.empty()) { - m_previewPanel->clearPanel(); - return; - } - - auto data_to_parse = m_dataHandler->textData(selected_files.back().toStdString()); - - // creating parser using current settings - auto parser = m_selectorPanel->createParser(); - parser->process(data_to_parse); - - m_previewPanel->showData(parser.get()); -} - -//! Parse all string data and generate graph data. - -void DataLoaderDialog::onParseAllRequest() -{ - m_graphImportData.clear(); - - auto parser = m_selectorPanel->createParser(); - for (const auto& name : m_selectorPanel->fileNames()) { - auto data_to_parse = m_dataHandler->textData(name.toStdString()); - - parser->process(data_to_parse); - auto parsed_text = parser->parsedData(); - - auto columns = m_previewPanel->columnInfo(); - for (auto [axis_info, intensity_info] : Utils::CreateGraphInfoPairs(columns)) { - auto data = Utils::CreateData(parsed_text, axis_info, intensity_info); - data.graph_description = createImportDescription(name, axis_info, intensity_info); - m_graphImportData.emplace_back(data); - } - } -} - -//! Reads dialog settings. - -void DataLoaderDialog::readSettings() -{ - QSettings settings; - - if (settings.contains(dialogsize_setting_name())) - resize(settings.value(dialogsize_setting_name(), QSize(800, 600)).toSize()); - - if (settings.contains(splittersize_setting_name())) { - QStringList splitter_sizes = QStringList() << "400" - << "400"; - splitter_sizes = settings.value(splittersize_setting_name(), splitter_sizes).toStringList(); - QList<int> sizes; - for (auto num : splitter_sizes) - sizes.push_back(num.toInt()); - m_splitter->setSizes(sizes); - } -} - -//! Writes dialog settings. - -void DataLoaderDialog::writeSettings() -{ - QSettings settings; - settings.setValue(dialogsize_setting_name(), size()); - - QStringList splitter_sizes; - for (auto x : m_splitter->sizes()) - splitter_sizes.push_back(QString::number(x)); - settings.setValue(splittersize_setting_name(), splitter_sizes); -} - -//! Init interconnections of all widgets. - -void DataLoaderDialog::initConnections() -{ - // connect toolbar and LoaderSelectorPanel - connect(m_toolBar, &DataLoaderToolBar::addFilesRequest, m_selectorPanel, - &LoaderSelectorPanel::onAddFilesRequest); - connect(m_toolBar, &DataLoaderToolBar::removeFilesRequest, m_selectorPanel, - &LoaderSelectorPanel::onRemoveFileRequest); - - // updates raw data container when file list changed - connect(m_selectorPanel, &LoaderSelectorPanel::fileNamesChanged, this, - &DataLoaderDialog::onLoadFilesRequest); - - // update text/table view when file selection changed - connect(m_selectorPanel, &LoaderSelectorPanel::fileSelectionChanged, this, - &DataLoaderDialog::onShowFilePreviewRequest); - - // update text/table view when parser properties changed - connect(m_selectorPanel, &LoaderSelectorPanel::parserPropertyChanged, this, - &DataLoaderDialog::onShowFilePreviewRequest); -} - -} // namespace gui2 diff --git a/gui2/dataloader/dataloaderdialog.h b/gui2/dataloader/dataloaderdialog.h deleted file mode 100644 index fe14c692666c3702a9ae7714a272b59a5a1e168b..0000000000000000000000000000000000000000 --- a/gui2/dataloader/dataloaderdialog.h +++ /dev/null @@ -1,77 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/dataloader/dataloaderdialog.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_DATALOADER_DATALOADERDIALOG_H -#define BORNAGAIN_GUI2_DATALOADER_DATALOADERDIALOG_H - -#include "darefl_export.h" -#include "gui2/importdataview/graphimportdata.h" -#include <QDialog> -#include <memory> -#include <vector> - -class QSplitter; - -namespace gui2 { - -class DataLoaderToolBar; -class LoaderSelectorPanel; -class LoaderPreviewPanel; -class DataHandler; - -//! Main dialog for the data loader. - -class DAREFLCORE_EXPORT DataLoaderDialog : public QDialog { - Q_OBJECT - -public: - DataLoaderDialog(QWidget* parent = nullptr); - ~DataLoaderDialog(); - - std::vector<GraphImportData> graphImportData() const; - - void setTargetCanvas(const std::vector<std::string>& canvas_names, int current_index); - - int targetCanvasIndex() const; - - void invokeFileSelectorDialog(); - - QStringList fileNames() const; - -protected: - void keyPressEvent(QKeyEvent* event) override; - void accept() override; - -private slots: - void onLoadFilesRequest(); - void onShowFilePreviewRequest(); - void onParseAllRequest(); - -private: - void readSettings(); - void writeSettings(); - void initConnections(); - - DataLoaderToolBar* m_toolBar{nullptr}; - LoaderSelectorPanel* m_selectorPanel{nullptr}; - LoaderPreviewPanel* m_previewPanel{nullptr}; - QSplitter* m_splitter{nullptr}; - - std::unique_ptr<DataHandler> m_dataHandler; - std::vector<GraphImportData> m_graphImportData; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_DATALOADER_DATALOADERDIALOG_H diff --git a/gui2/dataloader/dataloadertoolbar.cpp b/gui2/dataloader/dataloadertoolbar.cpp deleted file mode 100644 index f463b0fe91fc9b81cc1484d662c72cfeb15480a0..0000000000000000000000000000000000000000 --- a/gui2/dataloader/dataloadertoolbar.cpp +++ /dev/null @@ -1,41 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/dataloader/dataloadertoolbar.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/dataloader/dataloadertoolbar.h" -#include "gui2/mainwindow/styleutils.h" -#include <QAction> - -namespace gui2 { - -DataLoaderToolBar::DataLoaderToolBar(QWidget* parent) : QToolBar(parent) -{ - GUI::Utils::Style::SetToolBarStyleTextBesides(this); - - // add files - auto action = new QAction("Add files", this); - action->setIcon(QIcon(":/icons/import.svg")); - action->setToolTip("Adds more files to the list.\n " - "All of them will be parsed in the same way."); - connect(action, &QAction::triggered, [this]() { this->addFilesRequest(); }); - addAction(action); - - // remove files - action = new QAction("Remove files", this); - action->setIcon(QIcon(":/icons/beaker-remove-outline.svg")); - action->setToolTip("Remove selected files from the list."); - connect(action, &QAction::triggered, [this]() { this->removeFilesRequest(); }); - addAction(action); -} - -} // namespace gui2 diff --git a/gui2/dataloader/dataloadertoolbar.h b/gui2/dataloader/dataloadertoolbar.h deleted file mode 100644 index dc16b75c873cac47440d933a5d236e9a36cf59c1..0000000000000000000000000000000000000000 --- a/gui2/dataloader/dataloadertoolbar.h +++ /dev/null @@ -1,38 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/dataloader/dataloadertoolbar.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_DATALOADER_DATALOADERTOOLBAR_H -#define BORNAGAIN_GUI2_DATALOADER_DATALOADERTOOLBAR_H - -#include "darefl_export.h" -#include <QToolBar> - -namespace gui2 { - -//! Tool bar for DataLoaderDialog. - -class DAREFLCORE_EXPORT DataLoaderToolBar : public QToolBar { - Q_OBJECT - -public: - DataLoaderToolBar(QWidget* parent = nullptr); - -signals: - void addFilesRequest(); - void removeFilesRequest(); -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_DATALOADER_DATALOADERTOOLBAR_H diff --git a/gui2/dataloader/defaultparser.cpp b/gui2/dataloader/defaultparser.cpp deleted file mode 100644 index 2ebe6a23a93706eca3d1907346f3514277de1785..0000000000000000000000000000000000000000 --- a/gui2/dataloader/defaultparser.cpp +++ /dev/null @@ -1,80 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/dataloader/defaultparser.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/dataloader/defaultparser.h" -#include "gui2/dataloader/dataloader_utils.h" -#include <stdexcept> - -namespace gui2 { - -DefaultParser::DefaultParser(const ParserOptions& options) -{ - m_isSkipLineNumber = Utils::CreateLineNumberPatternValidator(options.m_skip_index_pattern); - m_isValidLineContent = Utils::CreateLinePrefixValidator(options.m_header_prefix); - m_line_splitter = Utils::CreateSeparatorBasedSplitter(options.m_separator); -} - -//! Parse data representing content of ASCII file. - -void DefaultParser::process(const std::vector<std::string>& raw_data) -{ - m_rawData = raw_data; - m_parsedData.clear(); - - int index{0}; - for (const auto& line : m_rawData) { - bool isValidLine = m_isValidLineContent(line) && !m_isSkipLineNumber(index + 1); - - if (isValidLine) - m_parsedData.emplace(index, m_line_splitter(line)); - - ++index; - } -} - -//! Returns total number of lines in raw data. - -size_t DefaultParser::totalLineCount() const -{ - return m_rawData.size(); -} - -//! Returns a pair representing raw line and flag describing parsing results. - -std::string DefaultParser::getLine(size_t index) const -{ - if (index >= m_rawData.size()) - throw std::runtime_error("Error in DefaultParser: out of bounds."); - - return m_rawData[index]; -} - -std::vector<std::string> DefaultParser::parseResults(size_t index) const -{ - auto it = m_parsedData.find(index); - return it == m_parsedData.end() ? std::vector<std::string>() : it->second; -} - -std::vector<std::vector<std::string>> DefaultParser::parsedData() const -{ - std::vector<std::vector<std::string>> result; - for (size_t index = 0; index < totalLineCount(); ++index) { - if (auto it = m_parsedData.find(index); it != m_parsedData.end()) - result.push_back(it->second); - } - - return result; -} - -} // namespace gui2 diff --git a/gui2/dataloader/defaultparser.h b/gui2/dataloader/defaultparser.h deleted file mode 100644 index 43808ecfb5116036134896e538c78b2b9c4542ba..0000000000000000000000000000000000000000 --- a/gui2/dataloader/defaultparser.h +++ /dev/null @@ -1,57 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/dataloader/defaultparser.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_DATALOADER_DEFAULTPARSER_H -#define BORNAGAIN_GUI2_DATALOADER_DEFAULTPARSER_H - -#include "darefl_export.h" -#include "gui2/dataloader/dataloader_types.h" -#include "gui2/dataloader/parserinterface.h" -#include <map> - -namespace gui2 { - -//! Provides basic algorirthm for parsing multi-string data representing content -//! of multi-column ASCII file. -//! + Skips empty lines or lines matching the prefix. -//! + Skips lines matching given line number pattern. -//! + Parse data in columns of basing on given separator value. - -// #import Here is a parser implementation (the only present parser so far) -class DAREFLCORE_EXPORT DefaultParser : public ParserInterface { -public: - DefaultParser(const ParserOptions& options); - - void process(const std::vector<std::string>& raw_data) override; - - size_t totalLineCount() const override; - - std::string getLine(size_t index) const override; - - std::vector<std::string> parseResults(size_t index) const override; - - std::vector<std::vector<std::string>> parsedData() const override; - -private: - accept_int_t m_isSkipLineNumber; - accept_string_t m_isValidLineContent; - line_splitter_t m_line_splitter; - std::vector<std::string> m_rawData; - //!< correspondence of parsed data to original line index - std::map<size_t, std::vector<std::string>> m_parsedData; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_DATALOADER_DEFAULTPARSER_H diff --git a/gui2/dataloader/importfilewidget.cpp b/gui2/dataloader/importfilewidget.cpp deleted file mode 100644 index 4c8d90b76fba3179d69378233ba8f3f6398914d7..0000000000000000000000000000000000000000 --- a/gui2/dataloader/importfilewidget.cpp +++ /dev/null @@ -1,184 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/dataloader/importfilewidget.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/dataloader/importfilewidget.h" -#include "gui2/core/app_constants.h" -#include "mvvm/utils/binutils.h" -#include "mvvm/utils/fileutils.h" -#include <QFileDialog> -#include <QItemSelectionModel> -#include <QListView> -#include <QMessageBox> -#include <QSettings> -#include <QStringListModel> -#include <QVBoxLayout> - -namespace gui2 { - -namespace { -const QString current_workdir_key = "currentworkdir"; - -const QString workdir_setting_name() -{ - return GUI::Constants::DataLoaderGroupKey + "/" + current_workdir_key; -} - -} // namespace - -ImportFileWidget::ImportFileWidget(QWidget* parent) - : QWidget(parent), m_listView(new QListView), m_listModel(new QStringListModel(this)) -{ - readSettings(); - - auto layout = new QVBoxLayout(this); - layout->setContentsMargins(0, 0, 0, 0); - layout->addWidget(m_listView); - - m_listView->setModel(m_listModel); - m_listView->setEditTriggers(QAbstractItemView::NoEditTriggers); - m_listView->setAlternatingRowColors(true); - m_listView->setSelectionMode(QAbstractItemView::ExtendedSelection); - - connect(m_listView->selectionModel(), &QItemSelectionModel::selectionChanged, this, - &ImportFileWidget::fileSelectionChanged); -} - -ImportFileWidget::~ImportFileWidget() -{ - writeSettings(); -} - -//! Summons dialog for file selections, update list view with file names. - -void ImportFileWidget::onAddFilesRequest() -{ - QFileDialog dialog(this, "Select one or more files to load", m_currentWorkdir); - dialog.setFileMode(QFileDialog::ExistingFiles); - dialog.setNameFilter("Text (*.txt *.csv *.dat);; Other (*.*)"); - dialog.setOption(QFileDialog::DontUseNativeDialog); - QStringList file_names = dialog.exec() ? dialog.selectedFiles() : QStringList(); - - file_names = validateForBinaryFiles(file_names); - - if (file_names.empty()) - return; - - updateCurrentWorkdir(file_names); - addFileNamesToModel(file_names); -} - -//! Removes currently selected file - -void ImportFileWidget::onRemoveFileRequest() -{ - auto selected = m_listView->selectionModel()->selectedIndexes(); - while (!selected.empty()) { - m_listModel->removeRow(selected.back().row()); - selected = m_listView->selectionModel()->selectedIndexes(); - } - - emit fileNamesChanged(); - - makeLastSelected(); -} - -//! Retuns the list of all file names imported by the user. - -QStringList ImportFileWidget::fileNames() const -{ - return m_listModel->stringList(); -} - -//! Retuns the list of currently selected file names. - -QStringList ImportFileWidget::selectedFileNames() const -{ - QStringList result; - for (auto index : m_listView->selectionModel()->selectedIndexes()) - result.append(m_listModel->data(index).toString()); - return result; -} - -//! Loads widget settings. - -void ImportFileWidget::readSettings() -{ - QSettings settings; - m_currentWorkdir = QDir::homePath(); - - if (settings.contains(workdir_setting_name())) - m_currentWorkdir = settings.value(workdir_setting_name()).toString(); -} - -//! Writes widget settings. - -void ImportFileWidget::writeSettings() -{ - QSettings settings; - settings.setValue(workdir_setting_name(), m_currentWorkdir); -} - -//! Returns list validated for binary files. - -QStringList ImportFileWidget::validateForBinaryFiles(const QStringList& file_names) -{ - QStringList result; - for (const auto& file_name : file_names) { - if (ModelView::Utils::is_binary(file_name.toStdString())) { - QMessageBox msgBox; - msgBox.setText(file_name + "\nmay be a binary file. Open it anyway?"); - msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); - int ret = msgBox.exec(); - if (ret == QMessageBox::Yes) - result.push_back(file_name); - } else { - result.push_back(file_name); - } - } - return result; -} - -//! Updates current working dir. - -void ImportFileWidget::updateCurrentWorkdir(const QStringList& file_names) -{ - auto file_name = file_names.back(); - auto parent_path = ModelView::Utils::parent_path(file_name.toStdString()); - m_currentWorkdir = QString::fromStdString(parent_path); -} - -//! Adds given list of file names to the model. - -void ImportFileWidget::addFileNamesToModel(const QStringList& file_names) -{ - auto current_names = fileNames(); - QStringList updated_names = current_names + file_names; - updated_names.removeDuplicates(); - m_listModel->setStringList(updated_names); - - emit fileNamesChanged(); - - makeLastSelected(); -} - -void ImportFileWidget::makeLastSelected() -{ - if (m_listView->selectionModel()->selectedIndexes().empty()) { - auto flags = QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows; - auto toSelect = m_listModel->index(m_listModel->rowCount() - 1); - m_listView->selectionModel()->select(toSelect, flags); - } -} - -} // namespace gui2 diff --git a/gui2/dataloader/importfilewidget.h b/gui2/dataloader/importfilewidget.h deleted file mode 100644 index c9360e5def2c762a093cdaf15f366c8d8d88c4ef..0000000000000000000000000000000000000000 --- a/gui2/dataloader/importfilewidget.h +++ /dev/null @@ -1,67 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/dataloader/importfilewidget.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_DATALOADER_IMPORTFILEWIDGET_H -#define BORNAGAIN_GUI2_DATALOADER_IMPORTFILEWIDGET_H - -#include "darefl_export.h" -#include <QWidget> - -class QListView; -class QStringListModel; - -namespace gui2 { - -//! Provides the possibility to select file names on disk and add them to list view. -//! List represents names of ASCII files which will be later imported and parsed. -//! Part of LoaderPreviewPanel. - -class DAREFLCORE_EXPORT ImportFileWidget : public QWidget { - Q_OBJECT - -public: - ImportFileWidget(QWidget* parent = nullptr); - ~ImportFileWidget(); - -public slots: - void onAddFilesRequest(); - void onRemoveFileRequest(); - - QStringList fileNames() const; - - QStringList selectedFileNames() const; - -signals: - void fileNamesChanged(); - void fileSelectionChanged(); - -private: - void readSettings(); - void writeSettings(); - - QStringList validateForBinaryFiles(const QStringList& file_names); - - void updateCurrentWorkdir(const QStringList& file_names); - void addFileNamesToModel(const QStringList& file_names); - - void makeLastSelected(); - - QListView* m_listView{nullptr}; - QStringListModel* m_listModel{nullptr}; - QString m_currentWorkdir; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_DATALOADER_IMPORTFILEWIDGET_H diff --git a/gui2/dataloader/importtableheader.cpp b/gui2/dataloader/importtableheader.cpp deleted file mode 100644 index cdae6c799dd6b3e919a5805357da71bcb9ab4159..0000000000000000000000000000000000000000 --- a/gui2/dataloader/importtableheader.cpp +++ /dev/null @@ -1,136 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/dataloader/importtableheader.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/dataloader/importtableheader.h" -#include "gui2/dataloader/dataloader_constants.h" -#include "gui2/dataloader/dataloader_types.h" -#include "mvvm/model/comboproperty.h" - -using ModelView::ComboProperty; - -namespace gui2 { - -namespace { -const std::vector<std::string> utilityRowNames = {"Type", "Unit", "Multiplier"}; - -const std::vector<std::string> typeNames = {GUI::Constants::AxisType, GUI::Constants::IntensityType, - GUI::Constants::IgnoreType}; - -const std::vector<std::string> unitNames = {"a.u.", "counts", "1/nm", "Angstrom"}; - -//! Returns column type from column index. -std::string suggestColumnTypeFromColumnIndex(int col) -{ - return col < static_cast<int>(typeNames.size()) ? typeNames[col] : GUI::Constants::IgnoreType; -} - -QVariant CreateTypeVariant(int col = 0) -{ - auto combo = ComboProperty::createFrom(typeNames); - auto selected_value = suggestColumnTypeFromColumnIndex(col); - combo.setValue(selected_value); - return QVariant::fromValue<ComboProperty>(combo); -} - -std::vector<QVariant> CreateTypeVariants(int maxColumnCount) -{ - std::vector<QVariant> result; - for (int i = 0; i < maxColumnCount; ++i) - result.push_back(CreateTypeVariant(i)); - return result; -} - -std::vector<QVariant> CreateUnitVariants(int maxColumnCount) -{ - std::vector<QVariant> result; - for (int i = 0; i < maxColumnCount; ++i) - result.push_back(QVariant::fromValue<ComboProperty>(ComboProperty::createFrom(unitNames))); - return result; -} - -std::vector<QVariant> CreateMultiplierVariants(int maxColumnCount) -{ - std::vector<QVariant> result(maxColumnCount, 1.0); - return result; -} - -} // namespace - -ImportTableHeader::ImportTableHeader(int max_column_count) : m_maxColumnCount(max_column_count) -{ - init_data(); -} - -int ImportTableHeader::rowCount() const -{ - return utilityRowNames.size(); -} - -int ImportTableHeader::columnCount() const -{ - return m_maxColumnCount; -} - -QVariant ImportTableHeader::data(int row, int column) const -{ - return isValid(row, column) ? m_data[row][column] : QVariant(); -} - -bool ImportTableHeader::setData(int row, int column, const QVariant& variant) -{ - if (isValid(row, column)) { - m_data[row][column] = variant; - return true; - } - - return false; -} - -std::string ImportTableHeader::rowName(int row) const -{ - return utilityRowNames[row]; -} - -std::vector<ColumnInfo> ImportTableHeader::columnInfo() const -{ - std::vector<ColumnInfo> result; - for (int column = 0; column < columnCount(); ++column) { - ColumnInfo info; - info.column = column; - info.type_name = data(TYPE, column).value<ComboProperty>().value(); - info.units = data(UNITS, column).value<ComboProperty>().value(); - info.multiplier = data(MULTIPLIER, column).value<double>(); - result.push_back(info); - } - - return result; -} - -void ImportTableHeader::init_data() -{ - m_data.resize(MAX); - m_data[TYPE] = CreateTypeVariants(columnCount()); - m_data[UNITS] = CreateUnitVariants(columnCount()); - m_data[MULTIPLIER] = CreateMultiplierVariants(columnCount()); -} - -//! Returns true if given pair of indices are valid for data array. - -bool ImportTableHeader::isValid(int row, int column) const -{ - return (row >= 0 && row < static_cast<int>(m_data.size())) - && (column >= 0 && column < static_cast<int>(m_data[row].size())); -} - -} // namespace gui2 diff --git a/gui2/dataloader/importtableheader.h b/gui2/dataloader/importtableheader.h deleted file mode 100644 index 5c1247b45919ccc8892dd653a8647599be05cc5c..0000000000000000000000000000000000000000 --- a/gui2/dataloader/importtableheader.h +++ /dev/null @@ -1,57 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/dataloader/importtableheader.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_DATALOADER_IMPORTTABLEHEADER_H -#define BORNAGAIN_GUI2_DATALOADER_IMPORTTABLEHEADER_H - -#include "darefl_export.h" -#include <QVariant> -#include <vector> - -namespace gui2 { - -struct ColumnInfo; - -//! Holds all data related to the content of utility rows in ImportTableModel. - -class DAREFLCORE_EXPORT ImportTableHeader { -public: - enum RowTypes { TYPE, UNITS, MULTIPLIER, MAX }; - using header_data_t = std::vector<std::vector<QVariant>>; - - ImportTableHeader(int max_column_count); - - int rowCount() const; - - int columnCount() const; - - QVariant data(int row, int column) const; - - bool setData(int row, int column, const QVariant& variant); - - std::string rowName(int row) const; - - std::vector<ColumnInfo> columnInfo() const; - -private: - void init_data(); - bool isValid(int row, int column) const; - - header_data_t m_data; - int m_maxColumnCount; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_DATALOADER_IMPORTTABLEHEADER_H diff --git a/gui2/dataloader/importtablemodel.cpp b/gui2/dataloader/importtablemodel.cpp deleted file mode 100644 index 5b61de4fab783328c03dc99e07dac5c2d0a6a14a..0000000000000000000000000000000000000000 --- a/gui2/dataloader/importtablemodel.cpp +++ /dev/null @@ -1,141 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/dataloader/importtablemodel.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/dataloader/importtablemodel.h" -#include "gui2/dataloader/dataloader_types.h" -#include "gui2/dataloader/importtableheader.h" -#include <QBrush> - -namespace gui2 { - -namespace { -//! Returns maximum number of columns in 2D data vector. -int maxColumnCount(const ImportTableModel::raw_data_t& data) -{ - int result{0}; - for (const auto& x : data) - result = std::max(result, static_cast<int>(x.size())); - return result; -} - -const int default_header_ncols = 2; -}; // namespace - -ImportTableModel::ImportTableModel(QObject* parent) - : QAbstractTableModel(parent) - , m_header(std::make_unique<ImportTableHeader>(default_header_ncols)) -{ -} - -ImportTableModel::~ImportTableModel() = default; - -//! Sets content of the model. - -void ImportTableModel::setRawData(const ImportTableModel::raw_data_t& raw_data) -{ - beginResetModel(); - m_maxColumnCount = maxColumnCount(raw_data); - m_header = std::make_unique<ImportTableHeader>(m_maxColumnCount); - m_rawData = raw_data; - endResetModel(); -} - -int ImportTableModel::rowCount(const QModelIndex&) const -{ - return static_cast<int>(m_rawData.size()) + utilityRowCount(); -} - -int ImportTableModel::columnCount(const QModelIndex&) const -{ - return m_maxColumnCount; -} - -QVariant ImportTableModel::data(const QModelIndex& index, int role) const -{ - if (!index.isValid()) - return QVariant(); - - if (role == Qt::DisplayRole || role == Qt::EditRole) - return dataFromIndex(index); - - else if (role == Qt::BackgroundRole && index.row() < utilityRowCount()) - return QBrush(Qt::lightGray); - - return QVariant(); -} - -bool ImportTableModel::setData(const QModelIndex& index, const QVariant& value, int role) -{ - if (!index.isValid()) - return false; - - if (index.row() < utilityRowCount() && role == Qt::EditRole) - return m_header->setData(index.row(), index.column(), value); - - return false; -} - -QVariant ImportTableModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if (orientation == Qt::Horizontal || role != Qt::DisplayRole) - return QVariant(); - - return section < utilityRowCount() ? QString::fromStdString(m_header->rowName(section)) - : QVariant(section - utilityRowCount() + 1); -} - -Qt::ItemFlags ImportTableModel::flags(const QModelIndex& index) const -{ - Qt::ItemFlags result = QAbstractItemModel::flags(index); - if (index.row() < utilityRowCount()) - result |= Qt::ItemIsEnabled | Qt::ItemIsEditable; - else - result |= Qt::ItemIsEnabled | Qt::ItemIsSelectable; - return result; -} - -std::vector<ColumnInfo> ImportTableModel::columnInfo() const -{ - return m_header->columnInfo(); -} - -int ImportTableModel::utilityRowCount() const -{ - return m_header ? m_header->rowCount() : 0; -} - -//! Returns data from index. Combines header data with parsed user data. - -QVariant ImportTableModel::dataFromIndex(const QModelIndex& index) const -{ - if (!index.isValid()) - return QVariant(); - - if (index.row() < utilityRowCount()) { - return m_header->data(index.row(), index.column()); - - } else { - int row = index.row() - utilityRowCount(); - if (row >= 0 && row < static_cast<int>(m_rawData.size())) { - int col = index.column(); - if (col >= 0 && col < static_cast<int>(m_rawData[row].size())) { - auto str = m_rawData[static_cast<int>(row)][static_cast<int>(col)]; - return QString::fromStdString(str); - } - } - } - return QVariant(); -} - -} // namespace gui2 diff --git a/gui2/dataloader/importtablemodel.h b/gui2/dataloader/importtablemodel.h deleted file mode 100644 index 6817673dc1b835f406135183e7773394b43bed9d..0000000000000000000000000000000000000000 --- a/gui2/dataloader/importtablemodel.h +++ /dev/null @@ -1,69 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/dataloader/importtablemodel.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_DATALOADER_IMPORTTABLEMODEL_H -#define BORNAGAIN_GUI2_DATALOADER_IMPORTTABLEMODEL_H - -#include "darefl_export.h" -#include <QAbstractTableModel> -#include <memory> -#include <string> -#include <vector> - -namespace gui2 { - -struct ColumnInfo; - -class ImportTableHeader; - -//! Table model to hold imported ASCII data after parsing it to multi-column presentation. - -class DAREFLCORE_EXPORT ImportTableModel : public QAbstractTableModel { - Q_OBJECT - -public: - using raw_data_t = std::vector<std::vector<std::string>>; - - ImportTableModel(QObject* parent = nullptr); - ~ImportTableModel() override; - - void setRawData(const raw_data_t& raw_data); - - int rowCount(const QModelIndex& = QModelIndex()) const override; - - int columnCount(const QModelIndex& = QModelIndex()) const override; - - QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; - - bool setData(const QModelIndex& index, const QVariant& value, int role) override; - - QVariant headerData(int section, Qt::Orientation orientation, int role) const override; - - Qt::ItemFlags flags(const QModelIndex& index) const override; - - std::vector<ColumnInfo> columnInfo() const; - -private: - int utilityRowCount() const; - QVariant dataFromIndex(const QModelIndex& index) const; - - std::unique_ptr<ImportTableHeader> m_header; - raw_data_t m_rawData; //! parsed column data - - int m_maxColumnCount{0}; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_DATALOADER_IMPORTTABLEMODEL_H diff --git a/gui2/dataloader/importtablewidget.cpp b/gui2/dataloader/importtablewidget.cpp deleted file mode 100644 index f2ae8123a44999e74568c05c882b246f74996c93..0000000000000000000000000000000000000000 --- a/gui2/dataloader/importtablewidget.cpp +++ /dev/null @@ -1,51 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/dataloader/importtablewidget.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/dataloader/importtablewidget.h" -#include "gui2/dataloader/dataloader_types.h" -#include "gui2/dataloader/importtablemodel.h" -#include "mvvm/viewmodel/viewmodeldelegate.h" -#include <QStandardItemModel> -#include <QTableView> -#include <QVBoxLayout> - -namespace gui2 { - -ImportTableWidget::ImportTableWidget(QWidget* parent) - : QWidget(parent) - , m_tableModel(new ImportTableModel(this)) - , m_tableView(new QTableView) - , m_delegate(new ModelView::ViewModelDelegate) -{ - auto layout = new QVBoxLayout(this); - layout->setContentsMargins(0, 0, 0, 0); - layout->addWidget(m_tableView); - - m_tableView->setItemDelegate(m_delegate.get()); - m_tableView->setModel(m_tableModel); -} - -ImportTableWidget::~ImportTableWidget() = default; - -void ImportTableWidget::setRawData(const std::vector<std::vector<std::string>>& table_data) -{ - m_tableModel->setRawData(table_data); -} - -std::vector<ColumnInfo> ImportTableWidget::columnInfo() const -{ - return m_tableModel->columnInfo(); -} - -} // namespace gui2 diff --git a/gui2/dataloader/importtablewidget.h b/gui2/dataloader/importtablewidget.h deleted file mode 100644 index 69e9ba1de9916fb6496147d5aaa43db61ef40206..0000000000000000000000000000000000000000 --- a/gui2/dataloader/importtablewidget.h +++ /dev/null @@ -1,58 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/dataloader/importtablewidget.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_DATALOADER_IMPORTTABLEWIDGET_H -#define BORNAGAIN_GUI2_DATALOADER_IMPORTTABLEWIDGET_H - -#include "darefl_export.h" -#include <QWidget> -#include <memory> -#include <string> -#include <vector> - -class QTableView; - -namespace ModelView { -class ViewModelDelegate; -} - -namespace gui2 { - -struct ColumnInfo; - -class ImportTableModel; - -//! Contains table with imported data. -//! Belongs to LoaderPreviewPanel. - -class DAREFLCORE_EXPORT ImportTableWidget : public QWidget { - Q_OBJECT - -public: - ImportTableWidget(QWidget* parent = nullptr); - ~ImportTableWidget(); - - void setRawData(const std::vector<std::vector<std::string>>& table_data); - - std::vector<ColumnInfo> columnInfo() const; - -private: - ImportTableModel* m_tableModel{nullptr}; - QTableView* m_tableView{nullptr}; - std::unique_ptr<ModelView::ViewModelDelegate> m_delegate; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_DATALOADER_IMPORTTABLEWIDGET_H diff --git a/gui2/dataloader/importtextview.cpp b/gui2/dataloader/importtextview.cpp deleted file mode 100644 index ce43335592e105a8c45d5506c5771cbfcf0a289a..0000000000000000000000000000000000000000 --- a/gui2/dataloader/importtextview.cpp +++ /dev/null @@ -1,131 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/dataloader/importtextview.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/dataloader/importtextview.h" -#include "mvvm/widgets/widgetutils.h" - -//! Based on Qt example "codeeditor" -//! Copyright (C) 2016 The Qt Company Ltd. - -#include <QPainter> -#include <QTextBlock> - -namespace gui2 { - -namespace { -const int line_number_gap = 4; -} - -ImportTextView::ImportTextView(QWidget* parent) : QPlainTextEdit(parent) -{ - lineNumberArea = new LineNumberArea(this); - - connect(this, &ImportTextView::blockCountChanged, this, - &ImportTextView::updateLineNumberAreaWidth); - connect(this, &ImportTextView::updateRequest, this, &ImportTextView::updateLineNumberArea); - connect(this, &ImportTextView::cursorPositionChanged, this, - &ImportTextView::highlightCurrentLine); - - updateLineNumberAreaWidth(0); - // highlightCurrentLine(); - - setReadOnly(true); - setWordWrapMode(QTextOption::NoWrap); - - setFont(QFont("Monospace", ModelView::Utils::SystemPointSize() * 0.8, QFont::Light)); -} - -int ImportTextView::lineNumberAreaWidth() -{ - int digits = 1; - int max = qMax(1, blockCount()); - while (max >= 10) { - max /= 10; - ++digits; - } - - int space = line_number_gap * 2 + fontMetrics().horizontalAdvance(QLatin1Char('9')) * digits; - - return space; -} - -void ImportTextView::updateLineNumberAreaWidth(int /* newBlockCount */) -{ - setViewportMargins(lineNumberAreaWidth(), 0, 0, 0); -} - -void ImportTextView::updateLineNumberArea(const QRect& rect, int dy) -{ - if (dy) - lineNumberArea->scroll(0, dy); - else - lineNumberArea->update(0, rect.y(), lineNumberArea->width(), rect.height()); - - if (rect.contains(viewport()->rect())) - updateLineNumberAreaWidth(0); -} - -void ImportTextView::resizeEvent(QResizeEvent* e) -{ - QPlainTextEdit::resizeEvent(e); - - QRect cr = contentsRect(); - lineNumberArea->setGeometry(QRect(cr.left(), cr.top(), lineNumberAreaWidth(), cr.height())); -} - -void ImportTextView::highlightCurrentLine() -{ - QList<QTextEdit::ExtraSelection> extraSelections; - - if (!isReadOnly()) { - QTextEdit::ExtraSelection selection; - - QColor lineColor = QColor(Qt::yellow).lighter(160); - - selection.format.setBackground(lineColor); - selection.format.setProperty(QTextFormat::FullWidthSelection, true); - selection.cursor = textCursor(); - selection.cursor.clearSelection(); - extraSelections.append(selection); - } - - setExtraSelections(extraSelections); -} - -void ImportTextView::lineNumberAreaPaintEvent(QPaintEvent* event) -{ - QPainter painter(lineNumberArea); - painter.fillRect(event->rect(), Qt::lightGray); - - QTextBlock block = firstVisibleBlock(); - int blockNumber = block.blockNumber(); - int top = qRound(blockBoundingGeometry(block).translated(contentOffset()).top()); - int bottom = top + qRound(blockBoundingRect(block).height()); - - while (block.isValid() && top <= event->rect().bottom()) { - if (block.isVisible() && bottom >= event->rect().top()) { - QString number = QString::number(blockNumber + 1); - painter.setPen(Qt::black); - painter.drawText(0, top, lineNumberArea->width() - line_number_gap, - fontMetrics().height(), Qt::AlignRight, number); - } - - block = block.next(); - top = bottom; - bottom = top + qRound(blockBoundingRect(block).height()); - ++blockNumber; - } -} - -} // namespace gui2 diff --git a/gui2/dataloader/importtextview.h b/gui2/dataloader/importtextview.h deleted file mode 100644 index 6a75eb91f834d19f12e1d799648b5ceb8388c7c3..0000000000000000000000000000000000000000 --- a/gui2/dataloader/importtextview.h +++ /dev/null @@ -1,74 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/dataloader/importtextview.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_DATALOADER_IMPORTTEXTVIEW_H -#define BORNAGAIN_GUI2_DATALOADER_IMPORTTEXTVIEW_H - -#include "darefl_export.h" - -//! Based on Qt example "codeeditor" -//! Copyright (C) 2016 The Qt Company Ltd. - -#include <QPlainTextEdit> - -class QPaintEvent; -class QResizeEvent; -class QSize; -class QWidget; - -namespace gui2 { - -class LineNumberArea; - -//! Text view to show imported data. - -class DAREFLCORE_EXPORT ImportTextView : public QPlainTextEdit { - Q_OBJECT - -public: - ImportTextView(QWidget* parent = nullptr); - - void lineNumberAreaPaintEvent(QPaintEvent* event); - int lineNumberAreaWidth(); - -protected: - void resizeEvent(QResizeEvent* event) override; - -private slots: - void updateLineNumberAreaWidth(int newBlockCount); - void highlightCurrentLine(); - void updateLineNumberArea(const QRect& rect, int dy); - -private: - QWidget* lineNumberArea; -}; - -//! Area with line numbers. - -class DAREFLCORE_EXPORT LineNumberArea : public QWidget { -public: - LineNumberArea(ImportTextView* editor) : QWidget(editor), codeEditor(editor) {} - - QSize sizeHint() const override { return QSize(codeEditor->lineNumberAreaWidth(), 0); } - -protected: - void paintEvent(QPaintEvent* event) override { codeEditor->lineNumberAreaPaintEvent(event); } - -private: - ImportTextView* codeEditor; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_DATALOADER_IMPORTTEXTVIEW_H diff --git a/gui2/dataloader/loaderpreviewpanel.cpp b/gui2/dataloader/loaderpreviewpanel.cpp deleted file mode 100644 index de72210de92cff11c711b4576848ddacefb4b72f..0000000000000000000000000000000000000000 --- a/gui2/dataloader/loaderpreviewpanel.cpp +++ /dev/null @@ -1,74 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/dataloader/loaderpreviewpanel.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/dataloader/loaderpreviewpanel.h" -#include "gui2/dataloader/dataloader_utils.h" -#include "gui2/dataloader/importtablewidget.h" -#include "gui2/dataloader/importtextview.h" -#include "gui2/dataloader/parserinterface.h" -#include <QColor> -#include <QTabWidget> -#include <QVBoxLayout> - -namespace gui2 { - -namespace { -const std::string gray{"#aab7b8"}; -const std::string blue{"#1b4f72"}; - -} // namespace - -LoaderPreviewPanel::LoaderPreviewPanel(QWidget* parent) - : QWidget(parent) - , m_textView(new ImportTextView) - , m_tableWidget(new ImportTableWidget) - , m_tabWidget(new QTabWidget) -{ - auto layout = new QVBoxLayout(this); - layout->setContentsMargins(0, 0, 0, 0); - - m_tabWidget->addTab(m_textView, "Text view"); - m_tabWidget->addTab(m_tableWidget, "Table view"); - - layout->addWidget(m_tabWidget); -} - -//! Sets raw text to the TextView. - -void LoaderPreviewPanel::showData(const ParserInterface* parser) -{ - m_textView->clear(); - for (size_t index = 0; index < parser->totalLineCount(); ++index) { - auto line_data = parser->getLine(index); - auto parts = parser->parseResults(index); - auto string_to_show = Utils::AddHtmlColorTagToParts(line_data, parts, blue, gray); - m_textView->appendHtml(QString::fromStdString(string_to_show)); - } - m_textView->moveCursor(QTextCursor::Start); - - m_tableWidget->setRawData(parser->parsedData()); -} - -std::vector<ColumnInfo> LoaderPreviewPanel::columnInfo() const -{ - return m_tableWidget->columnInfo(); -} - -void LoaderPreviewPanel::clearPanel() -{ - m_textView->clear(); - m_tableWidget->setRawData({}); -} - -} // namespace gui2 diff --git a/gui2/dataloader/loaderpreviewpanel.h b/gui2/dataloader/loaderpreviewpanel.h deleted file mode 100644 index c367f8a9ced717126586b3e3de0e6456d6fc83a2..0000000000000000000000000000000000000000 --- a/gui2/dataloader/loaderpreviewpanel.h +++ /dev/null @@ -1,54 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/dataloader/loaderpreviewpanel.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_DATALOADER_LOADERPREVIEWPANEL_H -#define BORNAGAIN_GUI2_DATALOADER_LOADERPREVIEWPANEL_H - -#include "darefl_export.h" -#include <QWidget> - -class QTabWidget; - -namespace gui2 { - -class ImportTextView; -class ImportTableWidget; - -class ParserInterface; -struct ColumnInfo; - -//! Panel with settings for DataLoaderDialog. -//! Located on its right side, contains text and table views. - -class DAREFLCORE_EXPORT LoaderPreviewPanel : public QWidget { - Q_OBJECT - -public: - LoaderPreviewPanel(QWidget* parent = nullptr); - - void showData(const ParserInterface* parser); - - std::vector<ColumnInfo> columnInfo() const; - - void clearPanel(); - -private: - ImportTextView* m_textView{nullptr}; - ImportTableWidget* m_tableWidget{nullptr}; - QTabWidget* m_tabWidget{nullptr}; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_DATALOADER_LOADERPREVIEWPANEL_H diff --git a/gui2/dataloader/loaderselectorpanel.cpp b/gui2/dataloader/loaderselectorpanel.cpp deleted file mode 100644 index c397d96a8ee3995f639c96bbec4e7fe24e9c5da1..0000000000000000000000000000000000000000 --- a/gui2/dataloader/loaderselectorpanel.cpp +++ /dev/null @@ -1,98 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/dataloader/loaderselectorpanel.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/dataloader/loaderselectorpanel.h" -#include "gui2/dataloader/defaultparser.h" -#include "gui2/dataloader/importfilewidget.h" -#include "gui2/dataloader/parserpropertywidget.h" -#include <QSplitter> -#include <QVBoxLayout> - -namespace gui2 { - -LoaderSelectorPanel::LoaderSelectorPanel(QWidget* parent) - : QWidget(parent) - , m_fileSelectorWidget(new ImportFileWidget) - , m_propertyWidget(new ParserPropertyWidget) - , m_splitter(new QSplitter) -{ - auto layout = new QVBoxLayout(this); - layout->setContentsMargins(0, 0, 0, 0); - - m_splitter->setOrientation(Qt::Vertical); - m_splitter->setChildrenCollapsible(false); - - m_splitter->addWidget(m_fileSelectorWidget); - m_splitter->addWidget(m_propertyWidget); - - layout->addWidget(m_splitter); - - init_connections(); -} - -LoaderSelectorPanel::~LoaderSelectorPanel() = default; - -std::unique_ptr<ParserInterface> LoaderSelectorPanel::createParser() const -{ - return m_propertyWidget->createParser(); -} - -void LoaderSelectorPanel::setTargetCanvas(const QStringList& canvas_names, int current_index) -{ - m_propertyWidget->setTargetCanvas(canvas_names, current_index); -} - -int LoaderSelectorPanel::targetCanvasIndex() const -{ - return m_targetCanvasIndex; -} - -void LoaderSelectorPanel::onAddFilesRequest() -{ - m_fileSelectorWidget->onAddFilesRequest(); -} - -void LoaderSelectorPanel::onRemoveFileRequest() -{ - m_fileSelectorWidget->onRemoveFileRequest(); -} - -QStringList LoaderSelectorPanel::selectedFileNames() const -{ - return m_fileSelectorWidget->selectedFileNames(); -} - -QStringList LoaderSelectorPanel::fileNames() const -{ - return m_fileSelectorWidget->fileNames(); -} - -void LoaderSelectorPanel::init_connections() -{ - auto on_file_names_changed = [this]() { fileNamesChanged(m_fileSelectorWidget->fileNames()); }; - connect(m_fileSelectorWidget, &ImportFileWidget::fileNamesChanged, on_file_names_changed); - - auto on_selection_changed = [this]() { - fileSelectionChanged(m_fileSelectorWidget->selectedFileNames()); - }; - connect(m_fileSelectorWidget, &ImportFileWidget::fileSelectionChanged, on_selection_changed); - - connect(m_propertyWidget, &ParserPropertyWidget::parserPropertyChanged, this, - &LoaderSelectorPanel::parserPropertyChanged); - - auto on_target_changed = [this](auto index) { m_targetCanvasIndex = index; }; - connect(m_propertyWidget, &ParserPropertyWidget::targetCanvasChanged, on_target_changed); -} - -} // namespace gui2 diff --git a/gui2/dataloader/loaderselectorpanel.h b/gui2/dataloader/loaderselectorpanel.h deleted file mode 100644 index ec73d41a16a37fbf00cdd2e29677ac74bbb86ca4..0000000000000000000000000000000000000000 --- a/gui2/dataloader/loaderselectorpanel.h +++ /dev/null @@ -1,68 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/dataloader/loaderselectorpanel.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_DATALOADER_LOADERSELECTORPANEL_H -#define BORNAGAIN_GUI2_DATALOADER_LOADERSELECTORPANEL_H - -#include "darefl_export.h" -#include <QWidget> -#include <memory> - -class QSplitter; - -namespace gui2 { - -class ParserInterface; -class ImportFileWidget; -class ParserPropertyWidget; - -//! Panel with settings for DataLoaderDialog. -//! Located on its left side, contains file selection dialog and parser property widget. - -class DAREFLCORE_EXPORT LoaderSelectorPanel : public QWidget { - Q_OBJECT - -public: - LoaderSelectorPanel(QWidget* parent = nullptr); - ~LoaderSelectorPanel(); - - std::unique_ptr<ParserInterface> createParser() const; - - void setTargetCanvas(const QStringList& canvas_names, int current_index); - - int targetCanvasIndex() const; - -public slots: - void onAddFilesRequest(); - void onRemoveFileRequest(); - QStringList selectedFileNames() const; - QStringList fileNames() const; - -signals: - void fileNamesChanged(const QStringList& file_names); - void fileSelectionChanged(const QStringList& file_names); - void parserPropertyChanged(); - -private: - void init_connections(); - - int m_targetCanvasIndex{-1}; - ImportFileWidget* m_fileSelectorWidget{nullptr}; - ParserPropertyWidget* m_propertyWidget{nullptr}; - QSplitter* m_splitter{nullptr}; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_DATALOADER_LOADERSELECTORPANEL_H diff --git a/gui2/dataloader/parserinterface.h b/gui2/dataloader/parserinterface.h deleted file mode 100644 index 8a0ea786d539ebcffc83ca60e37232c1cb104fb4..0000000000000000000000000000000000000000 --- a/gui2/dataloader/parserinterface.h +++ /dev/null @@ -1,49 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/dataloader/parserinterface.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_DATALOADER_PARSERINTERFACE_H -#define BORNAGAIN_GUI2_DATALOADER_PARSERINTERFACE_H - -#include "darefl_export.h" -#include <string> -#include <vector> - -namespace gui2 { - -//! Interface for all classes capable of parsing ASCII data into multicolumn presentation. - -class DAREFLCORE_EXPORT ParserInterface { // #import Here is where the data gets parsed -public: - virtual ~ParserInterface() = default; - - //! Parse data representing content of ASCII file. - virtual void process(const std::vector<std::string>& raw_data) = 0; - - //! Returns total number of lines in raw data. - virtual size_t totalLineCount() const = 0; - - //! Returns original line. - virtual std::string getLine(size_t index) const = 0; - - //! Returns parsed text for given line index. If line was skipped during parsing, returns empty - //! vector. - virtual std::vector<std::string> parseResults(size_t index) const = 0; - - //! Returns 2D vector representing parsed text. Skipped lines are not present. - virtual std::vector<std::vector<std::string>> parsedData() const = 0; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_DATALOADER_PARSERINTERFACE_H diff --git a/gui2/dataloader/parserpropertywidget.cpp b/gui2/dataloader/parserpropertywidget.cpp deleted file mode 100644 index 9caebe5871ca4cc402ba1ce4e47e8860b08a5e48..0000000000000000000000000000000000000000 --- a/gui2/dataloader/parserpropertywidget.cpp +++ /dev/null @@ -1,362 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/dataloader/parserpropertywidget.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/dataloader/parserpropertywidget.h" -#include "gui2/core/app_constants.h" -#include "gui2/dataloader/defaultparser.h" -#include "mvvm/widgets/widgetutils.h" -#include <QButtonGroup> -#include <QComboBox> -#include <QDebug> -#include <QGridLayout> -#include <QGroupBox> -#include <QLabel> -#include <QLineEdit> -#include <QRadioButton> -#include <QRegExpValidator> -#include <QSettings> -#include <QVBoxLayout> - -namespace { - -//! Creates widget with label and little space above. Intended for grid layouts. -QWidget* createSectionWidget(const QString& text) -{ - auto widget = new QWidget; - auto layout = new QVBoxLayout(widget); - layout->addSpacing(10); - auto label = new QLabel(text); - QFont font = label->font(); - font.setPointSize(ModelView::Utils::SystemPointSize() * 1.05); - label->setFont(font); - layout->addWidget(label); - return widget; -} - -const QString separatorgroupid_setting_name() -{ - const QString key = "separatorgroup_id"; - return gui2::GUI::Constants::ParserPropertyGroupKey + "/" + key; -} - -const QString customseparatortext_setting_name() -{ - const QString key = "customseparator_text"; - return gui2::GUI::Constants::ParserPropertyGroupKey + "/" + key; -} - -} // namespace - -namespace gui2 { - -ParserPropertyWidget::ParserPropertyWidget(QWidget* parent) : QWidget(parent) -{ - auto layout = new QVBoxLayout(this); - layout->addLayout(createGridLayout()); - layout->addStretch(1); - - readSettings(); -} - -ParserPropertyWidget::~ParserPropertyWidget() -{ - writeSettings(); -} - -//! Creates parser from parser properties. - -std::unique_ptr<ParserInterface> ParserPropertyWidget::createParser() const -{ - ParserOptions options = m_options; - - // sanity check for empty separator - options.m_separator = options.m_separator.empty() ? std::string(" ") : options.m_separator; - return std::make_unique<DefaultParser>(options); -} - -//! Sets list of canvas names as possible import targets. - -void ParserPropertyWidget::setTargetCanvas(const QStringList& canvas_names, int current_index) -{ - m_targetCanvasCombo->insertItems(0, canvas_names); - m_targetCanvasCombo->setCurrentIndex(current_index); -} - -void ParserPropertyWidget::onParserPropertyChange() -{ - qDebug() << "option" - << "header:" << QString::fromStdString(m_options.m_header_prefix) - << "separator:" << QString::fromStdString(m_options.m_separator) << "pattern" - << QString::fromStdString(m_options.m_skip_index_pattern); - emit parserPropertyChanged(); -} - -//! Reads widget settings. - -void ParserPropertyWidget::readSettings() -{ - QSettings settings; - - if (settings.contains(separatorgroupid_setting_name())) { - int button_id = settings.value(separatorgroupid_setting_name()).toInt(); - if (auto button = m_separatorButtonGroup->button(button_id); button) { - button->click(); - } - } - - if (settings.contains(customseparatortext_setting_name())) - m_customSeparatorLineEdit->setText( - settings.value(customseparatortext_setting_name()).toString()); -} - -//! Writes widget settings. - -void ParserPropertyWidget::writeSettings() -{ - QSettings settings; - - settings.setValue(separatorgroupid_setting_name(), m_separatorButtonGroup->checkedId()); - settings.setValue(customseparatortext_setting_name(), m_customSeparatorLineEdit->text()); -} - -QGridLayout* ParserPropertyWidget::createGridLayout() -{ - auto grid_layout = new QGridLayout; - - addSectionLabel("Separator", grid_layout); - m_separatorButtonGroup = new QButtonGroup(this); - addStandardSeparatorRow(grid_layout, m_separatorButtonGroup); - addCustomSeparatorRow(grid_layout, m_separatorButtonGroup); - - addSectionLabel("Ignore lines", grid_layout); - addIgnoreStringPatternRow(grid_layout); - addIgnoreNumbersPatternRow(grid_layout); - - addSectionLabel("Import target", grid_layout); - addImportToBlock(grid_layout); - - // make first colum with invisible label fixed - for (int col = 0; col < grid_layout->columnCount(); ++col) - grid_layout->setColumnStretch(col, 10); - grid_layout->setColumnStretch(0, 0); - - return grid_layout; -} - -void ParserPropertyWidget::addSectionLabel(const QString& text, QGridLayout* layout) -{ - int row = layout->rowCount(); - layout->addWidget(createSectionWidget(text), row, 0, 1, 3, Qt::AlignLeft); -} - -//! Adds row to the grid: elements with standard separator settings. - -void ParserPropertyWidget::addStandardSeparatorRow(QGridLayout* layout, QButtonGroup* group) -{ - // automatic separator - int row = layout->rowCount(); - auto automaticRadio = new QRadioButton; - automaticRadio->setChecked(true); - automaticRadio->setText("Automatic"); - automaticRadio->setToolTip("Try to guess column separator"); - connect(automaticRadio, &QRadioButton::clicked, [this](auto) { - m_options.m_separator.clear(); - onParserPropertyChange(); - }); - - // space separator - auto spaceRadio = new QRadioButton; - spaceRadio->setText("Space"); - spaceRadio->setToolTip("Use empty space as column separator"); - connect(spaceRadio, &QRadioButton::clicked, [this](auto) { - m_options.m_separator = " "; - onParserPropertyChange(); - }); - - // comma separator - auto commaRadio = new QRadioButton; - commaRadio->setText("Comma"); - commaRadio->setToolTip("Use comma as column separator"); - connect(commaRadio, &QRadioButton::clicked, [this](auto) { - m_options.m_separator = ","; - onParserPropertyChange(); - }); - - // adding all to layout - layout->addWidget(new QLabel(" "), row, 0, Qt::AlignLeft); - layout->addWidget(automaticRadio, row, 1, Qt::AlignLeft); - layout->addWidget(spaceRadio, row, 2, Qt::AlignLeft); - layout->addWidget(commaRadio, row, 3, Qt::AlignLeft); - group->addButton(automaticRadio, AUTOMATIC); - group->addButton(spaceRadio, SPACE); - group->addButton(commaRadio, COMMA); -} - -//! Adds row to the grid: elements with custom separator settings. - -void ParserPropertyWidget::addCustomSeparatorRow(QGridLayout* layout, QButtonGroup* group) -{ - int row = layout->rowCount(); - m_customSeparatorLineEdit = new QLineEdit; - auto customRadio = new QRadioButton; - - // custom separator radio - customRadio->setText("Custom"); - customRadio->setToolTip("Use given symbols as column separator"); - auto on_custom_separator = [this](auto) { - m_options.m_separator = m_customSeparatorLineEdit->text().toStdString(); - onParserPropertyChange(); - }; - connect(customRadio, &QRadioButton::clicked, on_custom_separator); - - // custom separator text - m_customSeparatorLineEdit->setMaximumWidth(ModelView::Utils::WidthOfLetterM() * 4); - m_customSeparatorLineEdit->setToolTip("Use given symbols as column separator"); - auto on_custom_lineedit = [this, customRadio]() { - if (customRadio->isChecked()) - m_options.m_separator = m_customSeparatorLineEdit->text().toStdString(); - onParserPropertyChange(); - }; - connect(m_customSeparatorLineEdit, &QLineEdit::editingFinished, on_custom_lineedit); - - // adding to the layout - layout->addWidget(new QLabel(" "), row, 0, Qt::AlignLeft); - layout->addWidget(customRadio, row, 1, Qt::AlignLeft); - layout->addWidget(m_customSeparatorLineEdit, row, 2, Qt::AlignLeft); - group->addButton(customRadio, CUSTOM); -} - -//! Adds row to the grid: elements with pattern to ignore lines. - -void ParserPropertyWidget::addIgnoreStringPatternRow(QGridLayout* layout) -{ - auto startingWithRadio = new QRadioButton; - auto startingFromLineEdit = new QLineEdit; - - // radio settings - int row = layout->rowCount(); - startingWithRadio->setText("Starting with"); - startingWithRadio->setAutoExclusive(false); - startingWithRadio->setChecked(true); - startingWithRadio->setToolTip("Ignore lines starting with a given character(s)"); - auto on_startingfrom_radio = [this, startingFromLineEdit](auto checked) { - m_options.m_header_prefix = checked ? startingFromLineEdit->text().toStdString() : ""; - onParserPropertyChange(); - }; - connect(startingWithRadio, &QRadioButton::clicked, on_startingfrom_radio); - - // line edit settings - startingFromLineEdit->setText("#"); - startingFromLineEdit->setToolTip("Ignore lines starting with a given character(s)"); - auto on_startingfrom_lineedit = [this, startingWithRadio, startingFromLineEdit]() { - if (startingWithRadio->isChecked()) - m_options.m_header_prefix = startingFromLineEdit->text().toStdString(); - onParserPropertyChange(); - }; - connect(startingFromLineEdit, &QLineEdit::editingFinished, on_startingfrom_lineedit); - - // adding to layout - layout->addWidget(new QLabel(" "), row, 0, Qt::AlignLeft); - layout->addWidget(startingWithRadio, row, 1, Qt::AlignLeft); - layout->addWidget(startingFromLineEdit, row, 2, Qt::AlignLeft); -} - -//! Adds row to the grid: elements with pattern to ignore line numbers. - -void ParserPropertyWidget::addIgnoreNumbersPatternRow(QGridLayout* layout) -{ - auto lineNumbersRadio = new QRadioButton; - auto lineNumbersLineEdit = new QLineEdit; - - // radio settings - int row = layout->rowCount(); - lineNumbersRadio->setAutoExclusive(false); - lineNumbersRadio->setText("Line numbers"); - lineNumbersRadio->setToolTip("Ignore lines with line numbers matching the pattern"); - auto on_linenumbers_radio = [this, lineNumbersLineEdit](auto checked) { - m_options.m_skip_index_pattern = checked ? lineNumbersLineEdit->text().toStdString() : ""; - onParserPropertyChange(); - }; - connect(lineNumbersRadio, &QRadioButton::clicked, on_linenumbers_radio); - - // line edit settings - lineNumbersLineEdit->setPlaceholderText("Example: 1-5,42"); - lineNumbersLineEdit->setToolTip("Ignore lines with line numbers matching the pattern"); - auto on_linenumbers_lineedit = [this, lineNumbersRadio, lineNumbersLineEdit]() { - if (lineNumbersRadio->isChecked()) - m_options.m_skip_index_pattern = lineNumbersLineEdit->text().toStdString(); - onParserPropertyChange(); - }; - connect(lineNumbersLineEdit, &QLineEdit::editingFinished, on_linenumbers_lineedit); - - // adding to the layout - layout->addWidget(new QLabel(" "), row, 0, Qt::AlignLeft); - layout->addWidget(lineNumbersRadio, row, 1, Qt::AlignLeft); - layout->addWidget(lineNumbersLineEdit, row, 2, Qt::AlignLeft); - - // validator - auto validator = new QRegExpValidator(QRegExp("^[0-9,-]*$"), this); - lineNumbersLineEdit->setValidator(validator); -} - -//! Adds row to the grid: elements related to the import target. - -void ParserPropertyWidget::addImportToBlock(QGridLayout* layout) -{ - auto newCanvasRadio = new QRadioButton; - auto existingCanvasRadio = new QRadioButton; - m_targetCanvasCombo = new QComboBox; - - // radio settings - newCanvasRadio->setText("New canvas"); - newCanvasRadio->setChecked(true); - newCanvasRadio->setToolTip("Data will be imported into the new canvas"); - auto on_newcanvas_radio = [this](auto checked) { - if (checked) - targetCanvasChanged(-1); - }; - connect(newCanvasRadio, &QRadioButton::clicked, on_newcanvas_radio); - - existingCanvasRadio->setText("Existing canvas"); - existingCanvasRadio->setToolTip("Data will be imported into existing canvas"); - auto on_existingcanvas_radio = [this](auto checked) { - if (checked) - targetCanvasChanged(m_targetCanvasCombo->currentIndex()); - }; - connect(existingCanvasRadio, &QRadioButton::clicked, on_existingcanvas_radio); - - // combo settings - m_targetCanvasCombo->setToolTip("Data will be imported into existing canvas"); - auto on_canvas_combo = [this, existingCanvasRadio](int index) { - if (existingCanvasRadio->isChecked()) - targetCanvasChanged(index); - }; - connect(m_targetCanvasCombo, - static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), - on_canvas_combo); - - // adding to the layout - int row = layout->rowCount(); - layout->addWidget(new QLabel(" "), row, 0, Qt::AlignLeft); - layout->addWidget(newCanvasRadio, row, 1, Qt::AlignLeft); - row = layout->rowCount(); - layout->addWidget(new QLabel(" "), row, 0, Qt::AlignLeft); - layout->addWidget(existingCanvasRadio, row, 1, Qt::AlignLeft); - layout->addWidget(m_targetCanvasCombo, row, 2, Qt::AlignLeft); - auto buttonGroup = new QButtonGroup(this); - buttonGroup->addButton(newCanvasRadio); - buttonGroup->addButton(existingCanvasRadio); -} - -} // namespace gui2 diff --git a/gui2/dataloader/parserpropertywidget.h b/gui2/dataloader/parserpropertywidget.h deleted file mode 100644 index c9d8c533d82ccca37dece769dd5efc5efe9b8683..0000000000000000000000000000000000000000 --- a/gui2/dataloader/parserpropertywidget.h +++ /dev/null @@ -1,75 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/dataloader/parserpropertywidget.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_DATALOADER_PARSERPROPERTYWIDGET_H -#define BORNAGAIN_GUI2_DATALOADER_PARSERPROPERTYWIDGET_H - -#include "darefl_export.h" -#include "gui2/dataloader/dataloader_types.h" -#include <QWidget> -#include <memory> - -class QGridLayout; -class QButtonGroup; -class QComboBox; -class QLineEdit; - -namespace gui2 { - -class ParserInterface; - -//! Panel to setup ASCII parser. Intended for concrete class DefaultParser. -//! Contains selection of separator symbols, patterns to ignore lines, and import target settings. - -class DAREFLCORE_EXPORT ParserPropertyWidget : public QWidget { - Q_OBJECT - -public: - enum SeparatorButtonId { AUTOMATIC, SPACE, COMMA, CUSTOM }; - - ParserPropertyWidget(QWidget* parent = nullptr); - ~ParserPropertyWidget(); - - std::unique_ptr<ParserInterface> createParser() const; - - void setTargetCanvas(const QStringList& canvas_names, int current_index); - -signals: - void parserPropertyChanged(); - int targetCanvasChanged(int canvas_index); - -private slots: - void onParserPropertyChange(); - -private: - void readSettings(); - void writeSettings(); - QGridLayout* createGridLayout(); - - void addSectionLabel(const QString& text, QGridLayout* layout); - void addStandardSeparatorRow(QGridLayout* layout, QButtonGroup* group); - void addCustomSeparatorRow(QGridLayout* layout, QButtonGroup* group); - void addIgnoreStringPatternRow(QGridLayout* layout); - void addIgnoreNumbersPatternRow(QGridLayout* layout); - void addImportToBlock(QGridLayout* layout); - - ParserOptions m_options; - QButtonGroup* m_separatorButtonGroup{nullptr}; - QComboBox* m_targetCanvasCombo{nullptr}; - QLineEdit* m_customSeparatorLineEdit{nullptr}; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_DATALOADER_PARSERPROPERTYWIDGET_H diff --git a/gui2/importdataview/CMakeLists.txt b/gui2/importdataview/CMakeLists.txt deleted file mode 100644 index d5cf77b5702d7eb93128923b1194860261ded85b..0000000000000000000000000000000000000000 --- a/gui2/importdataview/CMakeLists.txt +++ /dev/null @@ -1,19 +0,0 @@ -target_sources(${library_name} PRIVATE - dataselectionmodel.cpp - dataselectionmodel.h - dataselectorwidget.cpp - dataselectorwidget.h - dataviewmodel.cpp - dataviewmodel.h - graphcanvaswidget.cpp - graphcanvaswidget.h - graphimportdata.h - importdataeditor.cpp - importdataeditor.h - importdataeditoractions.cpp - importdataeditoractions.h - importdataeditortoolbal.cpp - importdataeditortoolbal.h - importdataview.cpp - importdataview.h -) diff --git a/gui2/importdataview/dataselectionmodel.cpp b/gui2/importdataview/dataselectionmodel.cpp deleted file mode 100644 index 2609b405d720ddfa34fb71533198403202502893..0000000000000000000000000000000000000000 --- a/gui2/importdataview/dataselectionmodel.cpp +++ /dev/null @@ -1,104 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/importdataview/dataselectionmodel.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/importdataview/dataselectionmodel.h" -#include "gui2/model/experimentaldataitems.h" -#include "gui2/model/item_constants.h" -#include "mvvm/model/itemutils.h" -#include "mvvm/model/mvvm_types.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/standarditems/graphitem.h" -#include "mvvm/viewmodel/viewmodel.h" -#include "mvvm/viewmodel/viewmodelutils.h" - -namespace gui2 { - -//! The constructor -DataSelectionModel::DataSelectionModel(ModelView::ViewModel* view_model, QObject* parent) - : QItemSelectionModel(view_model, parent) -{ - // FIXME cover with unit tests after implementing ViewItemSelectionModel - connect(view_model, &ModelView::ViewModel::modelAboutToBeReset, [this]() { clearSelection(); }); -} - -//! Set the selection on a single item -void DataSelectionModel::selectItem(ModelView::SessionItem* item) -{ - selectItems({item}); -} - -//! Set the selection on a list of items -void DataSelectionModel::selectItems(std::vector<ModelView::SessionItem*> items) -{ - QModelIndexList indexes; - for (auto item : items) - indexes << viewModel()->indexOfSessionItem(item); - - if (indexes.empty()) - return; - - clearSelection(); - - QItemSelection selection(indexes.front(), indexes.back()); - auto flags = QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows; - select(selection, flags); -} - -//! Return the selected items -std::vector<ModelView::SessionItem*> DataSelectionModel::selectedItems() const -{ - auto items = ModelView::Utils::ItemsFromIndex(selectedIndexes()); - return ModelView::Utils::UniqueItems(items); -} - -const ModelView::ViewModel* DataSelectionModel::viewModel() const -{ - return static_cast<const ModelView::ViewModel*>(model()); -} - -//! Returns active canvas. The canvas is active when it is either selected, or one of its own -//! graph is selected. If more than one canvas is selected, will return the first one. - -CanvasItem* DataSelectionModel::activeCanvas() const -{ - for (auto item : selectedItems()) { - if (item->modelType() == GUI::Constants::CanvasItemType) - return static_cast<CanvasItem*>(item); - else if (item->modelType() == ModelView::GUI::Constants::GraphItemType) - return static_cast<CanvasItem*>(item->parent()); - } - return nullptr; -} - -//! Returns currently selected graph. If more than one graph is selected, will return first one. - -ModelView::GraphItem* DataSelectionModel::selectedGraph() const -{ - auto graphs = selectedGraphs(); - return graphs.empty() ? nullptr : graphs.at(0); -} - -//! Returns vector of currently slected canvas. - -std::vector<CanvasItem*> DataSelectionModel::selectedCanvas() const -{ - return ModelView::Utils::CastedItems<CanvasItem>(selectedItems()); -} - -std::vector<ModelView::GraphItem*> DataSelectionModel::selectedGraphs() const -{ - return ModelView::Utils::CastedItems<ModelView::GraphItem>(selectedItems()); -} - -} // namespace gui2 diff --git a/gui2/importdataview/dataselectionmodel.h b/gui2/importdataview/dataselectionmodel.h deleted file mode 100644 index cd64bc03e6a7e9e0a449641323321f5089d23102..0000000000000000000000000000000000000000 --- a/gui2/importdataview/dataselectionmodel.h +++ /dev/null @@ -1,58 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/importdataview/dataselectionmodel.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_IMPORTDATAVIEW_DATASELECTIONMODEL_H -#define BORNAGAIN_GUI2_IMPORTDATAVIEW_DATASELECTIONMODEL_H - -#include "darefl_export.h" -#include <QItemSelectionModel> -#include <vector> - -namespace ModelView { -class ViewModel; -class SessionItem; -class GraphItem; -} // namespace ModelView - -namespace gui2 { - -class CanvasItem; - -//! Custom selection model for data view model (AbstractViewModel). - -class DAREFLCORE_EXPORT DataSelectionModel : public QItemSelectionModel { - Q_OBJECT - -public: - DataSelectionModel(ModelView::ViewModel* view_model, QObject* parent = nullptr); - ~DataSelectionModel() = default; - - void selectItem(ModelView::SessionItem* item); - void selectItems(std::vector<ModelView::SessionItem*> items); - - std::vector<ModelView::SessionItem*> selectedItems() const; - - const ModelView::ViewModel* viewModel() const; - - CanvasItem* activeCanvas() const; - ModelView::GraphItem* selectedGraph() const; - - std::vector<CanvasItem*> selectedCanvas() const; - - std::vector<ModelView::GraphItem*> selectedGraphs() const; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_IMPORTDATAVIEW_DATASELECTIONMODEL_H diff --git a/gui2/importdataview/dataselectorwidget.cpp b/gui2/importdataview/dataselectorwidget.cpp deleted file mode 100644 index 72bb7e960c3d5432b7c7f58eba23ce8c38b20415..0000000000000000000000000000000000000000 --- a/gui2/importdataview/dataselectorwidget.cpp +++ /dev/null @@ -1,73 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/importdataview/dataselectorwidget.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/importdataview/dataselectorwidget.h" -#include "gui2/importdataview/dataselectionmodel.h" -#include "gui2/importdataview/dataviewmodel.h" -#include "gui2/model/experimentaldataitems.h" -#include "mvvm/standarditems/graphitem.h" -#include "mvvm/widgets/collapsiblelistwidget.h" -#include "mvvm/widgets/standardtreeviews.h" -#include "mvvm/widgets/widgetutils.h" -#include <QHBoxLayout> -#include <QLabel> -#include <QSplitter> -#include <QTreeView> -#include <QVBoxLayout> - -namespace gui2 { - -DataSelectorWidget::DataSelectorWidget(DataViewModel* view_model, QWidget* parent) - : QWidget(parent) - , m_viewModel(view_model) - , m_selectionModel(new DataSelectionModel(m_viewModel, this)) - , m_selectorTree(new QTreeView) - , m_canvasPropertyEditor(new ModelView::PropertyTreeView) - , m_graphPropertyEditor(new ModelView::PropertyTreeView) - , m_collapsibleWidget(new ModelView::CollapsibleListWidget) -{ - auto layout = new QVBoxLayout(this); - - m_collapsibleWidget->addWidget(m_selectorTree, "Canvas list"); - m_collapsibleWidget->addWidget(m_canvasPropertyEditor, "Canvas properties", - /*set_collapsed*/ true); - m_collapsibleWidget->addWidget(m_graphPropertyEditor, "Graph properties", - /*set_collapsed*/ true); - - layout->addWidget(m_collapsibleWidget); - - m_selectorTree->setModel(m_viewModel); - m_selectorTree->setSelectionModel(m_selectionModel); - m_selectorTree->setSelectionMode(QAbstractItemView::ExtendedSelection); - m_selectorTree->setDragDropMode(QAbstractItemView::InternalMove); - m_selectorTree->setDragEnabled(true); - - connect(selectionModel(), &DataSelectionModel::selectionChanged, this, - &DataSelectorWidget::onSelectionChanged); -} - -DataSelectionModel* DataSelectorWidget::selectionModel() const -{ - return m_selectionModel; -} - -void DataSelectorWidget::onSelectionChanged() -{ - m_canvasPropertyEditor->setItem(m_selectionModel->activeCanvas()); - m_graphPropertyEditor->setItem(m_selectionModel->selectedGraph()); - - selectionChanged(); // emmit further -} - -} // namespace gui2 diff --git a/gui2/importdataview/dataselectorwidget.h b/gui2/importdataview/dataselectorwidget.h deleted file mode 100644 index e9ac3eea636d8cb99ec4c4b66fe333184ef76f6f..0000000000000000000000000000000000000000 --- a/gui2/importdataview/dataselectorwidget.h +++ /dev/null @@ -1,61 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/importdataview/dataselectorwidget.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_IMPORTDATAVIEW_DATASELECTORWIDGET_H -#define BORNAGAIN_GUI2_IMPORTDATAVIEW_DATASELECTORWIDGET_H - -#include "darefl_export.h" -#include <QWidget> - -class QTreeView; - -namespace ModelView { -class PropertyTreeView; -class CollapsibleListWidget; -} // namespace ModelView - -namespace gui2 { - -class DataSelectionModel; -class DataViewModel; - -//! Widget to select graphs and look at their properties. -//! Occupies the left part of ImportDataEditor. - -class DAREFLCORE_EXPORT DataSelectorWidget : public QWidget { - Q_OBJECT - -public: - DataSelectorWidget(DataViewModel* view_model, QWidget* parent = nullptr); - - DataSelectionModel* selectionModel() const; - -signals: - void selectionChanged(); - -private slots: - void onSelectionChanged(); - -private: - DataViewModel* m_viewModel{nullptr}; - DataSelectionModel* m_selectionModel{nullptr}; - QTreeView* m_selectorTree{nullptr}; - ModelView::PropertyTreeView* m_canvasPropertyEditor{nullptr}; - ModelView::PropertyTreeView* m_graphPropertyEditor{nullptr}; - ModelView::CollapsibleListWidget* m_collapsibleWidget{nullptr}; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_IMPORTDATAVIEW_DATASELECTORWIDGET_H diff --git a/gui2/importdataview/dataviewmodel.cpp b/gui2/importdataview/dataviewmodel.cpp deleted file mode 100644 index 89a754cbf27e6a83a2e08f65fe4078efaa013407..0000000000000000000000000000000000000000 --- a/gui2/importdataview/dataviewmodel.cpp +++ /dev/null @@ -1,121 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/importdataview/dataviewmodel.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/importdataview/dataviewmodel.h" -#include "gui2/model/experimentaldatamodel.h" -#include "gui2/model/item_constants.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/viewmodel/viewmodelutils.h" -#include "mvvm/widgets/widgetutils.h" -#include <QByteArray> -#include <QDataStream> -#include <QMimeData> - -using namespace ModelView; - -namespace { -const std::string ExperimentalDataMimeType = "darefl/ExperimentalDataMime"; - -} // namespace - -namespace gui2 { - -DataViewModel::DataViewModel(ExperimentalDataModel* model, QObject* parent) - : ModelView::TopItemsViewModel(model, parent) -{ -} - -//! Return the Qt flags for given index. We allow GraphItem drag, they can be dropped on CanvasItem. - -Qt::ItemFlags DataViewModel::flags(const QModelIndex& index) const -{ - Qt::ItemFlags result = ViewModel::flags(index); - - if (auto item = sessionItemFromIndex(index); item) { - if (item->modelType() == ModelView::GUI::Constants::GraphItemType) - result |= Qt::ItemIsDragEnabled; - else if (item->modelType() == GUI::Constants::CanvasItemType) - result |= Qt::ItemIsDropEnabled; - } - - return result; -} - -//! Generate the mime data for all selected items. - -QMimeData* DataViewModel::mimeData(const QModelIndexList& index_list) const -{ - auto result = new QMimeData; - - // Get the list of the identifiers - QStringList identifiers; - for (auto item : Utils::UniqueItemsFromIndex(index_list)) - identifiers.append(QString::fromStdString(item->identifier())); - - result->setData(QString::fromStdString(ExperimentalDataMimeType), - Utils::serialize(identifiers)); - - return result; -} - -//! Supported drag actions. - -Qt::DropActions DataViewModel::supportedDragActions() const -{ - return Qt::TargetMoveAction; -} - -//! Supported drop actions. - -Qt::DropActions DataViewModel::supportedDropActions() const -{ - return Qt::TargetMoveAction; -} - -//! Returns true if we can drop item here. - -bool DataViewModel::canDropMimeData(const QMimeData* data, Qt::DropAction, int, int, - const QModelIndex& parent) const -{ - if (data->hasFormat(QString::fromStdString(ExperimentalDataMimeType))) - if (auto target = sessionItemFromIndex(parent); target) - return target->modelType() == GUI::Constants::CanvasItemType; - - return false; -} - -bool DataViewModel::dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, - const QModelIndex& parent) -{ - if (!canDropMimeData(data, action, row, column, parent)) - return false; - - auto target = sessionItemFromIndex(parent); - - int requested_row = parent.isValid() ? parent.row() : row; - - // retrieving list of item identifiers and accessing items - auto identifiers = - Utils::deserialize(data->data(QString::fromStdString(ExperimentalDataMimeType))); - for (auto id : identifiers) { - auto item = sessionModel()->findItem(id.toStdString()); - - int row = std::clamp(requested_row, 0, item->parent()->itemCount(item->tagRow().tag) - 1); - sessionModel()->moveItem(item, target, {"", row}); - } - - return true; -} - -} // namespace gui2 diff --git a/gui2/importdataview/dataviewmodel.h b/gui2/importdataview/dataviewmodel.h deleted file mode 100644 index aa3d508c9fbc1736dcfde262a409d657fc8e0f04..0000000000000000000000000000000000000000 --- a/gui2/importdataview/dataviewmodel.h +++ /dev/null @@ -1,49 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/importdataview/dataviewmodel.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_IMPORTDATAVIEW_DATAVIEWMODEL_H -#define BORNAGAIN_GUI2_IMPORTDATAVIEW_DATAVIEWMODEL_H - -#include "darefl_export.h" -#include "mvvm/viewmodel/topitemsviewmodel.h" - -namespace ModelView { -class SessionModel; -} - -namespace gui2 { - -class ExperimentalDataModel; - -//! View model for ExperimentalDataModel with drag-and-drop support. - -class DAREFLCORE_EXPORT DataViewModel : public ModelView::TopItemsViewModel { - Q_OBJECT - -public: - DataViewModel(ExperimentalDataModel* model, QObject* parent = nullptr); - - Qt::ItemFlags flags(const QModelIndex& index) const override; - QMimeData* mimeData(const QModelIndexList& index_list) const override; - Qt::DropActions supportedDragActions() const override; - Qt::DropActions supportedDropActions() const override; - bool canDropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, - const QModelIndex& parent) const override; - bool dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, - const QModelIndex& parent) override; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_IMPORTDATAVIEW_DATAVIEWMODEL_H diff --git a/gui2/importdataview/graphcanvaswidget.cpp b/gui2/importdataview/graphcanvaswidget.cpp deleted file mode 100644 index b80ae5044c8fe136657cc2b40f6af4c0f8ad1f9b..0000000000000000000000000000000000000000 --- a/gui2/importdataview/graphcanvaswidget.cpp +++ /dev/null @@ -1,40 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/importdataview/graphcanvaswidget.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/importdataview/graphcanvaswidget.h" -#include "gui2/model/experimentaldataitems.h" -#include "mvvm/plotting/graphcanvas.h" -#include <QVBoxLayout> - -namespace gui2 { - -GraphCanvasWidget::GraphCanvasWidget(QWidget* parent) - : QWidget(parent), m_graphCanvas(new ModelView::GraphCanvas) -{ - auto layout = new QVBoxLayout(this); - layout->addWidget(m_graphCanvas); - layout->setContentsMargins(0, 5, 5, 5); -} - -void GraphCanvasWidget::setItem(CanvasItem* canvas_item) -{ - m_graphCanvas->setItem(canvas_item); -} - -void GraphCanvasWidget::updateViewport() -{ - m_graphCanvas->setViewportToContent(); -} - -} // namespace gui2 diff --git a/gui2/importdataview/graphcanvaswidget.h b/gui2/importdataview/graphcanvaswidget.h deleted file mode 100644 index a2e818624cf5ace352915fde4300d6e056b24f56..0000000000000000000000000000000000000000 --- a/gui2/importdataview/graphcanvaswidget.h +++ /dev/null @@ -1,48 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/importdataview/graphcanvaswidget.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_IMPORTDATAVIEW_GRAPHCANVASWIDGET_H -#define BORNAGAIN_GUI2_IMPORTDATAVIEW_GRAPHCANVASWIDGET_H - -#include "darefl_export.h" -#include <QWidget> - -namespace ModelView { -class GraphCanvas; -} - -namespace gui2 { - -class CanvasItem; - -//! Widget to show canvas with graph collection. -//! Occupies the right part of ImportDataEditor. - -class DAREFLCORE_EXPORT GraphCanvasWidget : public QWidget { - Q_OBJECT - -public: - GraphCanvasWidget(QWidget* parent = nullptr); - - void setItem(CanvasItem* canvas_item); - - void updateViewport(); - -private: - ModelView::GraphCanvas* m_graphCanvas{nullptr}; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_IMPORTDATAVIEW_GRAPHCANVASWIDGET_H diff --git a/gui2/importdataview/graphimportdata.h b/gui2/importdataview/graphimportdata.h deleted file mode 100644 index 01e688d4660267fd570345b1c90697b36c11e2a4..0000000000000000000000000000000000000000 --- a/gui2/importdataview/graphimportdata.h +++ /dev/null @@ -1,38 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/importdataview/graphimportdata.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_IMPORTDATAVIEW_GRAPHIMPORTDATA_H -#define BORNAGAIN_GUI2_IMPORTDATAVIEW_GRAPHIMPORTDATA_H - -#include "darefl_export.h" -#include <string> -#include <vector> - -namespace gui2 { - -//! Raw data to construct GraphItem and Data1DItem's. - -struct DAREFLCORE_EXPORT GraphImportData { - std::string graph_description; - - std::vector<double> bin_centers; - std::string axis_units; - - std::vector<double> bin_values; - std::string signal_units; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_IMPORTDATAVIEW_GRAPHIMPORTDATA_H diff --git a/gui2/importdataview/importdataeditor.cpp b/gui2/importdataview/importdataeditor.cpp deleted file mode 100644 index 1dc977629fb58fbc233470967c2d42e53bceb307..0000000000000000000000000000000000000000 --- a/gui2/importdataview/importdataeditor.cpp +++ /dev/null @@ -1,125 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/importdataview/importdataeditor.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/importdataview/importdataeditor.h" -#include "gui2/dataloader/dataloaderdialog.h" -#include "gui2/importdataview/dataselectionmodel.h" -#include "gui2/importdataview/dataselectorwidget.h" -#include "gui2/importdataview/dataviewmodel.h" -#include "gui2/importdataview/graphcanvaswidget.h" -#include "gui2/importdataview/importdataeditoractions.h" -#include "gui2/importdataview/importdataeditortoolbal.h" -#include "gui2/model/experimentaldataitems.h" -#include "gui2/model/experimentaldatamodel.h" -#include "mvvm/model/modelutils.h" -#include "mvvm/utils/containerutils.h" -#include <QSplitter> -#include <QVBoxLayout> - -using namespace ModelView; - -namespace gui2 { - -ImportDataEditor::ImportDataEditor(ExperimentalDataModel* model, QWidget* parent) - : QWidget(parent) - , m_dataModel(model) - , m_viewModel(new DataViewModel(model, this)) - , m_editorActions(new ImportDataEditorActions(m_dataModel, this)) - , m_editorToolBar(new ImportDataEditorToolBar(m_editorActions, this)) - , m_dataSelectorWidget(new DataSelectorWidget(m_viewModel)) - , m_graphCanvasWidget(new GraphCanvasWidget) -{ - auto layout = new QVBoxLayout(this); - layout->setContentsMargins(0, 0, 0, 0); - - auto splitter = new QSplitter; - splitter->addWidget(m_dataSelectorWidget); - splitter->addWidget(m_graphCanvasWidget); - splitter->setSizes(QList<int>() << 150 << 300); - - layout->addWidget(m_editorToolBar); - layout->addWidget(splitter); - - m_editorActions->setSelectionModel(m_dataSelectorWidget->selectionModel()); - m_viewModel->setRootSessionItem(model->canvasContainer()); - - setupConnections(); -} - -void ImportDataEditor::setupConnections() -{ - // connect toolbar with this editor - connect(m_editorToolBar, &ImportDataEditorToolBar::updateViewportRequest, - [this]() { m_graphCanvasWidget->updateViewport(); }); - - // connect selection model with this - auto on_selection_changed = [this]() { - m_graphCanvasWidget->setItem(selectionModel()->activeCanvas()); - }; - connect(m_dataSelectorWidget, &DataSelectorWidget::selectionChanged, on_selection_changed); - - // connect actions - connect(m_editorActions, &ImportDataEditorActions::invokeImportDialogRequest, this, - &ImportDataEditor::invokeImportDialog); -} - -//! Invoke the data load dialog and connect its state. - -void ImportDataEditor::invokeImportDialog() -{ - DataLoaderDialog dialog(this); - - auto [names, index] = canvasInfo(); - dialog.setTargetCanvas(names, index); - dialog.invokeFileSelectorDialog(); - if (dialog.fileNames().empty()) - return; - - if (dialog.exec() == QDialog::Accepted) { - auto canvases = Utils::FindItems<CanvasItem>(m_dataModel); - CanvasItem* target = - dialog.targetCanvasIndex() >= 0 ? canvases[dialog.targetCanvasIndex()] : nullptr; - - onImportDialogAccept(dialog.graphImportData(), target); - } -} - -//! Returns vector of canvas display name together with index of currently selected canvas. - -std::pair<std::vector<std::string>, int> ImportDataEditor::canvasInfo() const -{ - std::vector<std::string> names; - auto canvases = Utils::FindItems<CanvasItem>(m_dataModel); - auto current_canvas = selectionModel()->activeCanvas(); - std::transform(canvases.begin(), canvases.end(), std::back_inserter(names), - [](auto x) { return x->displayName(); }); - return std::make_pair(names, ModelView::Utils::IndexOfItem(canvases, current_canvas)); -} - -void ImportDataEditor::onImportDialogAccept(const std::vector<GraphImportData>& graph_data, - CanvasItem* canvas) -{ - if (!canvas) - canvas = m_dataModel->addCanvas(); - for (auto& data : graph_data) - m_dataModel->addGraph(data, *canvas); - selectionModel()->selectItem(canvas); -} - -DataSelectionModel* ImportDataEditor::selectionModel() const -{ - return m_dataSelectorWidget->selectionModel(); -} - -} // namespace gui2 diff --git a/gui2/importdataview/importdataeditor.h b/gui2/importdataview/importdataeditor.h deleted file mode 100644 index ed9e14b28877a3e0e11d6c570dcf1ea8606b1b75..0000000000000000000000000000000000000000 --- a/gui2/importdataview/importdataeditor.h +++ /dev/null @@ -1,60 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/importdataview/importdataeditor.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_IMPORTDATAVIEW_IMPORTDATAEDITOR_H -#define BORNAGAIN_GUI2_IMPORTDATAVIEW_IMPORTDATAEDITOR_H - -#include "darefl_export.h" -#include <QWidget> -#include <string> - -namespace gui2 { - -class ExperimentalDataModel; -struct GraphImportData; -class DataViewModel; -class DataSelectionModel; -class ImportDataEditorActions; -class ImportDataEditorToolBar; -class DataSelectorWidget; -class GraphCanvasWidget; -class CanvasItem; - -//! Main editor to import user data. - -class DAREFLCORE_EXPORT ImportDataEditor : public QWidget { - Q_OBJECT - -public: - ImportDataEditor(ExperimentalDataModel* model, QWidget* parent = nullptr); - -private: - void setupConnections(); - void invokeImportDialog(); - - std::pair<std::vector<std::string>, int> canvasInfo() const; - void onImportDialogAccept(const std::vector<GraphImportData>& graph_data, CanvasItem* canvas); - DataSelectionModel* selectionModel() const; - - ExperimentalDataModel* m_dataModel{nullptr}; - DataViewModel* m_viewModel{nullptr}; - ImportDataEditorActions* m_editorActions{nullptr}; - ImportDataEditorToolBar* m_editorToolBar{nullptr}; - DataSelectorWidget* m_dataSelectorWidget{nullptr}; - GraphCanvasWidget* m_graphCanvasWidget{nullptr}; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_IMPORTDATAVIEW_IMPORTDATAEDITOR_H diff --git a/gui2/importdataview/importdataeditoractions.cpp b/gui2/importdataview/importdataeditoractions.cpp deleted file mode 100644 index b5b28417302ef3cd16704b97b84f46fd420b0279..0000000000000000000000000000000000000000 --- a/gui2/importdataview/importdataeditoractions.cpp +++ /dev/null @@ -1,144 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/importdataview/importdataeditoractions.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/importdataview/importdataeditoractions.h" -#include "gui2/importdataview/dataselectionmodel.h" -#include "gui2/importdataview/graphimportdata.h" -#include "gui2/model/experimentaldataitems.h" -#include "gui2/model/experimentaldatamodel.h" -#include "mvvm/interfaces/undostackinterface.h" -#include "mvvm/model/comboproperty.h" -#include "mvvm/model/itemutils.h" -#include "mvvm/standarditems/graphitem.h" -#include "mvvm/standarditems/plottableitems.h" -#include "mvvm/viewmodel/viewmodelutils.h" - -namespace { -template <typename T> std::vector<T*> itemsFromIndexList(const QModelIndexList& indices) -{ - return ModelView::Utils::CastedItems<T>(ModelView::Utils::UniqueItemsFromIndex(indices)); -} - -} // namespace - -namespace gui2 { - -ImportDataEditorActions::ImportDataEditorActions(ExperimentalDataModel* model, QObject* parent) - : QObject(parent), m_dataModel(model) -{ -} - -void ImportDataEditorActions::setSelectionModel(DataSelectionModel* selection_model) -{ - if (m_selectionModel) - disconnect(m_selectionModel, &DataSelectionModel::selectionChanged, this, - &ImportDataEditorActions::onSelectionChanged); - - m_selectionModel = selection_model; - - if (m_selectionModel) - connect(m_selectionModel, &DataSelectionModel::selectionChanged, this, - &ImportDataEditorActions::onSelectionChanged); -} - -bool ImportDataEditorActions::isUndoEnabled() const -{ - return m_dataModel->undoStack() != nullptr; -} - -//! Create new canvas and append it to the end of canvas container. - -void ImportDataEditorActions::onAddCanvas() -{ - m_dataModel->addCanvas(); -} - -//! Merge selected canvases. All graphs will appear below canvas selected first. - -void ImportDataEditorActions::onMergeCanvases() -{ - if (isUndoEnabled()) - undoStack()->beginMacro("onMergeCanvases"); - - m_dataModel->mergeCanvases(m_selectionModel->selectedCanvas()); - - if (isUndoEnabled()) - undoStack()->endMacro(); -} - -//! Delete currently selected items. - -void ImportDataEditorActions::onDeleteItem() -{ - if (isUndoEnabled()) - undoStack()->beginMacro("onDeleteItem"); - - for (auto canvas : m_selectionModel->selectedCanvas()) - m_dataModel->removeCanvas(*canvas); - - for (auto graph : m_selectionModel->selectedGraphs()) - m_dataModel->removeGraph(*graph); - - if (isUndoEnabled()) - undoStack()->endMacro(); -} - -void ImportDataEditorActions::onUndo() -{ - if (!isUndoEnabled()) - return; - - m_dataModel->undoStack()->undo(); -} - -void ImportDataEditorActions::onRedo() -{ - if (!isUndoEnabled()) - return; - - m_dataModel->undoStack()->redo(); -} - -void ImportDataEditorActions::onImportDialogRequest() -{ - if (isUndoEnabled()) - undoStack()->beginMacro("onImportDialogRequest"); - - invokeImportDialogRequest(); - - if (isUndoEnabled()) - undoStack()->endMacro(); -} - -//! Processes changed selection. Will change line style of selected graph from -//! solid to dashed line. - -void ImportDataEditorActions::onSelectionChanged(const QItemSelection& selected, - const QItemSelection& deselected) -{ - auto selected_graphs = itemsFromIndexList<ModelView::GraphItem>(selected.indexes()); - for (auto graph : selected_graphs) - graph->penItem()->setSelected(true); - - auto deselected_graphs = itemsFromIndexList<ModelView::GraphItem>(deselected.indexes()); - for (auto graph : deselected_graphs) - graph->penItem()->setSelected(false); -} - -ModelView::UndoStackInterface* ImportDataEditorActions::undoStack() const -{ - return m_dataModel->undoStack(); -} - -} // namespace gui2 diff --git a/gui2/importdataview/importdataeditoractions.h b/gui2/importdataview/importdataeditoractions.h deleted file mode 100644 index e8df2d860a3ebb16f3f884b81f8f2bf55ac1c508..0000000000000000000000000000000000000000 --- a/gui2/importdataview/importdataeditoractions.h +++ /dev/null @@ -1,67 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/importdataview/importdataeditoractions.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_IMPORTDATAVIEW_IMPORTDATAEDITORACTIONS_H -#define BORNAGAIN_GUI2_IMPORTDATAVIEW_IMPORTDATAEDITORACTIONS_H - -#include "darefl_export.h" -#include <QObject> - -class QItemSelection; - -namespace ModelView { -class UndoStackInterface; -} - -namespace gui2 { - -class ExperimentalDataModel; -class DataSelectionModel; - -//! Actions for ImportDataEditor. - -class DAREFLCORE_EXPORT ImportDataEditorActions : public QObject { - Q_OBJECT - -public: - ImportDataEditorActions(ExperimentalDataModel* model, QObject* parent = nullptr); - - void setSelectionModel(DataSelectionModel* selection_model); - - bool isUndoEnabled() const; - -signals: - void invokeImportDialogRequest(); - -public slots: - void onAddCanvas(); - void onMergeCanvases(); - void onDeleteItem(); - void onUndo(); - void onRedo(); - void onImportDialogRequest(); - -private slots: - void onSelectionChanged(const QItemSelection& selected, const QItemSelection& deselected); - -private: - ModelView::UndoStackInterface* undoStack() const; - - ExperimentalDataModel* m_dataModel{nullptr}; - DataSelectionModel* m_selectionModel{nullptr}; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_IMPORTDATAVIEW_IMPORTDATAEDITORACTIONS_H diff --git a/gui2/importdataview/importdataeditortoolbal.cpp b/gui2/importdataview/importdataeditortoolbal.cpp deleted file mode 100644 index 2a1662514802ca504d1240fa31a19461c476fed3..0000000000000000000000000000000000000000 --- a/gui2/importdataview/importdataeditortoolbal.cpp +++ /dev/null @@ -1,88 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/importdataview/importdataeditortoolbal.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/importdataview/importdataeditortoolbal.h" -#include "gui2/importdataview/importdataeditoractions.h" -#include "gui2/mainwindow/styleutils.h" -#include <QAction> - -namespace gui2 { - -ImportDataEditorToolBar::ImportDataEditorToolBar(ImportDataEditorActions* editorActions, - QWidget* parent) - : QToolBar(parent), m_editorActions(editorActions) -{ - GUI::Utils::Style::SetToolBarStyleTextBesides(this); - - auto action = new QAction("Import", this); - action->setToolTip("Opens the data import dialog."); - action->setIcon(QIcon(":/icons/import.svg")); - connect(action, &QAction::triggered, this, - [this]() { m_editorActions->onImportDialogRequest(); }); - addAction(action); - - addSeparator(); - - auto add_canvas_action = new QAction("Add canvas", this); - add_canvas_action->setToolTip( - "Creates an empty canvas and appends it to the list.\n" - "Canvas can hold multiple graphs, graphs can be moved between canvas."); - add_canvas_action->setIcon(QIcon(":/icons/plus-box-outline.svg")); - connect(add_canvas_action, &QAction::triggered, [this]() { m_editorActions->onAddCanvas(); }); - addAction(add_canvas_action); - - auto merge_canvases_action = new QAction("Merge", this); - merge_canvases_action->setToolTip("Merge several selected canvases into one.\n" - "All graphs will appear on a single canvas."); - merge_canvases_action->setIcon(QIcon(":/icons/set-merge.svg")); - connect(merge_canvases_action, &QAction::triggered, - [this]() { m_editorActions->onMergeCanvases(); }); - addAction(merge_canvases_action); - - auto delete_action = new QAction("Remove", this); - delete_action->setToolTip("Remove the currently selected item,\n" - "single graph or canvas with whole content."); - delete_action->setIcon(QIcon(":/icons/beaker-remove-outline.svg")); - connect(delete_action, &QAction::triggered, [this]() { m_editorActions->onDeleteItem(); }); - addAction(delete_action); - - addSeparator(); - - auto undo_action = new QAction("Undo", this); - undo_action->setToolTip("Undo the action last performed."); - undo_action->setIcon(QIcon(":/icons/undo.svg")); - undo_action->setEnabled(editorActions->isUndoEnabled()); - connect(undo_action, &QAction::triggered, [this]() { m_editorActions->onUndo(); }); - addAction(undo_action); - - auto redo_action = new QAction("Redo", this); - redo_action->setToolTip("Redo the action just performed."); - redo_action->setIcon(QIcon(":/icons/redo.svg")); - redo_action->setEnabled(editorActions->isUndoEnabled()); - connect(redo_action, &QAction::triggered, [this]() { m_editorActions->onRedo(); }); - addAction(redo_action); - - auto empty = new QWidget(this); - empty->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); - addWidget(empty); - - auto reset_graph_action = new QAction("Replot", this); - reset_graph_action->setToolTip("Set plot axes to default range"); - reset_graph_action->setIcon(QIcon(":/icons/aspect-ratio.svg")); - connect(reset_graph_action, &QAction::triggered, this, - &ImportDataEditorToolBar::updateViewportRequest); - addAction(reset_graph_action); -} - -} // namespace gui2 diff --git a/gui2/importdataview/importdataeditortoolbal.h b/gui2/importdataview/importdataeditortoolbal.h deleted file mode 100644 index 2aab6d93976e8314938b484c59787a576dc8a07c..0000000000000000000000000000000000000000 --- a/gui2/importdataview/importdataeditortoolbal.h +++ /dev/null @@ -1,42 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/importdataview/importdataeditortoolbal.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_IMPORTDATAVIEW_IMPORTDATAEDITORTOOLBAL_H -#define BORNAGAIN_GUI2_IMPORTDATAVIEW_IMPORTDATAEDITORTOOLBAL_H - -#include "darefl_export.h" -#include <QToolBar> - -namespace gui2 { - -class ImportDataEditorActions; - -//! Toolbar for ImportDataEditor. - -class DAREFLCORE_EXPORT ImportDataEditorToolBar : public QToolBar { - Q_OBJECT - -public: - ImportDataEditorToolBar(ImportDataEditorActions* editorActions, QWidget* parent = nullptr); - -signals: - void updateViewportRequest(); - -private: - ImportDataEditorActions* m_editorActions{nullptr}; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_IMPORTDATAVIEW_IMPORTDATAEDITORTOOLBAL_H diff --git a/gui2/importdataview/importdataview.cpp b/gui2/importdataview/importdataview.cpp deleted file mode 100644 index b4c330517d964d74394363d6989e737defd4a422..0000000000000000000000000000000000000000 --- a/gui2/importdataview/importdataview.cpp +++ /dev/null @@ -1,30 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/importdataview/importdataview.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/importdataview/importdataview.h" -#include "gui2/importdataview/importdataeditor.h" -#include "gui2/model/applicationmodels.h" -#include <QVBoxLayout> - -namespace gui2 { - -ImportDataView::ImportDataView(ApplicationModels* models, QWidget* parent) - : QWidget(parent), m_models(models) -{ - auto layout = new QVBoxLayout(this); - layout->addWidget(new ImportDataEditor(models->experimentalDataModel())); - layout->setContentsMargins(0, 0, 0, 0); -} - -} // namespace gui2 diff --git a/gui2/importdataview/importdataview.h b/gui2/importdataview/importdataview.h deleted file mode 100644 index ca609a1a0ebf02d3d7913e8767eac52be232233e..0000000000000000000000000000000000000000 --- a/gui2/importdataview/importdataview.h +++ /dev/null @@ -1,39 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/importdataview/importdataview.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_IMPORTDATAVIEW_IMPORTDATAVIEW_H -#define BORNAGAIN_GUI2_IMPORTDATAVIEW_IMPORTDATAVIEW_H - -#include "darefl_export.h" -#include <QWidget> - -namespace gui2 { - -class ApplicationModels; - -//! Main window to import user data. - -class DAREFLCORE_EXPORT ImportDataView : public QWidget { - Q_OBJECT - -public: - ImportDataView(ApplicationModels* models, QWidget* parent = nullptr); - -private: - ApplicationModels* m_models{nullptr}; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_IMPORTDATAVIEW_IMPORTDATAVIEW_H diff --git a/gui2/layereditor/CMakeLists.txt b/gui2/layereditor/CMakeLists.txt deleted file mode 100644 index af4570d25a3938fd75f4a5217e59d83fc1ec5bde..0000000000000000000000000000000000000000 --- a/gui2/layereditor/CMakeLists.txt +++ /dev/null @@ -1,20 +0,0 @@ -target_sources(${library_name} PRIVATE - customlayertreeeditorfactory.cpp - customlayertreeeditorfactory.h - layereditor.cpp - layereditor.h - layereditoractions.cpp - layereditoractions.h - layereditortoolbar.cpp - layereditortoolbar.h - layereditorwidget.cpp - layereditorwidget.h - layerselectionmodel.cpp - layerselectionmodel.h - layertreeview.cpp - layertreeview.h - layerviewmodel.cpp - layerviewmodel.h - layerviewmodelcontroller.cpp - layerviewmodelcontroller.h -) diff --git a/gui2/layereditor/customlayertreeeditorfactory.cpp b/gui2/layereditor/customlayertreeeditorfactory.cpp deleted file mode 100644 index 73a17c450c92230c478ded29c196d38590b2096c..0000000000000000000000000000000000000000 --- a/gui2/layereditor/customlayertreeeditorfactory.cpp +++ /dev/null @@ -1,60 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/layereditor/customlayertreeeditorfactory.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/layereditor/customlayertreeeditorfactory.h" -#include "gui2/model/applicationmodels.h" -#include "gui2/model/materialmodel.h" -#include "mvvm/editors/externalpropertycomboeditor.h" -#include "mvvm/model/externalproperty.h" -#include <QModelIndex> -#include <algorithm> - -using namespace ModelView; - -namespace gui2 { - -namespace { -//! Return list of possible choices for material properties in MaterialModel. -//! Use "undefined material" as a first item in a list. -std::vector<ModelView::ExternalProperty> get_choice_of_materials(MaterialModel* model) -{ - std::vector<ModelView::ExternalProperty> result{ModelView::ExternalProperty::undefined()}; - auto other_data = model->material_data(); - std::copy(other_data.begin(), other_data.end(), std::back_inserter(result)); - return result; -} -} // namespace - -CustomLayerTreeEditorFactory::~CustomLayerTreeEditorFactory() = default; - -CustomLayerTreeEditorFactory::CustomLayerTreeEditorFactory(ApplicationModels* models) - : m_models(models) -{ -} - -std::unique_ptr<CustomEditor> -CustomLayerTreeEditorFactory::createEditor(const QModelIndex& index) const -{ - auto value = index.data(Qt::EditRole); - if (Utils::IsExtPropertyVariant(value)) { - auto material_choice_callback = [this]() { - return get_choice_of_materials(m_models->materialModel()); - }; - return std::make_unique<ExternalPropertyComboEditor>(material_choice_callback); - } else { - return DefaultEditorFactory::createEditor(index); - } -} - -} // namespace gui2 diff --git a/gui2/layereditor/customlayertreeeditorfactory.h b/gui2/layereditor/customlayertreeeditorfactory.h deleted file mode 100644 index e1e2e88118d0ec994de728ae10c2fc24bb4cbdc6..0000000000000000000000000000000000000000 --- a/gui2/layereditor/customlayertreeeditorfactory.h +++ /dev/null @@ -1,41 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/layereditor/customlayertreeeditorfactory.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_LAYEREDITOR_CUSTOMLAYERTREEEDITORFACTORY_H -#define BORNAGAIN_GUI2_LAYEREDITOR_CUSTOMLAYERTREEEDITORFACTORY_H - -#include "darefl_export.h" -#include "mvvm/editors/defaulteditorfactory.h" - -namespace gui2 { - -class ApplicationModels; - -//! Custom editor factory for LayerTreeView. Substitutes default ExternalProperty editor -//! with custom one, which will offer the choice between all defined materials. - -class DAREFLCORE_EXPORT CustomLayerTreeEditorFactory : public ModelView::DefaultEditorFactory { -public: - CustomLayerTreeEditorFactory(ApplicationModels* models); - ~CustomLayerTreeEditorFactory(); - - std::unique_ptr<ModelView::CustomEditor> createEditor(const QModelIndex& index) const; - -private: - ApplicationModels* m_models; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_LAYEREDITOR_CUSTOMLAYERTREEEDITORFACTORY_H diff --git a/gui2/layereditor/layereditor.cpp b/gui2/layereditor/layereditor.cpp deleted file mode 100644 index eb93fcb43080ef2d4fe086b70400ca252c98d8e9..0000000000000000000000000000000000000000 --- a/gui2/layereditor/layereditor.cpp +++ /dev/null @@ -1,72 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/layereditor/layereditor.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/layereditor/layereditor.h" -#include "gui2/layereditor/layereditoractions.h" -#include "gui2/layereditor/layereditortoolbar.h" -#include "gui2/layereditor/layereditorwidget.h" -#include "gui2/layereditor/layerselectionmodel.h" -#include "gui2/mainwindow/styleutils.h" -#include "gui2/model/applicationmodels.h" -#include <QVBoxLayout> - -namespace gui2 { - -LayerEditor::LayerEditor(QWidget* parent) - : QWidget(parent) - , m_actions(new LayerEditorActions(this)) - , m_editorWidget(new LayerEditorWidget(this)) - , m_toolBar(new LayerEditorToolBar(m_actions)) -{ - setWindowTitle("Layer editor"); - auto layout = new QVBoxLayout; - layout->addWidget(m_toolBar); - layout->addWidget(m_editorWidget); - setLayout(layout); - layout->setContentsMargins(0, 0, 0, 0); - layout->setSpacing(0); -} - -//! Set the mododel for the different items -void LayerEditor::setModels(ApplicationModels* models) -{ - m_actions->setModel(models->sampleModel()); - m_editorWidget->setModels(models); - - connect(m_editorWidget->selectionModel(), &LayerSelectionModel::selectionChanged, this, - &LayerEditor::selectionChanged); - - m_actions->setSelectionModel(m_editorWidget->selectionModel()); -} - -QSize LayerEditor::sizeHint() const -{ - return GUI::Utils::Style::DockSizeHint(); -} - -QSize LayerEditor::minimumSizeHint() const -{ - return GUI::Utils::Style::DockMinimumSizeHint(); -} - -void LayerEditor::selectionChanged() -{ - dynamic_cast<LayerEditorToolBar*>(m_toolBar)->updateToolButtonStates( - m_editorWidget->selectionModel()->firstSelected(), - m_editorWidget->selectionModel()->lastSelected()); -} - -LayerEditor::~LayerEditor() = default; - -} // namespace gui2 diff --git a/gui2/layereditor/layereditor.h b/gui2/layereditor/layereditor.h deleted file mode 100644 index c6545e61f8e42300b247466a48e6260833e7f962..0000000000000000000000000000000000000000 --- a/gui2/layereditor/layereditor.h +++ /dev/null @@ -1,55 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/layereditor/layereditor.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_LAYEREDITOR_LAYEREDITOR_H -#define BORNAGAIN_GUI2_LAYEREDITOR_LAYEREDITOR_H - -#include "darefl_export.h" -#include <QWidget> - -namespace ModelView { -class AbstractViewModel; -} - -namespace gui2 { - -class ApplicationModels; -class LayerEditorActions; -class LayerEditorToolBar; -class LayerEditorWidget; - -//! Layer editor. - -class DAREFLCORE_EXPORT LayerEditor : public QWidget { - Q_OBJECT - -public: - LayerEditor(QWidget* parent = nullptr); - ~LayerEditor(); - - void setModels(ApplicationModels* models); - - QSize sizeHint() const override; - QSize minimumSizeHint() const override; - void selectionChanged(); - -private: - LayerEditorActions* m_actions{nullptr}; - LayerEditorWidget* m_editorWidget{nullptr}; - LayerEditorToolBar* m_toolBar{nullptr}; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_LAYEREDITOR_LAYEREDITOR_H diff --git a/gui2/layereditor/layereditoractions.cpp b/gui2/layereditor/layereditoractions.cpp deleted file mode 100644 index 47522882d03742998a7314b96b97e71897e47831..0000000000000000000000000000000000000000 --- a/gui2/layereditor/layereditoractions.cpp +++ /dev/null @@ -1,149 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/layereditor/layereditoractions.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/layereditor/layereditoractions.h" -#include "gui2/layereditor/layerselectionmodel.h" -#include "gui2/model/item_constants.h" -#include "gui2/model/sampleitems.h" -#include "gui2/model/samplemodel.h" -#include "mvvm/model/itemutils.h" -#include "mvvm/model/modelutils.h" -#include "mvvm/viewmodel/viewmodel.h" -#include <QAction> - -using namespace ModelView; - -namespace gui2 { - -struct LayerEditorActions::LayerEditorActionsImpl { - SampleModel* sample_model{nullptr}; - LayerSelectionModel* selection_model{nullptr}; - LayerEditorActionsImpl() {} - - //! Finds parent and tagrow to insert new item - - std::pair<SessionItem*, TagRow> locateInsertPlace() - { - auto all_selected = selection_model->selectedItems(); - auto selected = all_selected.empty() ? nullptr : all_selected.back(); - if (selected) - return {selected->parent(), selected->tagRow().next()}; - return {root_item(), TagRow{}}; - } - - //! Returns a multi layer playing the role of invisible root item. - - ModelView::SessionItem* root_item() - { - return selection_model->viewModel()->sessionItemFromIndex(QModelIndex()); - } -}; - -LayerEditorActions::LayerEditorActions(QObject* parent) - : QObject(parent), p_impl(std::make_unique<LayerEditorActionsImpl>()) -{ -} - -void LayerEditorActions::setModel(SampleModel* model) -{ - p_impl->sample_model = model; -} - -//! Adds layer after selected item. If more than one item is selected, adds after the last one. - -void LayerEditorActions::onAddLayer() -{ - if (!p_impl->sample_model) - return; - - auto [parent, tagrow] = p_impl->locateInsertPlace(); - auto new_item = p_impl->sample_model->insertItem<LayerItem>(parent, tagrow); - p_impl->selection_model->selectItem(new_item); -} - -void LayerEditorActions::onAddMultiLayer() -{ - if (!p_impl->sample_model) - return; - - auto [parent, tagrow] = p_impl->locateInsertPlace(); - auto multilayer = p_impl->sample_model->insertItem<MultiLayerItem>(parent, tagrow); - p_impl->sample_model->insertItem<LayerItem>(multilayer); - p_impl->sample_model->insertItem<LayerItem>(multilayer); - p_impl->selection_model->selectItem(multilayer); -} - -void LayerEditorActions::onClone() -{ - if (!p_impl->sample_model) - return; - - auto items = p_impl->selection_model->selectedItems(); - if (items.empty()) - return; - - std::vector<ModelView::SessionItem*> new_selection; - for (auto to_clone : items) - new_selection.push_back(p_impl->sample_model->copyItem(to_clone, to_clone->parent(), - to_clone->tagRow().next())); - - p_impl->selection_model->selectItems(new_selection); -} - -void LayerEditorActions::onRemove() -{ - auto items = p_impl->selection_model->selectedItems(); - if (items.empty()) - return; - - auto prev_to_select = ModelView::Utils::FindPreviousSibling(items.front()); - auto next_to_select = ModelView::Utils::FindNextSibling(items.back()); - - for (auto item : items) - ModelView::Utils::DeleteItemFromModel(item); - if (next_to_select) { - p_impl->selection_model->selectItem(next_to_select); - } else if (prev_to_select) { - p_impl->selection_model->selectItem(prev_to_select); - } -} - -void LayerEditorActions::onMoveUp() -{ - auto selected = p_impl->selection_model->selectedItems(); - - for (auto item : selected) - ModelView::Utils::MoveUp(item); - - p_impl->selection_model->selectItems(selected); -} - -void LayerEditorActions::onMoveDown() -{ - auto selected = p_impl->selection_model->selectedItems(); - - for (auto item : selected) - ModelView::Utils::MoveDown(item); - - p_impl->selection_model->selectItems(selected); -} - -void LayerEditorActions::setSelectionModel(LayerSelectionModel* selection_model) -{ - p_impl->selection_model = selection_model; -} - -LayerEditorActions::~LayerEditorActions() = default; - -} // namespace gui2 diff --git a/gui2/layereditor/layereditoractions.h b/gui2/layereditor/layereditoractions.h deleted file mode 100644 index 8814586e6d89108fd6fa8340cc183bc205aa9e7f..0000000000000000000000000000000000000000 --- a/gui2/layereditor/layereditoractions.h +++ /dev/null @@ -1,55 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/layereditor/layereditoractions.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_LAYEREDITOR_LAYEREDITORACTIONS_H -#define BORNAGAIN_GUI2_LAYEREDITOR_LAYEREDITORACTIONS_H - -#include "darefl_export.h" -#include <QObject> -#include <memory> - -namespace gui2 { - -class SampleModel; -class LayerSelectionModel; - -//! Handles user actions applied to layer tree. -//! Belongs to LayerEditor. - -class DAREFLCORE_EXPORT LayerEditorActions : public QObject { - Q_OBJECT - -public: - LayerEditorActions(QObject* parent = nullptr); - ~LayerEditorActions(); - - void setModel(SampleModel* model); - - void onAddLayer(); - void onAddMultiLayer(); - void onClone(); - void onRemove(); - void onMoveUp(); - void onMoveDown(); - - void setSelectionModel(LayerSelectionModel* selection_model); - -private: - struct LayerEditorActionsImpl; - std::unique_ptr<LayerEditorActionsImpl> p_impl; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_LAYEREDITOR_LAYEREDITORACTIONS_H diff --git a/gui2/layereditor/layereditortoolbar.cpp b/gui2/layereditor/layereditortoolbar.cpp deleted file mode 100644 index 32e555a92cc2f00a83468b7452bd08808bcb5b66..0000000000000000000000000000000000000000 --- a/gui2/layereditor/layereditortoolbar.cpp +++ /dev/null @@ -1,119 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/layereditor/layereditortoolbar.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/layereditor/layereditortoolbar.h" -#include "gui2/layereditor/layereditoractions.h" -#include "gui2/mainwindow/styleutils.h" -#include <QAction> -#include <QMenu> -#include <QToolButton> - -namespace gui2 { - -LayerEditorToolBar::LayerEditorToolBar(LayerEditorActions* actions, QWidget* parent) - : QToolBar(parent) -{ - GUI::Utils::Style::SetToolBarStyleTextBesides(this); - - auto layer_menu = create_layer_menu(actions); - - auto add_layer_button = new QToolButton; - add_layer_button->setText("Add"); - add_layer_button->setToolTip( - "Adds a new single layer (default) or new layer-repeater after currently selected.\nIf " - "nothing is selected, appends to the end. Click and hold to see possible choices."); - add_layer_button->setPopupMode(QToolButton::MenuButtonPopup); - add_layer_button->setIcon(QIcon(":/icons/plus-circle-outline.svg")); - add_layer_button->setMenu(layer_menu); - add_layer_button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); - addWidget(add_layer_button); - m_toolbarWidgets.insert(std::pair<std::string, QWidget*>("Add", add_layer_button)); - connect(add_layer_button, &QToolButton::clicked, - [layer_menu]() { layer_menu->defaultAction()->triggered(); }); - - auto action = new QAction("Clone", this); - action->setIcon(QIcon(":/icons/plus-circle-multiple-outline.svg")); - action->setToolTip("Clones selected layer"); - connect(action, &QAction::triggered, actions, &LayerEditorActions::onClone); - addAction(action); - m_toolbarWidgets.insert(std::pair<std::string, QWidget*>("Clone", widgetForAction(action))); - - action = new QAction("Remove", this); - action->setIcon(QIcon(":/icons/beaker-remove-outline.svg")); - action->setToolTip("Removes selected layer"); - connect(action, &QAction::triggered, actions, &LayerEditorActions::onRemove); - addAction(action); - m_toolbarWidgets.insert(std::pair<std::string, QWidget*>("Remove", widgetForAction(action))); - - addSeparator(); - - action = new QAction("Up", this); - action->setIcon(QIcon(":/icons/arrow-up-circle-outline.svg")); - action->setToolTip("Moves selected layer up"); - connect(action, &QAction::triggered, actions, &LayerEditorActions::onMoveUp); - addAction(action); - m_toolbarWidgets.insert(std::pair<std::string, QWidget*>("Up", widgetForAction(action))); - - action = new QAction("Down", this); - action->setIcon(QIcon(":/icons/arrow-down-circle-outline.svg")); - action->setToolTip("Moves selected layer down"); - connect(action, &QAction::triggered, actions, &LayerEditorActions::onMoveDown); - addAction(action); - m_toolbarWidgets.insert(std::pair<std::string, QWidget*>("Down", widgetForAction(action))); - - m_toolbarWidgets["Add"]->setEnabled(true); - m_toolbarWidgets["Clone"]->setEnabled(true); - m_toolbarWidgets["Remove"]->setEnabled(true); - m_toolbarWidgets["Up"]->setEnabled(false); - m_toolbarWidgets["Down"]->setEnabled(false); -} - -//! Creates menu to add layer and layer-repeater. - -QMenu* LayerEditorToolBar::create_layer_menu(LayerEditorActions* editor_actions) -{ - auto result = new QMenu("Add", this); - result->setToolTipsVisible(true); - result->menuAction()->setToolTip("Adds a single layer or layer-repeater."); - result->setIcon(QIcon(":/icons/plus-circle-outline.svg")); - - // add layer action - auto action = result->addAction("Adds a single layer"); - action->setIcon(QIcon(":/icons/layers-outline.svg")); - action->setToolTip("Adds a new layer after selected one"); - connect(action, &QAction::triggered, editor_actions, &LayerEditorActions::onAddLayer); - result->setDefaultAction(action); - - // add layer repeater action - action = result->addAction("Adds layer repeater"); - action->setIcon(QIcon(":/icons/layers-triple-outline.svg")); - action->setToolTip("Adds a new layer-repeater after selected one.\n" - "Layer repeater allows to repeat it content (i.e. bi-layer) " - "certain amount of times"); - connect(action, &QAction::triggered, editor_actions, &LayerEditorActions::onAddMultiLayer); - - return result; -} - -//! Handle the QToolButtons for their enabled state depending on what is selected -void LayerEditorToolBar::updateToolButtonStates(bool first_present, bool last_present) -{ - m_toolbarWidgets["Add"]->setEnabled(true); - m_toolbarWidgets["Clone"]->setEnabled(true); - m_toolbarWidgets["Remove"]->setEnabled(true); - m_toolbarWidgets["Up"]->setEnabled((!first_present) ? (true) : (false)); - m_toolbarWidgets["Down"]->setEnabled((!last_present) ? (true) : (false)); -} - -} // namespace gui2 diff --git a/gui2/layereditor/layereditortoolbar.h b/gui2/layereditor/layereditortoolbar.h deleted file mode 100644 index 02abfab72dc6e588f9eef52096a72ba16d05c992..0000000000000000000000000000000000000000 --- a/gui2/layereditor/layereditortoolbar.h +++ /dev/null @@ -1,46 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/layereditor/layereditortoolbar.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_LAYEREDITOR_LAYEREDITORTOOLBAR_H -#define BORNAGAIN_GUI2_LAYEREDITOR_LAYEREDITORTOOLBAR_H - -#include "darefl_export.h" -#include <QToolBar> -#include <QWidget> -#include <map> -#include <string> - -namespace gui2 { - -class LayerEditorActions; - -//! Layer editor toolbar. - -class DAREFLCORE_EXPORT LayerEditorToolBar : public QToolBar { - Q_OBJECT - -public: - LayerEditorToolBar(LayerEditorActions* actions, QWidget* parent = nullptr); - ~LayerEditorToolBar() = default; - - void updateToolButtonStates(bool first_present, bool last_present); - -private: - QMenu* create_layer_menu(LayerEditorActions* editor_actions); - std::map<std::string, QWidget*> m_toolbarWidgets; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_LAYEREDITOR_LAYEREDITORTOOLBAR_H diff --git a/gui2/layereditor/layereditorwidget.cpp b/gui2/layereditor/layereditorwidget.cpp deleted file mode 100644 index 26b7b1e031101b37348c5f5501d1968c08ba3b71..0000000000000000000000000000000000000000 --- a/gui2/layereditor/layereditorwidget.cpp +++ /dev/null @@ -1,58 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/layereditor/layereditorwidget.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/layereditor/layereditorwidget.h" -#include "gui2/layereditor/customlayertreeeditorfactory.h" -#include "gui2/layereditor/layerselectionmodel.h" -#include "gui2/layereditor/layertreeview.h" -#include "gui2/layereditor/layerviewmodel.h" -#include "gui2/model/applicationmodels.h" -#include "gui2/model/sampleitems.h" -#include "gui2/model/samplemodel.h" -#include "mvvm/viewmodel/viewmodeldelegate.h" -#include <QVBoxLayout> - -namespace gui2 { - -LayerEditorWidget::LayerEditorWidget(QWidget* parent) - : QWidget(parent) - , m_layerView(new LayerTreeView) - , m_delegate(std::make_unique<ModelView::ViewModelDelegate>()) -{ - auto layout = new QVBoxLayout; - layout->setContentsMargins(0, 0, 0, 0); - layout->addWidget(m_layerView); - setLayout(layout); - m_layerView->setItemDelegate(m_delegate.get()); -} - -LayerEditorWidget::~LayerEditorWidget() = default; - -void LayerEditorWidget::setModels(ApplicationModels* models) -{ - m_viewModel = std::make_unique<LayerViewModel>(models->sampleModel()); - m_selectionModel = new LayerSelectionModel(m_viewModel.get(), this); - - m_delegate->setEditorFactory(std::make_unique<CustomLayerTreeEditorFactory>(models)); - m_viewModel->setRootSessionItem(models->sampleModel()->topItem<MultiLayerItem>()); - m_layerView->setModel(m_viewModel.get()); - m_layerView->setSelectionModel(m_selectionModel); -} - -LayerSelectionModel* LayerEditorWidget::selectionModel() const -{ - return m_selectionModel; -} - -} // namespace gui2 diff --git a/gui2/layereditor/layereditorwidget.h b/gui2/layereditor/layereditorwidget.h deleted file mode 100644 index 74c15defd1022ef943e2cd738008e1b8b9d2d6c3..0000000000000000000000000000000000000000 --- a/gui2/layereditor/layereditorwidget.h +++ /dev/null @@ -1,56 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/layereditor/layereditorwidget.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_LAYEREDITOR_LAYEREDITORWIDGET_H -#define BORNAGAIN_GUI2_LAYEREDITOR_LAYEREDITORWIDGET_H - -#include "darefl_export.h" -#include <QWidget> -#include <memory> - -namespace ModelView { -class ViewModelDelegate; -} // namespace ModelView - -namespace gui2 { - -class ApplicationModels; -class LayerTreeView; -class LayerSelectionModel; -class LayerViewModel; - -//! Widget to hold layer tree (LayerTreeView) and all corresponding models and delegates. -//! Belongs to LayerEditor. - -class DAREFLCORE_EXPORT LayerEditorWidget : public QWidget { - Q_OBJECT - -public: - LayerEditorWidget(QWidget* parent = nullptr); - ~LayerEditorWidget(); - - void setModels(ApplicationModels* models); - - LayerSelectionModel* selectionModel() const; - -private: - std::unique_ptr<LayerViewModel> m_viewModel; - LayerSelectionModel* m_selectionModel{nullptr}; - LayerTreeView* m_layerView{nullptr}; - std::unique_ptr<ModelView::ViewModelDelegate> m_delegate; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_LAYEREDITOR_LAYEREDITORWIDGET_H diff --git a/gui2/layereditor/layerselectionmodel.cpp b/gui2/layereditor/layerselectionmodel.cpp deleted file mode 100644 index 8d9893546a8f09553998632d6ba94eb8952b0217..0000000000000000000000000000000000000000 --- a/gui2/layereditor/layerselectionmodel.cpp +++ /dev/null @@ -1,102 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/layereditor/layerselectionmodel.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/layereditor/layerselectionmodel.h" -#include "gui2/model/sampleitems.h" -#include "mvvm/viewmodel/viewmodel.h" -#include "mvvm/viewmodel/viewmodelutils.h" -#include <QItemSelection> - -namespace gui2 { - -LayerSelectionModel::LayerSelectionModel(ModelView::ViewModel* view_model, QObject* parent) - : QItemSelectionModel(view_model, parent) -{ - // FIXME cover with unit tests after implementing ViewItemSelectionModel - connect(view_model, &ModelView::ViewModel::modelAboutToBeReset, [this]() { clearSelection(); }); -} - -//! Selects all rows corresponding to given items. - -void LayerSelectionModel::selectItems(std::vector<ModelView::SessionItem*> items) -{ - QModelIndexList indexes; - for (auto item : items) - indexes << viewModel()->indexOfSessionItem(item->getItem(LayerItem::P_NAME)); - - if (indexes.empty()) - return; - - clearSelection(); - - QItemSelection selection(indexes.front(), indexes.back()); - auto flags = QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows; - select(selection, flags); - // setCurrentIndex(id, flags); What to do? -} - -//! Selects whole row corresponding to given item. - -void LayerSelectionModel::selectItem(ModelView::SessionItem* item) -{ - selectItems({item}); -} - -//! Returns vector of selected layers or multilayers. -//! We assume, that there is a single line selection mode switched on, and that -//! the columns contains property items related to either LayerItem or MultiLayerItem. - -std::vector<ModelView::SessionItem*> LayerSelectionModel::selectedItems() const -{ - const QModelIndexList& selection = selectedRows(); - if (selection.empty()) - return {}; - - std::vector<ModelView::SessionItem*> result; - for (const auto& index : selection) - if (auto item = viewModel()->sessionItemFromIndex(index); item) - result.push_back(item->parent()); - - return result; -} - -//! Return the casted view model -const ModelView::ViewModel* LayerSelectionModel::viewModel() const -{ - return static_cast<const ModelView::ViewModel*>(model()); -} - -//! Checks if the first row is presen in the selection -bool LayerSelectionModel::firstSelected() const -{ - const QModelIndexList& selection = selectedRows(); - for (const auto& index : selection) { - if (index.row() == 0) - return true; - } - return false; -} - -//! checks if the last row is present in the selection -bool LayerSelectionModel::lastSelected() const -{ - const QModelIndexList& selection = selectedRows(); - for (const auto& index : selection) { - if (index.row() == viewModel()->rowCount() - 1) - return true; - } - return false; -} - -} // namespace gui2 diff --git a/gui2/layereditor/layerselectionmodel.h b/gui2/layereditor/layerselectionmodel.h deleted file mode 100644 index 27ce310e871860cd9f22a8a835584c979412f2ee..0000000000000000000000000000000000000000 --- a/gui2/layereditor/layerselectionmodel.h +++ /dev/null @@ -1,52 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/layereditor/layerselectionmodel.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_LAYEREDITOR_LAYERSELECTIONMODEL_H -#define BORNAGAIN_GUI2_LAYEREDITOR_LAYERSELECTIONMODEL_H - -#include "darefl_export.h" -#include <QItemSelectionModel> -#include <vector> - -namespace ModelView { -class ViewModel; -class SessionItem; -} // namespace ModelView - -namespace gui2 { - -class LayerEditorActions; - -//! Custom selection model for layer view model (AbstractViewModel). - -class DAREFLCORE_EXPORT LayerSelectionModel : public QItemSelectionModel { - Q_OBJECT - -public: - LayerSelectionModel(ModelView::ViewModel* view_model, QObject* parent = nullptr); - ~LayerSelectionModel() = default; - - void selectItems(std::vector<ModelView::SessionItem*> items); - void selectItem(ModelView::SessionItem* item); - bool firstSelected() const; - bool lastSelected() const; - - std::vector<ModelView::SessionItem*> selectedItems() const; - - const ModelView::ViewModel* viewModel() const; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_LAYEREDITOR_LAYERSELECTIONMODEL_H diff --git a/gui2/layereditor/layertreeview.cpp b/gui2/layereditor/layertreeview.cpp deleted file mode 100644 index 96f5f8c6b2a63748b6e3b971d8ac3d9ebf7d9850..0000000000000000000000000000000000000000 --- a/gui2/layereditor/layertreeview.cpp +++ /dev/null @@ -1,38 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/layereditor/layertreeview.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/layereditor/layertreeview.h" -#include <QHeaderView> -#include <QMouseEvent> - -namespace gui2 { - -LayerTreeView::~LayerTreeView() = default; - -LayerTreeView::LayerTreeView(QWidget* parent) : QTreeView(parent) -{ - setAlternatingRowColors(true); - setSelectionBehavior(QAbstractItemView::SelectRows); - setSelectionMode(QAbstractItemView::ExtendedSelection); - // setTabKeyNavigation(true); - header()->setSectionResizeMode(QHeaderView::Stretch); -} - -void LayerTreeView::setModel(QAbstractItemModel* model) -{ - QTreeView::setModel(model); - expandAll(); -} - -} // namespace gui2 diff --git a/gui2/layereditor/layertreeview.h b/gui2/layereditor/layertreeview.h deleted file mode 100644 index 020944e05d5d27d45276d8617a075aa08934b28b..0000000000000000000000000000000000000000 --- a/gui2/layereditor/layertreeview.h +++ /dev/null @@ -1,37 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/layereditor/layertreeview.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_LAYEREDITOR_LAYERTREEVIEW_H -#define BORNAGAIN_GUI2_LAYEREDITOR_LAYERTREEVIEW_H - -#include "darefl_export.h" -#include <QTreeView> - -namespace gui2 { - -//! Extension of QTreeView for layer editing. - -class DAREFLCORE_EXPORT LayerTreeView : public QTreeView { -public: - using QTreeView::QTreeView; - - explicit LayerTreeView(QWidget* parent = nullptr); - ~LayerTreeView() override; - - void setModel(QAbstractItemModel* model) override; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_LAYEREDITOR_LAYERTREEVIEW_H diff --git a/gui2/layereditor/layerviewmodel.cpp b/gui2/layereditor/layerviewmodel.cpp deleted file mode 100644 index 81bba9a71c8cee4a2a59aaee3a3997d569e8a127..0000000000000000000000000000000000000000 --- a/gui2/layereditor/layerviewmodel.cpp +++ /dev/null @@ -1,27 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/layereditor/layerviewmodel.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/layereditor/layerviewmodel.h" -#include "gui2/layereditor/layerviewmodelcontroller.h" - -using namespace ModelView; - -namespace gui2 { - -LayerViewModel::LayerViewModel(SessionModel* model, QObject* parent) - : ViewModel(std::make_unique<LayerViewModelController>(model, this), parent) -{ -} - -} // namespace gui2 diff --git a/gui2/layereditor/layerviewmodel.h b/gui2/layereditor/layerviewmodel.h deleted file mode 100644 index f787cf4ec8cbde9912e801cb0d42cada52788969..0000000000000000000000000000000000000000 --- a/gui2/layereditor/layerviewmodel.h +++ /dev/null @@ -1,38 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/layereditor/layerviewmodel.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_LAYEREDITOR_LAYERVIEWMODEL_H -#define BORNAGAIN_GUI2_LAYEREDITOR_LAYERVIEWMODEL_H - -#include "darefl_export.h" -#include "mvvm/viewmodel/viewmodel.h" - -namespace ModelView { -class SessionModel; -} // namespace ModelView - -namespace gui2 { - -//! View model to display content of MultiLayerItem in table like views. - -class DAREFLCORE_EXPORT LayerViewModel : public ModelView::ViewModel { - Q_OBJECT - -public: - LayerViewModel(ModelView::SessionModel* model, QObject* parent = nullptr); -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_LAYEREDITOR_LAYERVIEWMODEL_H diff --git a/gui2/layereditor/layerviewmodelcontroller.cpp b/gui2/layereditor/layerviewmodelcontroller.cpp deleted file mode 100644 index 2e84bd4389e7807ef64812c0dc1fcc5d75542932..0000000000000000000000000000000000000000 --- a/gui2/layereditor/layerviewmodelcontroller.cpp +++ /dev/null @@ -1,80 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/layereditor/layerviewmodelcontroller.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/layereditor/layerviewmodelcontroller.h" -#include "gui2/model/sampleitems.h" -#include "mvvm/interfaces/rowstrategyinterface.h" -#include "mvvm/viewmodel/standardchildrenstrategies.h" -#include "mvvm/viewmodel/standardviewitems.h" -#include "mvvm/viewmodel/viewmodel.h" - -using namespace ModelView; - -namespace gui2 { - -//! Custom strategy to form table rows for nested multilayers and layers. - -class CustomLayerRowStrategy : public RowStrategyInterface { -public: - QStringList horizontalHeaderLabels() const - { - return QStringList() << "Name" - << "Nr." - << "Material" - << "Thickness [nm]" - << "Sigma [nm]"; - } - - std::vector<std::unique_ptr<ViewItem>> constructRow(SessionItem* item) - { - std::vector<std::unique_ptr<ViewItem>> result; - - // multilayer row contains its name, repetion and placeholders (instead of material and - // thickness) - if (auto multilayer = dynamic_cast<MultiLayerItem*>(item)) { - result.emplace_back( - std::make_unique<ViewDataItem>(multilayer->getItem(LayerItem::P_NAME))); - // result.push_back(new ViewLabelItem(multilayer)); - result.emplace_back(std::make_unique<ViewDataItem>( - multilayer->getItem(MultiLayerItem::P_NREPETITIONS))); - result.emplace_back(std::make_unique<ViewEmptyItem>()); // instead of P_MATERIAL - result.emplace_back(std::make_unique<ViewEmptyItem>()); // instead of P_THICKNESS - result.emplace_back(std::make_unique<ViewEmptyItem>()); // instead of P_ROUGHNESS - } - - // layer row contains its name, placeholder for repetition, layer material and thickness - if (auto layer = dynamic_cast<LayerItem*>(item)) { - result.emplace_back(std::make_unique<ViewDataItem>(layer->getItem(LayerItem::P_NAME))); - // result.push_back(new ViewLabelItem(layer)); - result.emplace_back(std::make_unique<ViewEmptyItem>()); // instead of P_NREPETITIONS - result.emplace_back( - std::make_unique<ViewDataItem>(layer->getItem(LayerItem::P_MATERIAL))); - result.emplace_back( - std::make_unique<ViewDataItem>(layer->getItem(LayerItem::P_THICKNESS))); - result.emplace_back(std::make_unique<ViewDataItem>( - layer->getItem(LayerItem::P_ROUGHNESS)->getItem(RoughnessItem::P_SIGMA))); - } - - return result; - } -}; - -LayerViewModelController::LayerViewModelController(SessionModel* model, ViewModel* view_model) - : ViewModelController(model, view_model) -{ - setRowStrategy(std::make_unique<CustomLayerRowStrategy>()); - setChildrenStrategy(std::make_unique<TopItemsStrategy>()); -} - -} // namespace gui2 diff --git a/gui2/layereditor/layerviewmodelcontroller.h b/gui2/layereditor/layerviewmodelcontroller.h deleted file mode 100644 index ba2f8e54f39422fb4a0d0320da2395ac575eea3f..0000000000000000000000000000000000000000 --- a/gui2/layereditor/layerviewmodelcontroller.h +++ /dev/null @@ -1,37 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/layereditor/layerviewmodelcontroller.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_LAYEREDITOR_LAYERVIEWMODELCONTROLLER_H -#define BORNAGAIN_GUI2_LAYEREDITOR_LAYERVIEWMODELCONTROLLER_H - -#include "darefl_export.h" -#include "mvvm/viewmodel/viewmodelcontroller.h" - -namespace ModelView { -class ViewModel; -} // namespace ModelView - -namespace gui2 { - -//! Controller for LayerViewModel to show MultiLayerItem in a tree with custom layout. -//! Will iterate through all top level items and creates rows with layer properties. - -class DAREFLCORE_EXPORT LayerViewModelController : public ModelView::ViewModelController { -public: - LayerViewModelController(ModelView::SessionModel* model, ModelView::ViewModel* view_model); -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_LAYEREDITOR_LAYERVIEWMODELCONTROLLER_H diff --git a/gui2/main.cpp b/gui2/main.cpp deleted file mode 100644 index a02e438cf6e6d30e634542d9c5881273949f7100..0000000000000000000000000000000000000000 --- a/gui2/main.cpp +++ /dev/null @@ -1,32 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/main.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/mainwindow/mainwindow.h" -#include <QApplication> -#include <QLocale> - -int main(int argc, char** argv) -{ - QLocale::setDefault(QLocale(QLocale::English, QLocale::UnitedStates)); - - QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); - QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); - - QApplication app(argc, argv); - - gui2::MainWindow win; - win.show(); - - return app.exec(); -} diff --git a/gui2/mainwindow/CMakeLists.txt b/gui2/mainwindow/CMakeLists.txt deleted file mode 100644 index 686de9d1caf4d96ef0c94007e6b3d68793e61fac..0000000000000000000000000000000000000000 --- a/gui2/mainwindow/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -target_sources(${library_name} PRIVATE - actionmanager.cpp - actionmanager.h - fancytab.cpp - fancytab.h - mainbarwidget.cpp - mainbarwidget.h - mainwindow.cpp - mainwindow.h - simulationview.cpp - simulationview.h - styleutils.cpp - styleutils.h -) - diff --git a/gui2/mainwindow/actionmanager.cpp b/gui2/mainwindow/actionmanager.cpp deleted file mode 100644 index 7f203171236a0dd3f7cc1b06b6f01567a7343350..0000000000000000000000000000000000000000 --- a/gui2/mainwindow/actionmanager.cpp +++ /dev/null @@ -1,110 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/mainwindow/actionmanager.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/mainwindow/actionmanager.h" -#include "mvvm/widgets/widgetutils.h" -#include <QAction> -#include <QMainWindow> -#include <QMenuBar> -#include <QToolBar> - -namespace gui2 { - -ActionManager::ActionManager(QMainWindow* mainwindow) - : QObject(mainwindow), m_mainWindow(mainwindow) -{ - createActions(); - setupMenus(m_mainWindow->menuBar()); -} - -void ActionManager::aboutToShowFileMenu() -{ - m_recentProjectMenu->clear(); - m_recentProjectMenu->setEnabled(!m_recentProjects.isEmpty()); - - for (auto project_dir : m_recentProjects) { - auto trimmed_project_dir = ModelView::Utils::WithTildeHomePath(project_dir); - auto action = m_recentProjectMenu->addAction(trimmed_project_dir); - action->setData(QVariant::fromValue(project_dir)); - auto on_project_selected = [this, project_dir]() { - openExistingProjectRequest(project_dir); - }; - connect(action, &QAction::triggered, on_project_selected); - } - - if (!m_recentProjects.empty()) { - m_recentProjectMenu->addSeparator(); - auto action = m_recentProjectMenu->addAction("Clear Menu"); - connect(action, &QAction::triggered, [this]() { clearResentProjectListRequest(); }); - } -} - -void ActionManager::setRecentProjectsList(const QStringList& projects) -{ - m_recentProjects = projects; -} - -//! Creates application-wise actions to create, open, save, and save-as projects. - -void ActionManager::createActions() -{ - m_createNewProjectAction = new QAction("&New Project", this); - m_createNewProjectAction->setShortcuts(QKeySequence::New); - m_createNewProjectAction->setStatusTip("Create a new project"); - connect(m_createNewProjectAction, &QAction::triggered, this, - &ActionManager::createNewProjectRequest); - - m_openExistingProjectAction = new QAction("&Open Project", this); - m_openExistingProjectAction->setShortcuts(QKeySequence::Open); - m_openExistingProjectAction->setStatusTip("Open an existing project"); - connect(m_openExistingProjectAction, &QAction::triggered, - [this]() { openExistingProjectRequest({}); }); - - m_saveCurrentProjectAction = new QAction("&Save Project", this); - m_saveCurrentProjectAction->setShortcuts(QKeySequence::Save); - m_saveCurrentProjectAction->setStatusTip("Save project"); - m_saveCurrentProjectAction->setShortcutContext(Qt::ApplicationShortcut); - connect(m_saveCurrentProjectAction, &QAction::triggered, this, - &ActionManager::saveCurrentProjectRequest); - - m_saveProjectAsAction = new QAction("Save &As...", this); - m_saveProjectAsAction->setShortcuts(QKeySequence::SaveAs); - m_saveProjectAsAction->setStatusTip("Save project under different name"); - connect(m_saveProjectAsAction, &QAction::triggered, this, &ActionManager::saveProjectAsRequest); - - m_exitAction = new QAction("E&xit Application", this); - m_exitAction->setShortcuts(QKeySequence::Quit); - m_exitAction->setStatusTip("Exit the application"); - connect(m_exitAction, &QAction::triggered, m_mainWindow, &QMainWindow::close); -} - -//! Equips menu with actions. - -void ActionManager::setupMenus(QMenuBar* menubar) -{ - auto fileMenu = menubar->addMenu("&File"); - connect(fileMenu, &QMenu::aboutToShow, this, &ActionManager::aboutToShowFileMenu); - fileMenu->addAction(m_createNewProjectAction); - fileMenu->addAction(m_openExistingProjectAction); - m_recentProjectMenu = fileMenu->addMenu("Recent Projects"); - - fileMenu->addSeparator(); - fileMenu->addAction(m_saveCurrentProjectAction); - fileMenu->addAction(m_saveProjectAsAction); - - fileMenu->addSeparator(); - fileMenu->addAction(m_exitAction); -} - -} // namespace gui2 diff --git a/gui2/mainwindow/actionmanager.h b/gui2/mainwindow/actionmanager.h deleted file mode 100644 index bfc19406ba679a25456347ea003a6aa100b0f088..0000000000000000000000000000000000000000 --- a/gui2/mainwindow/actionmanager.h +++ /dev/null @@ -1,69 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/mainwindow/actionmanager.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_MAINWINDOW_ACTIONMANAGER_H -#define BORNAGAIN_GUI2_MAINWINDOW_ACTIONMANAGER_H - -#include "darefl_export.h" -#include <QObject> - -class QMainWindow; -class QAction; -class QMenuBar; -class QMenu; - -namespace gui2 { - -//! Actions for MainWindow. Equips toolbar and menubar with actions to create, open, save, -//! and save-as projects. It doesn't have logic and simply forwards requests further. - -class DAREFLCORE_EXPORT ActionManager : public QObject { - Q_OBJECT - -public: - ActionManager(QMainWindow* mainwindow = nullptr); - -signals: - void createNewProjectRequest(); - void openExistingProjectRequest(const QString& dirname); - void saveCurrentProjectRequest(); - void saveProjectAsRequest(); - void clearResentProjectListRequest(); - -public slots: - void setRecentProjectsList(const QStringList& projects); - -private slots: - void aboutToShowFileMenu(); - -private: - void createActions(); - void setupMenus(QMenuBar* menubar); - - QMainWindow* m_mainWindow{nullptr}; - - QAction* m_createNewProjectAction{nullptr}; - QAction* m_openExistingProjectAction{nullptr}; - QAction* m_saveCurrentProjectAction{nullptr}; - QAction* m_saveProjectAsAction{nullptr}; - QAction* m_exitAction{nullptr}; - - QMenu* m_recentProjectMenu{nullptr}; - - QStringList m_recentProjects; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_MAINWINDOW_ACTIONMANAGER_H diff --git a/gui2/mainwindow/fancytab.cpp b/gui2/mainwindow/fancytab.cpp deleted file mode 100644 index e8aabba5bd675833de017d9f0abe377625f5b5a5..0000000000000000000000000000000000000000 --- a/gui2/mainwindow/fancytab.cpp +++ /dev/null @@ -1,84 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/mainwindow/fancytab.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/mainwindow/fancytab.h" -#include "mvvm/widgets/widgetutils.h" -#include <QHBoxLayout> -#include <QLabel> -#include <QMouseEvent> -#include <QPainter> - -namespace { -QColor defaultColor() -{ - static QWidget tmpWidget; - return tmpWidget.palette().color(QPalette::Window); -} -} // namespace - -namespace gui2 { - -FancyTab::FancyTab(const QString& title, QWidget* parent) - : QWidget(parent), m_label(new QLabel(title)) -{ - ModelView::Utils::ScaleLabelFont(m_label, 1.25); - setFixedHeight(ModelView::Utils::HeightOfLetterM() * 2.5); - - auto layout = new QHBoxLayout(this); - layout->setContentsMargins(0, 0, 0, 0); - - layout->addWidget(m_label, 0, Qt::AlignCenter); - setMouseTracking(true); -} - -void FancyTab::setSelected(bool value) -{ - m_isSelected = value; - update(); -} - -void FancyTab::paintEvent(QPaintEvent*) -{ - QPainter painter(this); - - if (m_widgetColor.isValid()) - painter.fillRect(0, 0, size().width(), size().height(), m_widgetColor); - - if (m_isSelected && isEnabled()) - painter.fillRect( - QRectF(QPointF(0, size().height() - 2), QPointF(size().width(), size().height())), - QColor("#0d4283")); -} - -void FancyTab::mousePressEvent(QMouseEvent* event) -{ - if (isEnabled() && event->button() == Qt::LeftButton) - clicked(); -} - -void FancyTab::enterEvent(QEvent*) -{ - if (isEnabled()) - m_widgetColor = QColor(Qt::lightGray); - update(); -} - -void FancyTab::leaveEvent(QEvent*) -{ - if (isEnabled()) - m_widgetColor = defaultColor(); - update(); -} - -} // namespace gui2 diff --git a/gui2/mainwindow/fancytab.h b/gui2/mainwindow/fancytab.h deleted file mode 100644 index e9b5f8325dbea313afbc8b008897ed5d79a99203..0000000000000000000000000000000000000000 --- a/gui2/mainwindow/fancytab.h +++ /dev/null @@ -1,52 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/mainwindow/fancytab.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_MAINWINDOW_FANCYTAB_H -#define BORNAGAIN_GUI2_MAINWINDOW_FANCYTAB_H - -#include "darefl_export.h" -#include <QColor> -#include <QWidget> - -class QLabel; -class QString; - -namespace gui2 { - -class DAREFLCORE_EXPORT FancyTab : public QWidget { - Q_OBJECT - -public: - FancyTab(const QString& title, QWidget* parent = nullptr); - - void setSelected(bool value); - -signals: - void clicked(); - -protected: - void paintEvent(QPaintEvent*) override; - void mousePressEvent(QMouseEvent* event) override; - void enterEvent(QEvent*) override; - void leaveEvent(QEvent*) override; - -private: - QLabel* m_label{nullptr}; - bool m_isSelected{false}; - QColor m_widgetColor; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_MAINWINDOW_FANCYTAB_H diff --git a/gui2/mainwindow/mainbarwidget.cpp b/gui2/mainwindow/mainbarwidget.cpp deleted file mode 100644 index e75f790a433627a827a5a3fa57da0fb00c3f5a1b..0000000000000000000000000000000000000000 --- a/gui2/mainwindow/mainbarwidget.cpp +++ /dev/null @@ -1,59 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/mainwindow/mainbarwidget.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/mainwindow/mainbarwidget.h" -#include "gui2/mainwindow/fancytab.h" -#include <QHBoxLayout> -#include <QLabel> -#include <QPushButton> -#include <QStackedWidget> -#include <QVBoxLayout> - -namespace gui2 { - -MainBarWidget::MainBarWidget(QWidget* parent) - : QWidget(parent), m_stackedWidget(new QStackedWidget), m_labelLayout(new QHBoxLayout) -{ - m_labelLayout->setContentsMargins(0, 0, 0, 0); - - auto layout = new QVBoxLayout(this); - layout->addLayout(m_labelLayout); - layout->addWidget(m_stackedWidget); - layout->setContentsMargins(0, 0, 0, 0); -} - -MainBarWidget::~MainBarWidget() = default; - -void MainBarWidget::addWidget(QWidget* widget, const QString& title, bool is_enabled) -{ - int index = m_stackedWidget->addWidget(widget); - - auto tab = new FancyTab(title); - tab->setEnabled(is_enabled); - auto on_tab_clicked = [this, index]() { setCurrentIndex(index); }; - connect(tab, &FancyTab::clicked, on_tab_clicked); - - m_indexToTab[index] = tab; - m_labelLayout->addWidget(tab); -} - -void MainBarWidget::setCurrentIndex(int index) -{ - for (auto it : m_indexToTab) - it.second->setSelected(it.first == index); - - m_stackedWidget->setCurrentIndex(index); -} - -} // namespace gui2 diff --git a/gui2/mainwindow/mainbarwidget.h b/gui2/mainwindow/mainbarwidget.h deleted file mode 100644 index 2b6c082e08cccdba81447b8d140b80d773584155..0000000000000000000000000000000000000000 --- a/gui2/mainwindow/mainbarwidget.h +++ /dev/null @@ -1,52 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/mainwindow/mainbarwidget.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_MAINWINDOW_MAINBARWIDGET_H -#define BORNAGAIN_GUI2_MAINWINDOW_MAINBARWIDGET_H - -#include "darefl_export.h" -#include <QWidget> -#include <map> - -class QStackedWidget; -class QHBoxLayout; -class QPushButton; - -namespace gui2 { - -class FancyTab; - -//! Widget container with functionality similar to QTabWidget. Has large button bar on top, -//! and stacked widget at bottom. - -class DAREFLCORE_EXPORT MainBarWidget : public QWidget { - Q_OBJECT - -public: - MainBarWidget(QWidget* parent = nullptr); - ~MainBarWidget(); - - void addWidget(QWidget* widget, const QString& title, bool is_enabled = true); - - void setCurrentIndex(int index); - -private: - QStackedWidget* m_stackedWidget{nullptr}; - QHBoxLayout* m_labelLayout{nullptr}; - std::map<int, FancyTab*> m_indexToTab; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_MAINWINDOW_MAINBARWIDGET_H diff --git a/gui2/mainwindow/mainwindow.cpp b/gui2/mainwindow/mainwindow.cpp deleted file mode 100644 index 272176f4215c6c0e664fa3e0420869a34c1826de..0000000000000000000000000000000000000000 --- a/gui2/mainwindow/mainwindow.cpp +++ /dev/null @@ -1,122 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/mainwindow/mainwindow.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/mainwindow/mainwindow.h" -#include "BAVersion.h" -#include "gui2/importdataview/importdataview.h" -#include "gui2/mainwindow/actionmanager.h" -#include "gui2/mainwindow/mainbarwidget.h" -#include "gui2/mainwindow/simulationview.h" -#include "gui2/model/applicationmodels.h" -#include "gui2/settingsview/settingsview.h" -#include "gui2/welcomeview/welcomeview.h" -#include <QCloseEvent> -#include <QCoreApplication> -#include <QFileDialog> -#include <QMenuBar> -#include <QSettings> - -namespace { -const QString main_window_group = "MainWindow"; -const QString size_key = "size"; -const QString pos_key = "pos"; -} // namespace - -namespace gui2 { - -MainWindow::MainWindow() - : m_models(std::make_unique<ApplicationModels>()), m_actionManager(new ActionManager(this)) -{ - init_application(); - init_components(); - init_connections(); - setCentralWidget(m_barWidget); -} - -MainWindow::~MainWindow() = default; - -void MainWindow::closeEvent(QCloseEvent* event) -{ - if (m_welcomeView->canCloseProject()) { - write_settings(); - event->accept(); - } else { - event->ignore(); - } -} - -void MainWindow::init_application() -{ - QCoreApplication::setApplicationName("BornAgain gui2 preview"); - QCoreApplication::setApplicationVersion(QString::fromStdString(BornAgain::GetVersionNumber())); - QCoreApplication::setOrganizationName("BornAgain"); - - QSettings settings; - if (settings.childGroups().contains(main_window_group)) { - settings.beginGroup(main_window_group); - resize(settings.value(size_key, QSize(400, 400)).toSize()); - move(settings.value(pos_key, QPoint(200, 200)).toPoint()); - settings.endGroup(); - } -} - -void MainWindow::init_components() -{ - m_welcomeView = new WelcomeView(m_models.get()); - m_importDataView = new ImportDataView(m_models.get()); - m_simView = new SimulationView(m_models.get()); - m_settingsView = new SettingsView(m_models.get()); - m_barWidget = new MainBarWidget; - - m_barWidget->addWidget(m_welcomeView, "Project"); - m_barWidget->addWidget(m_importDataView, "Data"); - m_barWidget->addWidget(m_simView, "Simulation"); - m_barWidget->addWidget(new QWidget, "Fitting", false); - m_barWidget->addWidget(new QWidget, "Export", false); - m_barWidget->addWidget(m_settingsView, "Settings"); - m_barWidget->setCurrentIndex(0); -} - -//! Setup main connections. - -void MainWindow::init_connections() -{ - // connect ActionManager signals with WelcomeView slots - connect(m_actionManager, &ActionManager::createNewProjectRequest, m_welcomeView, - &WelcomeView::onCreateNewProject); - connect(m_actionManager, &ActionManager::openExistingProjectRequest, m_welcomeView, - &WelcomeView::onOpenExistingProject); - connect(m_actionManager, &ActionManager::saveCurrentProjectRequest, m_welcomeView, - &WelcomeView::onSaveCurrentProject); - connect(m_actionManager, &ActionManager::saveProjectAsRequest, m_welcomeView, - &WelcomeView::onSaveProjectAs); - connect(m_actionManager, &ActionManager::clearResentProjectListRequest, m_welcomeView, - &WelcomeView::onClearRecentProjectsList); - - connect(m_welcomeView, &WelcomeView::recentProjectsListModified, m_actionManager, - &ActionManager::setRecentProjectsList); - - m_welcomeView->updateNames(); -} - -void MainWindow::write_settings() -{ - QSettings settings; - settings.beginGroup(main_window_group); - settings.setValue(size_key, size()); - settings.setValue(pos_key, pos()); - settings.endGroup(); -} - -} // namespace gui2 diff --git a/gui2/mainwindow/mainwindow.h b/gui2/mainwindow/mainwindow.h deleted file mode 100644 index c86fd27a4f7309b54bcf449739696bc6a17d34f7..0000000000000000000000000000000000000000 --- a/gui2/mainwindow/mainwindow.h +++ /dev/null @@ -1,61 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/mainwindow/mainwindow.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_MAINWINDOW_MAINWINDOW_H -#define BORNAGAIN_GUI2_MAINWINDOW_MAINWINDOW_H - -#include "darefl_export.h" -#include <QMainWindow> -#include <memory> - -namespace gui2 { - -class WelcomeView; -class ImportDataView; -class SimulationView; -class MainBarWidget; -class ApplicationModels; -class ActionManager; -class SettingsView; - -//! Application main window. - -class DAREFLCORE_EXPORT MainWindow : public QMainWindow { - Q_OBJECT - -public: - MainWindow(); - ~MainWindow(); - -protected: - void closeEvent(QCloseEvent* event); - -private: - void init_application(); - void init_components(); - void init_connections(); - void write_settings(); - - std::unique_ptr<ApplicationModels> m_models; - ActionManager* m_actionManager{nullptr}; - WelcomeView* m_welcomeView{nullptr}; - ImportDataView* m_importDataView{nullptr}; - SimulationView* m_simView{nullptr}; - SettingsView* m_settingsView{nullptr}; - MainBarWidget* m_barWidget{nullptr}; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_MAINWINDOW_MAINWINDOW_H diff --git a/gui2/mainwindow/simulationview.cpp b/gui2/mainwindow/simulationview.cpp deleted file mode 100644 index 82f05023ff34242be92c70db02b539a1f9674ea0..0000000000000000000000000000000000000000 --- a/gui2/mainwindow/simulationview.cpp +++ /dev/null @@ -1,65 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/mainwindow/simulationview.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/mainwindow/simulationview.h" -#include "gui2/layereditor/layereditor.h" -#include "gui2/materialeditor/materialeditor.h" -#include "gui2/quicksimeditor/instrumentpropertyeditor.h" -#include "gui2/quicksimeditor/quicksimeditor.h" -#include "gui2/sldeditor/sldeditor.h" -#include "mvvm/widgets/collapsiblelistwidget.h" -#include <QSplitter> -#include <QVBoxLayout> - -using namespace ModelView; - -namespace gui2 { - -SimulationView::SimulationView(ApplicationModels* models, QWidget* parent) - : QMainWindow(parent) - , m_editorList(new CollapsibleListWidget) - , m_simEditor(new QuickSimEditor) - , m_models(models) -{ - auto splitter = new QSplitter; - - initEditorList(); - - splitter->addWidget(m_editorList); - splitter->addWidget(m_simEditor); - - setCentralWidget(splitter); -} - -void SimulationView::initEditorList() -{ - m_editorList->layout()->setContentsMargins(4, 4, 4, 4); - auto material_editor = new MaterialEditor(this); - auto layer_editor = new LayerEditor(this); - auto sld_editor = new SLDEditor(this); - auto instrument_editor = new InstrumentPropertyEditor(this); - - m_editorList->addWidget(material_editor, "Material editor"); - m_editorList->addWidget(layer_editor, "Layer editor", /*set_collapsed*/ true); - m_editorList->addWidget(instrument_editor, "Instrument editor", /*set_collapsed*/ true); - m_editorList->addWidget(sld_editor, "SLD editor", /*set_collapsed*/ true); - - material_editor->setModels(m_models); - layer_editor->setModels(m_models); - sld_editor->setModels(m_models); - m_simEditor->setModels(m_models); - instrument_editor->setModels(m_models); -} - -} // namespace gui2 diff --git a/gui2/mainwindow/simulationview.h b/gui2/mainwindow/simulationview.h deleted file mode 100644 index 0daf2048d8d2ebe0f3c65e818422e62237d4aa87..0000000000000000000000000000000000000000 --- a/gui2/mainwindow/simulationview.h +++ /dev/null @@ -1,49 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/mainwindow/simulationview.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_MAINWINDOW_SIMULATIONVIEW_H -#define BORNAGAIN_GUI2_MAINWINDOW_SIMULATIONVIEW_H - -#include "darefl_export.h" -#include <QMainWindow> -#include <memory> - -namespace ModelView { -class CollapsibleListWidget; -} - -namespace gui2 { - -class ApplicationModels; -class QuickSimEditor; - -//! Main simulation window with all components for quick sample editing and simulations. - -class DAREFLCORE_EXPORT SimulationView : public QMainWindow { - Q_OBJECT - -public: - SimulationView(ApplicationModels* models, QWidget* parent = nullptr); - -private: - void initEditorList(); - - ModelView::CollapsibleListWidget* m_editorList{nullptr}; - QuickSimEditor* m_simEditor{nullptr}; - ApplicationModels* m_models{nullptr}; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_MAINWINDOW_SIMULATIONVIEW_H diff --git a/gui2/mainwindow/styleutils.cpp b/gui2/mainwindow/styleutils.cpp deleted file mode 100644 index b623439ad6543c755a69e3f876dc46779466ca1c..0000000000000000000000000000000000000000 --- a/gui2/mainwindow/styleutils.cpp +++ /dev/null @@ -1,46 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/mainwindow/styleutils.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/mainwindow/styleutils.h" -#include "gui2/resources/resources.h" -#include <QFontMetrics> -#include <QSize> -#include <QToolBar> -#include <QWidget> - -namespace gui2 { - -QSize GUI::Utils::Style::ToolBarIconSize() -{ - return QSize(24, 24); -} - -QSize GUI::Utils::Style::DockSizeHint() -{ - return QSize(480, 360); -} - -QSize GUI::Utils::Style::DockMinimumSizeHint() -{ - return QSize(320, 240); -} - -void GUI::Utils::Style::SetToolBarStyleTextBesides(QToolBar* toolbar) -{ - InitIconResources(); - toolbar->setIconSize(GUI::Utils::Style::ToolBarIconSize()); - toolbar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); -} - -} // namespace gui2 diff --git a/gui2/mainwindow/styleutils.h b/gui2/mainwindow/styleutils.h deleted file mode 100644 index 46cd0558141f7f9731f2decdee74c20164d66538..0000000000000000000000000000000000000000 --- a/gui2/mainwindow/styleutils.h +++ /dev/null @@ -1,46 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/mainwindow/styleutils.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_MAINWINDOW_STYLEUTILS_H -#define BORNAGAIN_GUI2_MAINWINDOW_STYLEUTILS_H - -#include "darefl_export.h" - -class QSize; -class QFont; -class QToolBar; - -namespace gui2 { - -//! Namespace for central access to all theme styling. - -namespace GUI::Utils::Style { - -//! Size of tolbar icons for LayerEditor, MaterialEditor and similar. -DAREFLCORE_EXPORT QSize ToolBarIconSize(); - -//! Hint on size of docks on main reflectometry window. -DAREFLCORE_EXPORT QSize DockSizeHint(); - -//! Hint on minimum size of docks on main reflectometry window. -DAREFLCORE_EXPORT QSize DockMinimumSizeHint(); - -//! Set common style for a toolbar. -DAREFLCORE_EXPORT void SetToolBarStyleTextBesides(QToolBar* toolbar); - -}; // namespace GUI::Utils::Style - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_MAINWINDOW_STYLEUTILS_H diff --git a/gui2/materialeditor/CMakeLists.txt b/gui2/materialeditor/CMakeLists.txt deleted file mode 100644 index 60371de52cd2dae8d76dc0bc7475a484ed46d4fd..0000000000000000000000000000000000000000 --- a/gui2/materialeditor/CMakeLists.txt +++ /dev/null @@ -1,16 +0,0 @@ -target_sources(${library_name} PRIVATE - materialeditor.cpp - materialeditor.h - materialeditoractions.cpp - materialeditoractions.h - materialeditortoolbar.cpp - materialeditortoolbar.h - materialeditorwidget.cpp - materialeditorwidget.h - materialselectionmodel.cpp - materialselectionmodel.h - materialtableview.cpp - materialtableview.h - materialtreeview.cpp - materialtreeview.h -) diff --git a/gui2/materialeditor/materialeditor.cpp b/gui2/materialeditor/materialeditor.cpp deleted file mode 100644 index b26a7a8b4e529de5ae68119c6f11d8557c7040b0..0000000000000000000000000000000000000000 --- a/gui2/materialeditor/materialeditor.cpp +++ /dev/null @@ -1,61 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/materialeditor/materialeditor.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/materialeditor/materialeditor.h" -#include "gui2/mainwindow/styleutils.h" -#include "gui2/materialeditor/materialeditoractions.h" -#include "gui2/materialeditor/materialeditortoolbar.h" -#include "gui2/materialeditor/materialeditorwidget.h" -#include "gui2/model/applicationmodels.h" -#include "gui2/model/materialmodel.h" -#include <QVBoxLayout> - -namespace gui2 { - -MaterialEditor::MaterialEditor(QWidget* parent) - : QWidget(parent) - , m_actions(new MaterialEditorActions(this)) - , m_editorWidget(new MaterialEditorWidget) - , m_toolBar(new MaterialEditorToolBar(m_actions)) -{ - setWindowTitle("Material editor"); - auto layout = new QVBoxLayout; - layout->addWidget(m_toolBar); - layout->addWidget(m_editorWidget); - setLayout(layout); - layout->setContentsMargins(0, 0, 0, 0); - layout->setSpacing(0); -} - -//! Set the mododel for the different items -void MaterialEditor::setModels(ApplicationModels* models) -{ - m_editorWidget->setModels(models); - m_actions->setModel(models->materialModel()); - m_actions->setMaterialSelectionModel(m_editorWidget->selectionModel()); -} - -QSize MaterialEditor::sizeHint() const -{ - return GUI::Utils::Style::DockSizeHint(); -} - -QSize MaterialEditor::minimumSizeHint() const -{ - return GUI::Utils::Style::DockMinimumSizeHint(); -} - -MaterialEditor::~MaterialEditor() = default; - -} // namespace gui2 diff --git a/gui2/materialeditor/materialeditor.h b/gui2/materialeditor/materialeditor.h deleted file mode 100644 index 9dda6f932f37817bf258977b4c5b659f9b205469..0000000000000000000000000000000000000000 --- a/gui2/materialeditor/materialeditor.h +++ /dev/null @@ -1,50 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/materialeditor/materialeditor.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_MATERIALEDITOR_MATERIALEDITOR_H -#define BORNAGAIN_GUI2_MATERIALEDITOR_MATERIALEDITOR_H - -#include "darefl_export.h" -#include <QWidget> - -namespace gui2 { - -class ApplicationModels; -class MaterialEditorActions; -class MaterialEditorToolBar; -class MaterialEditorWidget; - -//! Material editor. - -class DAREFLCORE_EXPORT MaterialEditor : public QWidget { - Q_OBJECT - -public: - MaterialEditor(QWidget* parent = nullptr); - ~MaterialEditor(); - - void setModels(ApplicationModels* models); - - QSize sizeHint() const override; - QSize minimumSizeHint() const override; - -private: - MaterialEditorActions* m_actions{nullptr}; - MaterialEditorWidget* m_editorWidget{nullptr}; - MaterialEditorToolBar* m_toolBar{nullptr}; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_MATERIALEDITOR_MATERIALEDITOR_H diff --git a/gui2/materialeditor/materialeditoractions.cpp b/gui2/materialeditor/materialeditoractions.cpp deleted file mode 100644 index 59ff450438aca0b4344f8cc09ba6604404ca4f0c..0000000000000000000000000000000000000000 --- a/gui2/materialeditor/materialeditoractions.cpp +++ /dev/null @@ -1,180 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/materialeditor/materialeditoractions.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/materialeditor/materialeditoractions.h" -#include "gui2/materialeditor/materialselectionmodel.h" -#include "gui2/model/materialitems.h" -#include "gui2/model/materialmodel.h" -#include "mvvm/model/modelutils.h" -#include "mvvm/model/sessionitemdata.h" -#include "mvvm/viewmodel/viewmodel.h" -#include <QFile> -#include <QTextStream> - -using namespace ModelView; - -namespace gui2 { - -struct MaterialEditorActions::MaterialEditorActionsImpl { - MaterialModel* material_model{nullptr}; - MaterialSelectionModel* selection_model{nullptr}; - MaterialEditorActionsImpl() {} - - //! Finds parent and tagrow to insert new item - - std::pair<SessionItem*, TagRow> locateInsertPlace() - { - auto all_selected = selection_model->selectedMaterials(); - auto selected = all_selected.empty() ? nullptr : all_selected.back(); - if (selected) - return {selected->parent(), selected->tagRow().next()}; - return {root_item(), TagRow{}}; - } - - //! Returns a multi layer playing the role of invisible root item. - - ModelView::SessionItem* root_item() - { - return selection_model->viewModel()->sessionItemFromIndex(QModelIndex()); - } -}; - -MaterialEditorActions::MaterialEditorActions(QObject* parent) - : QObject(parent), p_impl(std::make_unique<MaterialEditorActionsImpl>()) -{ -} - -void MaterialEditorActions::setModel(MaterialModel* model) -{ - p_impl->material_model = model; -} - -void MaterialEditorActions::setMaterialSelectionModel(MaterialSelectionModel* selection_model) -{ - p_impl->selection_model = selection_model; -} - -void MaterialEditorActions::onAddMaterial() -{ - if (!p_impl->material_model) - return; - - auto [parent, tagrow] = p_impl->locateInsertPlace(); - auto material = p_impl->material_model->addDefaultMaterial(tagrow); - p_impl->selection_model->selectItem(material); -} - -//! Processes request to clone selected materials. - -void MaterialEditorActions::onCloneMaterial() -{ - if (!p_impl->material_model) - return; - - std::vector<ModelView::SessionItem*> new_selection; - for (const auto item : p_impl->selection_model->selectedMaterials()) - new_selection.push_back(p_impl->material_model->cloneMaterial(item)); - p_impl->selection_model->selectItems(new_selection); -} - -void MaterialEditorActions::onRemoveMaterial() -{ - if (!p_impl->selection_model) - return; - - for (auto item : p_impl->selection_model->selectedMaterials()) - ModelView::Utils::DeleteItemFromModel(item); -} - -void MaterialEditorActions::onMoveUp() -{ - if (!p_impl->selection_model) - return; - - for (auto item : p_impl->selection_model->selectedMaterials()) - ModelView::Utils::MoveUp(item); -} - -void MaterialEditorActions::onMoveDown() -{ - if (!p_impl->selection_model) - return; - - auto items = p_impl->selection_model->selectedMaterials(); - std::reverse(items.begin(), items.end()); // to correctly move multiple selections - for (auto item : p_impl->selection_model->selectedMaterials()) - ModelView::Utils::MoveDown(item); -} - -void MaterialEditorActions::onExport() -{ - auto item = p_impl->root_item(); - const auto containers = item->children(); - - bool title = true; // print title only once in ascii file - QString tableData; - QString titleData; - - for (auto container : containers) { - auto data = container->modelType(); - for (auto fields : dynamic_cast<MaterialBaseItem*>(container)->children()) { - if (title) { - titleData += (fields->displayName()).c_str(); - titleData += " "; - } - auto val = fields->data<QVariant>(1); // role 1 has the values. - if (strcmp(val.typeName(), "std::string") == 0) { - tableData += val.value<std::string>().c_str(); - tableData += " "; - } else if (strcmp(val.typeName(), "int") == 0) { - auto int_val = val.value<int>(); - tableData += QString::number(int_val); - tableData += " "; - } else if (strcmp(val.typeName(), "double") == 0) { - auto double_val = val.value<double>(); - tableData += QString::number(double_val); - tableData += " "; - } else if (strcmp(val.typeName(), "float") == 0) { - auto float_val = val.value<float>(); - tableData += QString::number(float_val); - tableData += " "; - } else { - auto color_str = val.toString(); - tableData += color_str; - tableData += " "; - } - } - if (title) { - titleData += "\n"; - tableData = titleData + tableData; - } - title = false; - tableData += "\n"; - } - /*for text file*/ - QFile txtFile("materialdata"); - if (txtFile.open(QIODevice::WriteOnly)) { - - QTextStream out(&txtFile); - out << tableData; - - txtFile.close(); - } -} - -void MaterialEditorActions::onImport() {} - -MaterialEditorActions::~MaterialEditorActions() = default; - -} // namespace gui2 diff --git a/gui2/materialeditor/materialeditoractions.h b/gui2/materialeditor/materialeditoractions.h deleted file mode 100644 index 151ceaeab2b5884863548f904782aa56ebd073db..0000000000000000000000000000000000000000 --- a/gui2/materialeditor/materialeditoractions.h +++ /dev/null @@ -1,56 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/materialeditor/materialeditoractions.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_MATERIALEDITOR_MATERIALEDITORACTIONS_H -#define BORNAGAIN_GUI2_MATERIALEDITOR_MATERIALEDITORACTIONS_H - -#include "darefl_export.h" -#include <QObject> -#include <memory> - -namespace gui2 { - -class MaterialModel; -class MaterialSelectionModel; - -//! Handles user actions applied to material table. -//! Belongs to MaterialEditor. - -class DAREFLCORE_EXPORT MaterialEditorActions : public QObject { - Q_OBJECT - -public: - MaterialEditorActions(QObject* parent = nullptr); - ~MaterialEditorActions(); - - void setModel(MaterialModel* model); - - void onAddMaterial(); - void onCloneMaterial(); - void onRemoveMaterial(); - void onMoveUp(); - void onMoveDown(); - void onExport(); - void onImport(); - - void setMaterialSelectionModel(MaterialSelectionModel* selection_model); - -private: - struct MaterialEditorActionsImpl; - std::unique_ptr<MaterialEditorActionsImpl> p_impl; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_MATERIALEDITOR_MATERIALEDITORACTIONS_H diff --git a/gui2/materialeditor/materialeditortoolbar.cpp b/gui2/materialeditor/materialeditortoolbar.cpp deleted file mode 100644 index e0ad2ff50b85ea0b14f80591a4e8a49d2065b289..0000000000000000000000000000000000000000 --- a/gui2/materialeditor/materialeditortoolbar.cpp +++ /dev/null @@ -1,75 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/materialeditor/materialeditortoolbar.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/materialeditor/materialeditortoolbar.h" -#include "gui2/mainwindow/styleutils.h" -#include "gui2/materialeditor/materialeditoractions.h" -#include <QAction> -#include <QToolButton> - -namespace gui2 { - -MaterialEditorToolBar::MaterialEditorToolBar(MaterialEditorActions* actions, QWidget* parent) - : QToolBar(parent) -{ - GUI::Utils::Style::SetToolBarStyleTextBesides(this); - - auto action = new QAction("Add material", this); - action->setIcon(QIcon(":/icons/plus-circle-outline.svg")); - action->setToolTip("Adds new material at the bottom of the list"); - connect(action, &QAction::triggered, actions, &MaterialEditorActions::onAddMaterial); - addAction(action); - - action = new QAction("Clone", this); - action->setIcon(QIcon(":/icons/plus-circle-multiple-outline.svg")); - action->setToolTip("Clones selected material"); - connect(action, &QAction::triggered, actions, &MaterialEditorActions::onCloneMaterial); - addAction(action); - - action = new QAction("Remove", this); - action->setIcon(QIcon(":/icons/beaker-remove-outline.svg")); - action->setToolTip("Removes selected material"); - connect(action, &QAction::triggered, actions, &MaterialEditorActions::onRemoveMaterial); - addAction(action); - - addSeparator(); - - action = new QAction("Up", this); - action->setIcon(QIcon(":/icons/arrow-up-circle-outline.svg")); - action->setToolTip("Moves selected material up"); - connect(action, &QAction::triggered, actions, &MaterialEditorActions::onMoveUp); - addAction(action); - - action = new QAction("Down", this); - action->setIcon(QIcon(":/icons/arrow-down-circle-outline.svg")); - action->setToolTip("Moves selected material down"); - connect(action, &QAction::triggered, actions, &MaterialEditorActions::onMoveDown); - addAction(action); - - addSeparator(); - - action = new QAction("Import", this); - action->setIcon(QIcon(":/icons/import.svg")); - action->setToolTip("Imports materials from file"); - connect(action, &QAction::triggered, actions, &MaterialEditorActions::onImport); - addAction(action); - - action = new QAction("Export", this); - action->setIcon(QIcon(":/icons/export.svg")); - action->setToolTip("Exports materials to file"); - connect(action, &QAction::triggered, actions, &MaterialEditorActions::onExport); - addAction(action); -} - -} // namespace gui2 diff --git a/gui2/materialeditor/materialeditortoolbar.h b/gui2/materialeditor/materialeditortoolbar.h deleted file mode 100644 index 201f66441fd44056566aedd2955b842cb473d80c..0000000000000000000000000000000000000000 --- a/gui2/materialeditor/materialeditortoolbar.h +++ /dev/null @@ -1,37 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/materialeditor/materialeditortoolbar.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_MATERIALEDITOR_MATERIALEDITORTOOLBAR_H -#define BORNAGAIN_GUI2_MATERIALEDITOR_MATERIALEDITORTOOLBAR_H - -#include "darefl_export.h" -#include <QToolBar> - -namespace gui2 { - -class MaterialEditorActions; - -//! Material editor toolbar. - -class DAREFLCORE_EXPORT MaterialEditorToolBar : public QToolBar { - Q_OBJECT - -public: - MaterialEditorToolBar(MaterialEditorActions* actions, QWidget* parent = nullptr); - ~MaterialEditorToolBar() = default; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_MATERIALEDITOR_MATERIALEDITORTOOLBAR_H diff --git a/gui2/materialeditor/materialeditorwidget.cpp b/gui2/materialeditor/materialeditorwidget.cpp deleted file mode 100644 index 210414960816bf824d80e5a471b19ac8cacca949..0000000000000000000000000000000000000000 --- a/gui2/materialeditor/materialeditorwidget.cpp +++ /dev/null @@ -1,59 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/materialeditor/materialeditorwidget.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/materialeditor/materialeditorwidget.h" -#include "gui2/materialeditor/materialselectionmodel.h" -#include "gui2/materialeditor/materialtableview.h" -#include "gui2/materialeditor/materialtreeview.h" -#include "gui2/model/applicationmodels.h" -#include "gui2/model/materialitems.h" -#include "gui2/model/materialmodel.h" -#include "mvvm/factories/viewmodelfactory.h" -#include "mvvm/model/modelutils.h" -#include "mvvm/viewmodel/viewmodeldelegate.h" -#include <QVBoxLayout> - -namespace gui2 { - -MaterialEditorWidget::MaterialEditorWidget(QWidget* parent) - : QWidget(parent) - , m_materialView(new MaterialTreeView) - , m_delegate(std::make_unique<ModelView::ViewModelDelegate>()) -{ - auto layout = new QVBoxLayout; - layout->setContentsMargins(0, 0, 0, 0); - layout->addWidget(m_materialView); - setLayout(layout); - m_materialView->setItemDelegate(m_delegate.get()); -} - -MaterialEditorWidget::~MaterialEditorWidget() = default; - -void MaterialEditorWidget::setModels(ApplicationModels* models) -{ - m_materialModel = models->materialModel(); - m_viewModel = ModelView::Factory::CreatePropertyTableViewModel(m_materialModel); - m_selectionModel = new MaterialSelectionModel(m_viewModel.get(), this); - m_viewModel->setRootSessionItem( - ModelView::Utils::TopItem<MaterialContainerItem>(m_materialModel)); - m_materialView->setModel(m_viewModel.get()); - m_materialView->setSelectionModel(m_selectionModel); -} - -MaterialSelectionModel* MaterialEditorWidget::selectionModel() const -{ - return m_selectionModel; -} - -} // namespace gui2 diff --git a/gui2/materialeditor/materialeditorwidget.h b/gui2/materialeditor/materialeditorwidget.h deleted file mode 100644 index 6ec8302c2c46acfd9fb15f094496841c949da6b9..0000000000000000000000000000000000000000 --- a/gui2/materialeditor/materialeditorwidget.h +++ /dev/null @@ -1,59 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/materialeditor/materialeditorwidget.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_MATERIALEDITOR_MATERIALEDITORWIDGET_H -#define BORNAGAIN_GUI2_MATERIALEDITOR_MATERIALEDITORWIDGET_H - -#include "darefl_export.h" -#include <QWidget> -#include <memory> - -namespace ModelView { -class ViewModel; -class ViewModelDelegate; -} // namespace ModelView - -namespace gui2 { - -class ApplicationModels; -class MaterialModel; -class MaterialTableView; -class MaterialTreeView; -class MaterialSelectionModel; - -//! Widget to hold material table (MaterialTreeView) and all corresponding models and delegates. -//! Belongs to MaterialEditor. - -class DAREFLCORE_EXPORT MaterialEditorWidget : public QWidget { - Q_OBJECT - -public: - MaterialEditorWidget(QWidget* parent = nullptr); - ~MaterialEditorWidget(); - - void setModels(ApplicationModels* models); - - MaterialSelectionModel* selectionModel() const; - -private: - MaterialModel* m_materialModel{nullptr}; - std::unique_ptr<ModelView::ViewModel> m_viewModel; - MaterialSelectionModel* m_selectionModel{nullptr}; - MaterialTreeView* m_materialView{nullptr}; - std::unique_ptr<ModelView::ViewModelDelegate> m_delegate; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_MATERIALEDITOR_MATERIALEDITORWIDGET_H diff --git a/gui2/materialeditor/materialselectionmodel.cpp b/gui2/materialeditor/materialselectionmodel.cpp deleted file mode 100644 index 6095cbfe49220cb3e598727461979a4151d4beb4..0000000000000000000000000000000000000000 --- a/gui2/materialeditor/materialselectionmodel.cpp +++ /dev/null @@ -1,66 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/materialeditor/materialselectionmodel.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/materialeditor/materialselectionmodel.h" -#include "gui2/model/materialitems.h" -#include "mvvm/viewmodel/viewmodel.h" -#include "mvvm/viewmodel/viewmodelutils.h" - -namespace gui2 { - -MaterialSelectionModel::MaterialSelectionModel(ModelView::ViewModel* view_model, QObject* parent) - : QItemSelectionModel(view_model, parent) -{ - // FIXME cover with unit tests after implementing ViewItemSelectionModel - connect(view_model, &ModelView::ViewModel::modelAboutToBeReset, [this]() { clearSelection(); }); -} - -void MaterialSelectionModel::selectItem(ModelView::SessionItem* item) -{ - selectItems({item}); -} - -void MaterialSelectionModel::selectItems(std::vector<ModelView::SessionItem*> items) -{ - QModelIndexList indexes; - for (auto item : items) - indexes << viewModel()->indexOfSessionItem(item->getItem(MaterialBaseItem::P_NAME)); - - if (indexes.empty()) - return; - - clearSelection(); - - QItemSelection selection(indexes.front(), indexes.back()); - auto flags = QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows; - select(selection, flags); -} - -//! Returns vector of selected materials. - -std::vector<MaterialBaseItem*> MaterialSelectionModel::selectedMaterials() const -{ - std::vector<MaterialBaseItem*> result; - auto selected_items = ModelView::Utils::ParentItemsFromIndex(selectedIndexes()); - std::transform(std::begin(selected_items), std::end(selected_items), std::back_inserter(result), - [](auto item) { return dynamic_cast<MaterialBaseItem*>(item); }); - return result; -} - -const ModelView::ViewModel* MaterialSelectionModel::viewModel() const -{ - return static_cast<const ModelView::ViewModel*>(model()); -} - -} // namespace gui2 diff --git a/gui2/materialeditor/materialselectionmodel.h b/gui2/materialeditor/materialselectionmodel.h deleted file mode 100644 index 297b5ed7281288201a4bad8b36cd3b011fe842c8..0000000000000000000000000000000000000000 --- a/gui2/materialeditor/materialselectionmodel.h +++ /dev/null @@ -1,53 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/materialeditor/materialselectionmodel.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_MATERIALEDITOR_MATERIALSELECTIONMODEL_H -#define BORNAGAIN_GUI2_MATERIALEDITOR_MATERIALSELECTIONMODEL_H - -#include "darefl_export.h" -#include <QItemSelectionModel> -#include <vector> - -namespace ModelView { -class ViewModel; -class SessionItem; -} // namespace ModelView - -namespace gui2 { - -class MaterialEditorActions; -class MaterialBaseItem; - -//! Custom selection model for material view model (AbstractViewModel). -//! Reports clients about selected MaterialItem in material table and hides -//! QModelIndex related machinery. - -class DAREFLCORE_EXPORT MaterialSelectionModel : public QItemSelectionModel { - Q_OBJECT - -public: - MaterialSelectionModel(ModelView::ViewModel* view_model, QObject* parent = nullptr); - ~MaterialSelectionModel() = default; - - void selectItem(ModelView::SessionItem* item); - void selectItems(std::vector<ModelView::SessionItem*> items); - - std::vector<MaterialBaseItem*> selectedMaterials() const; - - const ModelView::ViewModel* viewModel() const; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_MATERIALEDITOR_MATERIALSELECTIONMODEL_H diff --git a/gui2/materialeditor/materialtableview.cpp b/gui2/materialeditor/materialtableview.cpp deleted file mode 100644 index 332c935f5c4664250b54dd558b9435cc27f51689..0000000000000000000000000000000000000000 --- a/gui2/materialeditor/materialtableview.cpp +++ /dev/null @@ -1,69 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/materialeditor/materialtableview.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/materialeditor/materialtableview.h" -#include <QHeaderView> -#include <QMouseEvent> - -namespace gui2 { - -MaterialTableView::~MaterialTableView() = default; - -void MaterialTableView::setModel(QAbstractItemModel* model) -{ - QTableView::setModel(model); - setAlternatingRowColors(true); - horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); - horizontalHeader()->setSectionResizeMode(0, QHeaderView::ResizeToContents); -} - -void MaterialTableView::keyPressEvent(QKeyEvent* event) -{ - if (!event || event->key() != Qt::Key_Return || state() == QAbstractItemView::EditingState) - return QTableView::keyPressEvent(event); - - const QModelIndex index = currentIndex(); - if (isKeyboardEditable(index)) - edit(index); -} - -QModelIndex MaterialTableView::moveCursor(QAbstractItemView::CursorAction cursorAction, - Qt::KeyboardModifiers modifiers) -{ - const QModelIndex current_index = currentIndex(); - bool filtered_action = cursorAction == QAbstractItemView::MoveNext - || cursorAction == QAbstractItemView::MovePrevious; - - if (!current_index.isValid() || !isTextField(current_index) || !filtered_action) - return QTableView::moveCursor(cursorAction, modifiers); - - QModelIndex next = current_index; - do { - setCurrentIndex(next); - next = QTableView::moveCursor(cursorAction, modifiers); - } while (!isTextField(next)); - return next; -} - -bool MaterialTableView::isTextField(const QModelIndex& index) const -{ - return index.isValid() && index.column() > 1; // color and checkbox are not keyboard editable -} - -bool MaterialTableView::isKeyboardEditable(const QModelIndex& index) const -{ - return index.isValid(); -} - -} // namespace gui2 diff --git a/gui2/materialeditor/materialtableview.h b/gui2/materialeditor/materialtableview.h deleted file mode 100644 index 1a276a4b5679d8befbc9b89e49d00907704d0c43..0000000000000000000000000000000000000000 --- a/gui2/materialeditor/materialtableview.h +++ /dev/null @@ -1,46 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/materialeditor/materialtableview.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_MATERIALEDITOR_MATERIALTABLEVIEW_H -#define BORNAGAIN_GUI2_MATERIALEDITOR_MATERIALTABLEVIEW_H - -#include "darefl_export.h" -#include <QTableView> - -namespace gui2 { - -//! Extension of QTableView for material editing. -//! Provide better user experinece while navigating between cells. -//! Part of MaterialTableWidget. - -class DAREFLCORE_EXPORT MaterialTableView : public QTableView { -public: - using QTableView::QTableView; - ~MaterialTableView() override; - - void setModel(QAbstractItemModel* model) override; - -protected: - void keyPressEvent(QKeyEvent* event) override; - QModelIndex moveCursor(QAbstractItemView::CursorAction cursorAction, - Qt::KeyboardModifiers modifiers) override; - -private: - bool isTextField(const QModelIndex& index) const; - bool isKeyboardEditable(const QModelIndex& index) const; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_MATERIALEDITOR_MATERIALTABLEVIEW_H diff --git a/gui2/materialeditor/materialtreeview.cpp b/gui2/materialeditor/materialtreeview.cpp deleted file mode 100644 index b21916153e3fb6950761ea230d069d07f116e128..0000000000000000000000000000000000000000 --- a/gui2/materialeditor/materialtreeview.cpp +++ /dev/null @@ -1,76 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/materialeditor/materialtreeview.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/materialeditor/materialtreeview.h" -#include <QHeaderView> -#include <QMouseEvent> - -namespace gui2 { - -MaterialTreeView::~MaterialTreeView() = default; - -MaterialTreeView::MaterialTreeView(QWidget* parent) : QTreeView(parent) -{ - setAlternatingRowColors(true); - setSelectionBehavior(QAbstractItemView::SelectRows); - setSelectionMode(QAbstractItemView::ExtendedSelection); - // setTabKeyNavigation(true); - header()->setSectionResizeMode(QHeaderView::Stretch); -} - -void MaterialTreeView::setModel(QAbstractItemModel* model) -{ - QTreeView::setModel(model); - expandAll(); -} - -void MaterialTreeView::keyPressEvent(QKeyEvent* event) -{ - if (!event || event->key() != Qt::Key_Return || state() == QAbstractItemView::EditingState) - return QTreeView::keyPressEvent(event); - - const QModelIndex index = currentIndex(); - if (isKeyboardEditable(index)) - edit(index); -} - -QModelIndex MaterialTreeView::moveCursor(QAbstractItemView::CursorAction cursorAction, - Qt::KeyboardModifiers modifiers) -{ - const QModelIndex current_index = currentIndex(); - bool filtered_action = cursorAction == QAbstractItemView::MoveNext - || cursorAction == QAbstractItemView::MovePrevious; - - if (!current_index.isValid() || !isTextField(current_index) || !filtered_action) - return QTreeView::moveCursor(cursorAction, modifiers); - - QModelIndex next = current_index; - do { - setCurrentIndex(next); - next = QTreeView::moveCursor(cursorAction, modifiers); - } while (!isTextField(next)); - return next; -} - -bool MaterialTreeView::isTextField(const QModelIndex& index) const -{ - return index.isValid() && index.column() > 0; // color is not keyboard editable -} - -bool MaterialTreeView::isKeyboardEditable(const QModelIndex& index) const -{ - return index.isValid(); -} - -} // namespace gui2 diff --git a/gui2/materialeditor/materialtreeview.h b/gui2/materialeditor/materialtreeview.h deleted file mode 100644 index 2a7f3492e1d9a3609eb86d833568a677973bf2de..0000000000000000000000000000000000000000 --- a/gui2/materialeditor/materialtreeview.h +++ /dev/null @@ -1,48 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/materialeditor/materialtreeview.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_MATERIALEDITOR_MATERIALTREEVIEW_H -#define BORNAGAIN_GUI2_MATERIALEDITOR_MATERIALTREEVIEW_H - -#include "darefl_export.h" -#include <QTreeView> - -namespace gui2 { - -//! Extension of QTreeView for material editing. -//! Provide better user experinece while navigating between cells. -//! Part of MaterialTableWidget. - -class DAREFLCORE_EXPORT MaterialTreeView : public QTreeView { -public: - using QTreeView::QTreeView; - - explicit MaterialTreeView(QWidget* parent = nullptr); - ~MaterialTreeView() override; - - void setModel(QAbstractItemModel* model) override; - -protected: - void keyPressEvent(QKeyEvent* event) override; - QModelIndex moveCursor(QAbstractItemView::CursorAction cursorAction, - Qt::KeyboardModifiers modifiers) override; - -private: - bool isTextField(const QModelIndex& index) const; - bool isKeyboardEditable(const QModelIndex& index) const; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_MATERIALEDITOR_MATERIALTREEVIEW_H diff --git a/gui2/model/CMakeLists.txt b/gui2/model/CMakeLists.txt deleted file mode 100644 index 6245d7c30c6ffb9ffcc6332431c40a833bceb771..0000000000000000000000000000000000000000 --- a/gui2/model/CMakeLists.txt +++ /dev/null @@ -1,31 +0,0 @@ -target_sources(${library_name} PRIVATE - applicationmodels.cpp - applicationmodels.h - experimentaldatacontroller.cpp - experimentaldatacontroller.h - experimentaldataitems.cpp - experimentaldataitems.h - experimentaldatamodel.cpp - experimentaldatamodel.h - instrumentitems.cpp - instrumentitems.h - instrumentmodel.cpp - instrumentmodel.h - item_constants.h - jobitem.cpp - jobitem.h - jobmodel.cpp - jobmodel.h - materialitems.cpp - materialitems.h - materialmodel.cpp - materialmodel.h - materialpropertycontroller.cpp - materialpropertycontroller.h - modelutils.cpp - modelutils.h - sampleitems.cpp - sampleitems.h - samplemodel.cpp - samplemodel.h -) diff --git a/gui2/model/applicationmodels.cpp b/gui2/model/applicationmodels.cpp deleted file mode 100644 index bd6e815bb31b399d6b029410299b9184ffffeb94..0000000000000000000000000000000000000000 --- a/gui2/model/applicationmodels.cpp +++ /dev/null @@ -1,138 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/model/applicationmodels.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/model/applicationmodels.h" -#include "gui2/model/experimentaldatacontroller.h" -#include "gui2/model/experimentaldatamodel.h" -#include "gui2/model/instrumentmodel.h" -#include "gui2/model/jobmodel.h" -#include "gui2/model/materialmodel.h" -#include "gui2/model/materialpropertycontroller.h" -#include "gui2/model/sampleitems.h" -#include "gui2/model/samplemodel.h" -#include "gui2/sldeditor/sldelementmodel.h" -#include "mvvm/model/externalproperty.h" -#include "mvvm/model/itempool.h" -#include "mvvm/model/modelutils.h" -#include "mvvm/model/sessionitem.h" - -namespace gui2 { - -using namespace ModelView; - -struct ApplicationModels::ApplicationModelsImpl { - std::unique_ptr<MaterialModel> m_material_model; - std::unique_ptr<SampleModel> m_sample_model; - std::unique_ptr<SLDElementModel> m_sld_view_model; - std::unique_ptr<JobModel> m_job_model; - std::unique_ptr<ExperimentalDataModel> m_experimental_model; - std::unique_ptr<InstrumentModel> m_instrument_model; - std::unique_ptr<MaterialPropertyController> m_material_controller; - std::unique_ptr<ExperimentalDataController> m_data_controller; - std::shared_ptr<ItemPool> item_pool; - - ApplicationModelsImpl() - { - item_pool = std::make_shared<ItemPool>(); - m_material_model = std::make_unique<MaterialModel>(item_pool); - m_sample_model = std::make_unique<SampleModel>(item_pool); - m_sld_view_model = std::make_unique<SLDElementModel>(); - m_job_model = std::make_unique<JobModel>(item_pool); - m_experimental_model = std::make_unique<ExperimentalDataModel>(item_pool); - m_instrument_model = std::make_unique<InstrumentModel>(item_pool); - m_material_controller = std::make_unique<MaterialPropertyController>(m_material_model.get(), - m_sample_model.get()); - m_data_controller = std::make_unique<ExperimentalDataController>(m_experimental_model.get(), - m_instrument_model.get()); - m_sample_model->create_default_multilayer(); - update_material_properties(); - } - - //! Runs through all layers and assign materials. - //! Expecting 3 materials existing by default (air, default, Si) to assign to our 3 layers. - - void update_material_properties() - { - auto multilayer = Utils::TopItem<MultiLayerItem>(m_sample_model.get()); - auto layers = multilayer->items<LayerItem>(MultiLayerItem::T_LAYERS); - size_t index(0); - for (const auto& material_property : m_material_model->material_data()) { - if (index < layers.size()) - layers[index]->setProperty(LayerItem::P_MATERIAL, material_property); - ++index; - } - } - - //! Models intended for saving. - std::vector<SessionModel*> persistent_models() const - { - return {m_material_model.get(), m_sample_model.get(), m_instrument_model.get(), - m_experimental_model.get()}; - } - - //! All application models. - std::vector<SessionModel*> application_models() const - { - return {m_material_model.get(), m_sample_model.get(), m_instrument_model.get(), - m_sld_view_model.get(), m_job_model.get(), m_experimental_model.get()}; - } -}; - -ApplicationModels::ApplicationModels() : p_impl(std::make_unique<ApplicationModelsImpl>()) {} - -ApplicationModels::~ApplicationModels() = default; - -MaterialModel* ApplicationModels::materialModel() -{ - return p_impl->m_material_model.get(); -} - -SampleModel* ApplicationModels::sampleModel() -{ - return p_impl->m_sample_model.get(); -} - -SLDElementModel* ApplicationModels::sldViewModel() -{ - return p_impl->m_sld_view_model.get(); -} - -JobModel* ApplicationModels::jobModel() -{ - return p_impl->m_job_model.get(); -} - -ExperimentalDataModel* ApplicationModels::experimentalDataModel() -{ - return p_impl->m_experimental_model.get(); -} - -InstrumentModel* ApplicationModels::instrumentModel() -{ - return p_impl->m_instrument_model.get(); -} - -std::vector<SessionModel*> ApplicationModels::persistent_models() const -{ - return p_impl->persistent_models(); -} - -//! Return vector of all models of our application. - -std::vector<SessionModel*> ApplicationModels::application_models() const -{ - return p_impl->application_models(); -} - -} // namespace gui2 diff --git a/gui2/model/applicationmodels.h b/gui2/model/applicationmodels.h deleted file mode 100644 index 3b862b9215b7ec12067c21888c0ec7bc120db9aa..0000000000000000000000000000000000000000 --- a/gui2/model/applicationmodels.h +++ /dev/null @@ -1,61 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/model/applicationmodels.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_MODEL_APPLICATIONMODELS_H -#define BORNAGAIN_GUI2_MODEL_APPLICATIONMODELS_H - -#include "darefl_export.h" -#include "mvvm/interfaces/applicationmodelsinterface.h" -#include <memory> - -namespace ModelView { -class SessionModel; -} - -namespace gui2 { - -class MaterialModel; -class SampleModel; -class SLDElementModel; -class SLDElementController; -class JobModel; -class ExperimentalDataModel; -class InstrumentModel; - -//! Main class to holds all models of GUI session. - -class DAREFLCORE_EXPORT ApplicationModels : public ModelView::ApplicationModelsInterface { -public: - ApplicationModels(); - ~ApplicationModels(); - - MaterialModel* materialModel(); - SampleModel* sampleModel(); - SLDElementModel* sldViewModel(); - JobModel* jobModel(); - ExperimentalDataModel* experimentalDataModel(); - InstrumentModel* instrumentModel(); - - std::vector<ModelView::SessionModel*> persistent_models() const override; - - std::vector<ModelView::SessionModel*> application_models() const; - -private: - struct ApplicationModelsImpl; - std::unique_ptr<ApplicationModelsImpl> p_impl; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_MODEL_APPLICATIONMODELS_H diff --git a/gui2/model/experimentaldatacontroller.cpp b/gui2/model/experimentaldatacontroller.cpp deleted file mode 100644 index 384e82b14d7a2cbe58deafa541e281cb1305eea1..0000000000000000000000000000000000000000 --- a/gui2/model/experimentaldatacontroller.cpp +++ /dev/null @@ -1,52 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/model/experimentaldatacontroller.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/model/experimentaldatacontroller.h" -#include "gui2/model/experimentaldataitems.h" -#include "gui2/model/experimentaldatamodel.h" -#include "gui2/model/instrumentitems.h" -#include "gui2/model/instrumentmodel.h" -#include "gui2/model/modelutils.h" -#include "mvvm/model/externalproperty.h" -#include "mvvm/model/modelutils.h" - -namespace gui2 { - -ExperimentalDataController::ExperimentalDataController(ExperimentalDataModel* data_model, - InstrumentModel* instrument_model) - : ModelListener(data_model), m_instrument_model(instrument_model) -{ - setOnDataChange([this](auto, auto) { update_all(); }); - setOnItemInserted([this](auto, auto) { update_all(); }); - setOnItemRemoved([this](auto, auto) { update_all(); }); - setOnModelReset([this](auto) { update_all(); }); - - update_all(); -} - -//! Updates all material properties in LayerItems to get new material colors and labels. - -void ExperimentalDataController::update_all() -{ - for (auto scan : ModelView::Utils::FindItems<ExperimentalScanItem>(m_instrument_model)) { - auto property = - scan->property<ModelView::ExternalProperty>(ExperimentalScanItem::P_IMPORTED_DATA); - auto updated = - Utils::FindProperty(Utils::CreateGraphProperties(model()), property.identifier()); - if (property != updated) - scan->setProperty(ExperimentalScanItem::P_IMPORTED_DATA, updated); - } -} - -} // namespace gui2 diff --git a/gui2/model/experimentaldatacontroller.h b/gui2/model/experimentaldatacontroller.h deleted file mode 100644 index d7769cb687c963da7eeb9c7cf7605486c856798a..0000000000000000000000000000000000000000 --- a/gui2/model/experimentaldatacontroller.h +++ /dev/null @@ -1,45 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/model/experimentaldatacontroller.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_MODEL_EXPERIMENTALDATACONTROLLER_H -#define BORNAGAIN_GUI2_MODEL_EXPERIMENTALDATACONTROLLER_H - -#include "darefl_export.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/signals/modellistener.h" - -namespace gui2 { - -class InstrumentModel; -class ExperimentalDataModel; - -//! Listens for all changes in ExperimentalDataModel and updates properties in InstrumentModel. -//! Main task is to update links of ExperimentalScanItem to particular imported graph, when -//! ExperimentalDataModel is changing. - -class DAREFLCORE_EXPORT ExperimentalDataController - : public ModelView::ModelListener<ExperimentalDataModel> { -public: - ExperimentalDataController(ExperimentalDataModel* data_model, - InstrumentModel* instrument_model); - -private: - void update_all(); - - InstrumentModel* m_instrument_model{nullptr}; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_MODEL_EXPERIMENTALDATACONTROLLER_H diff --git a/gui2/model/experimentaldataitems.cpp b/gui2/model/experimentaldataitems.cpp deleted file mode 100644 index 4838a6c56d18bb5bcb1e9065a056c13ae38ec62e..0000000000000000000000000000000000000000 --- a/gui2/model/experimentaldataitems.cpp +++ /dev/null @@ -1,55 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/model/experimentaldataitems.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/model/experimentaldataitems.h" -#include "gui2/model/item_constants.h" -#include "mvvm/standarditems/axisitems.h" -#include "mvvm/standarditems/data1ditem.h" - -using namespace ModelView; - -namespace gui2 { - -CanvasItem::CanvasItem() : GraphViewportItem(GUI::Constants::CanvasItemType) -{ - yAxis()->setProperty(ViewportAxisItem::P_IS_LOG, true); - setData(std::string("")); -} - -std::pair<double, double> CanvasItem::data_yaxis_range() const -{ - auto [ymin, ymax] = GraphViewportItem::data_yaxis_range(); - return {ymin, ymax * 2.0}; -} - -CanvasContainerItem::CanvasContainerItem() : ContainerItem(GUI::Constants::CanvasContainerItemType) -{ -} - -std::vector<CanvasItem*> CanvasContainerItem::canvasItems() const -{ - return items<CanvasItem>(T_ITEMS); -} - -ExperimentalDataContainerItem::ExperimentalDataContainerItem() - : ContainerItem(GUI::Constants::ExperimentalDataContainerItemType) -{ -} - -std::vector<Data1DItem*> ExperimentalDataContainerItem::dataItems() const -{ - return items<ModelView::Data1DItem>(T_ITEMS); -} - -} // namespace gui2 diff --git a/gui2/model/experimentaldataitems.h b/gui2/model/experimentaldataitems.h deleted file mode 100644 index 47a3549a56dca69d95cc999f5c5d28ee568eeaf2..0000000000000000000000000000000000000000 --- a/gui2/model/experimentaldataitems.h +++ /dev/null @@ -1,64 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/model/experimentaldataitems.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_MODEL_EXPERIMENTALDATAITEMS_H -#define BORNAGAIN_GUI2_MODEL_EXPERIMENTALDATAITEMS_H - -#include "darefl_export.h" -#include "mvvm/standarditems/containeritem.h" -#include "mvvm/standarditems/graphviewportitem.h" - -namespace ModelView { -class Data1DItem; -} - -namespace gui2 { - -//! Holds a collection of GraphItem's for simultaneous plotting, as well as all information -//! related to plotting properties. Used in the context of importing of 1D data. Serves as an input -//! for GraphCanvas widget. - -class DAREFLCORE_EXPORT CanvasItem : public ModelView::GraphViewportItem { -public: - CanvasItem(); - -protected: - std::pair<double, double> data_yaxis_range() const override; -}; - -//! Holds a collection of CanvasItem. -//! Used in the context of importing of 1D data, when user groups different GraphItem's -//! on different canvas for later plotting. - -class DAREFLCORE_EXPORT CanvasContainerItem : public ModelView::ContainerItem { -public: - CanvasContainerItem(); - - std::vector<CanvasItem*> canvasItems() const; -}; - -//! Holds a collection of Data1DItem's with raw data as imported by the user. -//! The order of items in the collection chronologically corresponds to user activity. -//! All other plotting entities (GraphItems) are linked to data items in this container. - -class DAREFLCORE_EXPORT ExperimentalDataContainerItem : public ModelView::ContainerItem { -public: - ExperimentalDataContainerItem(); - - std::vector<ModelView::Data1DItem*> dataItems() const; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_MODEL_EXPERIMENTALDATAITEMS_H diff --git a/gui2/model/experimentaldatamodel.cpp b/gui2/model/experimentaldatamodel.cpp deleted file mode 100644 index e11a3bf517e9220a278a4d525ddb0e1592866f21..0000000000000000000000000000000000000000 --- a/gui2/model/experimentaldatamodel.cpp +++ /dev/null @@ -1,139 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/model/experimentaldatamodel.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/model/experimentaldatamodel.h" -#include "gui2/importdataview/graphimportdata.h" -#include "gui2/model/experimentaldataitems.h" - -#include "mvvm/model/itemcatalogue.h" -#include "mvvm/model/modelutils.h" -#include "mvvm/standarditems/axisitems.h" -#include "mvvm/standarditems/containeritem.h" -#include "mvvm/standarditems/data1ditem.h" -#include "mvvm/standarditems/graphitem.h" -#include "mvvm/standarditems/graphviewportitem.h" - -#include <algorithm> -#include <cmath> - -using namespace ModelView; - -namespace { - -std::unique_ptr<ItemCatalogue> CreateItemCatalogue() -{ - auto result = std::make_unique<ModelView::ItemCatalogue>(); - result->registerItem<gui2::CanvasItem>(); - result->registerItem<gui2::CanvasContainerItem>(); - result->registerItem<gui2::ExperimentalDataContainerItem>(); - return result; -} - -} // namespace - -namespace gui2 { - -ExperimentalDataModel::ExperimentalDataModel(std::shared_ptr<ItemPool> pool) - : SessionModel("ExperimentalDataModel", pool) - -{ - init_model(); -} - -//! Returns the canvas container of the model. - -CanvasContainerItem* ExperimentalDataModel::canvasContainer() const -{ - return topItem<CanvasContainerItem>(); -} - -//! Returns the data container of the model. - -ExperimentalDataContainerItem* ExperimentalDataModel::dataContainer() const -{ - return topItem<ExperimentalDataContainerItem>(); -} - -CanvasItem* ExperimentalDataModel::addCanvas() -{ - return insertItem<CanvasItem>(canvasContainer()); -} - -//! Adds graph to 'target_canvas' and returns the result. -//! Internally add Data1DItem object to ExperimentalDataContainerItem, -//! and set it to GraphItem. - -ModelView::GraphItem* ExperimentalDataModel::addGraph(const GraphImportData& graph_data, - CanvasItem& target_canvas) -{ - auto result = insertItem<GraphItem>(&target_canvas); - - auto data = insertItem<Data1DItem>(dataContainer()); - data->setAxis<PointwiseAxisItem>(graph_data.bin_centers); - data->setValues(graph_data.bin_values); - result->setDataItem(data); - - result->setData(graph_data.graph_description); - - return result; -} - -//! Remove graph from the model. Underlying DataItem will be removed too. - -void ExperimentalDataModel::removeGraph(GraphItem& graph) -{ - auto dataItem = graph.dataItem(); - - removeItem(graph.parent(), graph.tagRow()); - removeItem(dataItem->parent(), dataItem->tagRow()); -} - -//! Remove canvas with all its graphs. - -void ExperimentalDataModel::removeCanvas(CanvasItem& canvas) -{ - // Remove graph first. Use special method for that, since we want to remove underlying items. - for (auto graph : canvas.graphItems()) - removeGraph(*graph); - removeItem(canvas.parent(), canvas.tagRow()); -} - -//! Merge canvas from the vector. All graphs will be the children of the first canvas in the vector. -//! All other canvas will be emptied and deleted. - -void ExperimentalDataModel::mergeCanvases(const std::vector<CanvasItem*>& canvases) -{ - if (canvases.size() <= 1) - return; - - CanvasItem* target = canvases.front(); - for (auto it = std::next(canvases.begin()); it < canvases.end(); ++it) { - CanvasItem* source = (*it); - for (auto graph : source->graphItems()) - moveItem(graph, target, {"", -1}); - removeItem(source->parent(), source->tagRow()); - } -} - -void ExperimentalDataModel::init_model() -{ - setItemCatalogue(CreateItemCatalogue()); - - insertItem<ExperimentalDataContainerItem>(rootItem()); - insertItem<CanvasContainerItem>(rootItem()); - - setUndoRedoEnabled(true); -} - -} // namespace gui2 diff --git a/gui2/model/experimentaldatamodel.h b/gui2/model/experimentaldatamodel.h deleted file mode 100644 index dd0529be83797962eba6fe1d036caf5c26509181..0000000000000000000000000000000000000000 --- a/gui2/model/experimentaldatamodel.h +++ /dev/null @@ -1,61 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/model/experimentaldatamodel.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_MODEL_EXPERIMENTALDATAMODEL_H -#define BORNAGAIN_GUI2_MODEL_EXPERIMENTALDATAMODEL_H - -#include "darefl_export.h" -#include "mvvm/model/sessionmodel.h" -#include <vector> - -namespace ModelView { -class SessionItem; -class GraphItem; -class GraphViewportItem; -} // namespace ModelView - -namespace gui2 { - -class CanvasContainerItem; -class ExperimentalDataContainerItem; -class CanvasItem; -struct GraphImportData; - -//! The model to store imported reflectometry data. - -class DAREFLCORE_EXPORT ExperimentalDataModel : public ModelView::SessionModel { -public: - ExperimentalDataModel(std::shared_ptr<ModelView::ItemPool> pool = {}); - - CanvasContainerItem* canvasContainer() const; - - ExperimentalDataContainerItem* dataContainer() const; - - CanvasItem* addCanvas(); - - ModelView::GraphItem* addGraph(const GraphImportData& graph_data, CanvasItem& target_canvas); - - void removeGraph(ModelView::GraphItem& graph); - - void removeCanvas(CanvasItem& canvas); - - void mergeCanvases(const std::vector<CanvasItem*>& canvases); - -private: - void init_model(); -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_MODEL_EXPERIMENTALDATAMODEL_H diff --git a/gui2/model/instrumentitems.cpp b/gui2/model/instrumentitems.cpp deleted file mode 100644 index a0990a06256c6f509529601d16255f2b631dacc8..0000000000000000000000000000000000000000 --- a/gui2/model/instrumentitems.cpp +++ /dev/null @@ -1,134 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/model/instrumentitems.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/model/instrumentitems.h" -#include "gui2/model/item_constants.h" -#include "gui2/model/modelutils.h" -#include "mvvm/model/externalproperty.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/standarditems/axisitems.h" -#include "mvvm/standarditems/graphitem.h" -#include <QColor> - -using namespace ModelView; - -namespace gui2 { - -BasicSpecularScanItem::BasicSpecularScanItem(const std::string& model_type) - : CompoundItem(model_type) -{ -} - -// ---------------------------------------------------------------------------- - -QSpecScanItem::QSpecScanItem() : BasicSpecularScanItem(GUI::Constants::QSpecScanItemType) -{ - addProperty(P_NBINS, 500)->setDisplayName("Nbins"); - addProperty(P_QMIN, 0.0)->setDisplayName("Qmin"); - addProperty(P_QMAX, 1.0)->setDisplayName("Qmax"); -} - -std::vector<double> QSpecScanItem::qScanValues() const -{ - int nbins = property<int>(P_NBINS); - double qmin = property<double>(P_QMIN); - double qmax = property<double>(P_QMAX); - return FixedBinAxisItem::create(nbins, qmin, qmax)->binCenters(); -} - -// ---------------------------------------------------------------------------- - -ExperimentalScanItem::ExperimentalScanItem() - : BasicSpecularScanItem(GUI::Constants::ExperimentalScanItemType) -{ - addProperty(P_IMPORTED_DATA, ExternalProperty::undefined())->setDisplayName("Graph"); -} - -void ExperimentalScanItem::setGraphItem(GraphItem* graph) -{ - setProperty(P_IMPORTED_DATA, Utils::CreateProperty(graph)); -} - -GraphItem* ExperimentalScanItem::graphItem() const -{ - if (model()) { - auto graph_id = property<ExternalProperty>(P_IMPORTED_DATA).identifier(); - return dynamic_cast<GraphItem*>(model()->findItem(graph_id)); - } - return nullptr; -} - -std::vector<double> ExperimentalScanItem::qScanValues() const -{ - return graphItem() ? graphItem()->binCenters() : std::vector<double>(); -} - -// ---------------------------------------------------------------------------- - -SpecularScanGroupItem::SpecularScanGroupItem() - : GroupItem(GUI::Constants::SpecularScanGroupItemType) -{ - registerItem<QSpecScanItem>("Q-scan", /*make_selected*/ true); - registerItem<ExperimentalScanItem>("Based on data"); - init_group(); -} - -// ---------------------------------------------------------------------------- - -SpecularBeamItem::SpecularBeamItem() : CompoundItem(GUI::Constants::SpecularBeamItemType) -{ - addProperty(P_INTENSITY, 1.0)->setDisplayName("Intensity"); - addProperty<SpecularScanGroupItem>(P_SCAN_GROUP)->setDisplayName("Specular scan type"); -} - -std::vector<double> SpecularBeamItem::qScanValues() const -{ - auto scan_group = item<SpecularScanGroupItem>(P_SCAN_GROUP); - if (auto scanItem = dynamic_cast<const BasicSpecularScanItem*>(scan_group->currentItem()); - scanItem) - return scanItem->qScanValues(); - return {}; -} - -double SpecularBeamItem::intensity() const -{ - return property<double>(P_INTENSITY); -} - -//! Returns corresponding experimental graph. If current setup is based on simple q-scan, will -//! return nullptr. - -GraphItem* SpecularBeamItem::experimentalGraphItem() const -{ - auto scan_group = item<SpecularScanGroupItem>(P_SCAN_GROUP); - if (auto scanItem = dynamic_cast<const ExperimentalScanItem*>(scan_group->currentItem()); - scanItem) - return scanItem->graphItem(); - return nullptr; -} - -// ---------------------------------------------------------------------------- - -SpecularInstrumentItem::SpecularInstrumentItem() - : CompoundItem(GUI::Constants::SpecularInstrumentItemType) -{ - addProperty<SpecularBeamItem>(P_BEAM); -} - -SpecularBeamItem* SpecularInstrumentItem::beamItem() const -{ - return item<SpecularBeamItem>(P_BEAM); -} - -} // namespace gui2 diff --git a/gui2/model/instrumentitems.h b/gui2/model/instrumentitems.h deleted file mode 100644 index 7e39a9290cfa763a9b4dbdf3c133e0a2aba08868..0000000000000000000000000000000000000000 --- a/gui2/model/instrumentitems.h +++ /dev/null @@ -1,101 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/model/instrumentitems.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_MODEL_INSTRUMENTITEMS_H -#define BORNAGAIN_GUI2_MODEL_INSTRUMENTITEMS_H - -//! @file gui2/model/instrumentitems.h -//! Collection of items to construct specular instrument. - -#include "darefl_export.h" -#include "mvvm/model/compounditem.h" -#include "mvvm/model/groupitem.h" - -namespace ModelView { -class GraphItem; -} - -namespace gui2 { - -//! Represents base type for beam scan parameters. - -class DAREFLCORE_EXPORT BasicSpecularScanItem : public ModelView::CompoundItem { -public: - BasicSpecularScanItem(const std::string& model_type); - virtual std::vector<double> qScanValues() const = 0; -}; - -//! Represents Q-space specular scan with fixed bin size. - -class DAREFLCORE_EXPORT QSpecScanItem : public BasicSpecularScanItem { -public: - static inline const std::string P_NBINS = "P_NBINS"; - static inline const std::string P_QMIN = "P_QMIN"; - static inline const std::string P_QMAX = "P_QMAX"; - QSpecScanItem(); - - std::vector<double> qScanValues() const override; -}; - -//! Represents scan according to imported experimental data. - -class DAREFLCORE_EXPORT ExperimentalScanItem : public BasicSpecularScanItem { -public: - static inline const std::string P_IMPORTED_DATA = "P_IMPORTED_DATA"; - ExperimentalScanItem(); - - void setGraphItem(ModelView::GraphItem* graph); - - ModelView::GraphItem* graphItem() const; - - std::vector<double> qScanValues() const override; -}; - -//! Represent selection of possible specular scans. - -class DAREFLCORE_EXPORT SpecularScanGroupItem : public ModelView::GroupItem { -public: - SpecularScanGroupItem(); -}; - -//! Represents specular beam, contains settings of scan parameters. - -class DAREFLCORE_EXPORT SpecularBeamItem : public ModelView::CompoundItem { -public: - static inline const std::string P_INTENSITY = "P_INTENSITY"; - static inline const std::string P_SCAN_GROUP = "P_SCAN_GROUP"; - - SpecularBeamItem(); - - std::vector<double> qScanValues() const; - - double intensity() const; - - ModelView::GraphItem* experimentalGraphItem() const; -}; - -//! Represents specular instrument. - -class DAREFLCORE_EXPORT SpecularInstrumentItem : public ModelView::CompoundItem { -public: - static inline const std::string P_BEAM = "P_BEAM"; - - SpecularInstrumentItem(); - - SpecularBeamItem* beamItem() const; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_MODEL_INSTRUMENTITEMS_H diff --git a/gui2/model/instrumentmodel.cpp b/gui2/model/instrumentmodel.cpp deleted file mode 100644 index 299f378e439aceecc3be9d92f0e7ce63ff977eaf..0000000000000000000000000000000000000000 --- a/gui2/model/instrumentmodel.cpp +++ /dev/null @@ -1,45 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/model/instrumentmodel.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/model/instrumentmodel.h" -#include "gui2/model/instrumentitems.h" -#include "mvvm/model/itemcatalogue.h" - -using namespace ModelView; - -namespace { - -std::unique_ptr<ItemCatalogue> CreateItemCatalogue() -{ - auto result = std::make_unique<ModelView::ItemCatalogue>(); - result->registerItem<gui2::SpecularInstrumentItem>(); - result->registerItem<gui2::SpecularBeamItem>(); - result->registerItem<gui2::SpecularScanGroupItem>(); - result->registerItem<gui2::QSpecScanItem>(); - result->registerItem<gui2::ExperimentalScanItem>(); - return result; -} - -} // namespace - -namespace gui2 { - -InstrumentModel::InstrumentModel(std::shared_ptr<ItemPool> pool) - : ModelView::SessionModel("InstrumentModel", pool) -{ - setItemCatalogue(CreateItemCatalogue()); - insertItem<SpecularInstrumentItem>(); -} - -} // namespace gui2 diff --git a/gui2/model/instrumentmodel.h b/gui2/model/instrumentmodel.h deleted file mode 100644 index d9f545338a8b0af91640a7eb050add1c93c3b871..0000000000000000000000000000000000000000 --- a/gui2/model/instrumentmodel.h +++ /dev/null @@ -1,32 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/model/instrumentmodel.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_MODEL_INSTRUMENTMODEL_H -#define BORNAGAIN_GUI2_MODEL_INSTRUMENTMODEL_H - -#include "darefl_export.h" -#include "mvvm/model/sessionmodel.h" - -namespace gui2 { - -//! Model to store specular instruments settings. - -class DAREFLCORE_EXPORT InstrumentModel : public ModelView::SessionModel { -public: - InstrumentModel(std::shared_ptr<ModelView::ItemPool> pool = {}); -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_MODEL_INSTRUMENTMODEL_H diff --git a/gui2/model/item_constants.h b/gui2/model/item_constants.h deleted file mode 100644 index 720c6f1ace1aa8aa95a754e72d7125f3b810009a..0000000000000000000000000000000000000000 --- a/gui2/model/item_constants.h +++ /dev/null @@ -1,40 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/model/item_constants.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_MODEL_ITEM_CONSTANTS_H -#define BORNAGAIN_GUI2_MODEL_ITEM_CONSTANTS_H - -#include <string> - -namespace gui2::Constants { - -const std::string CanvasContainerItemType = "CanvasContainer"; -const std::string CanvasItemType = "Canvas"; -const std::string ExperimentalDataContainerItemType = "ExperimentalDataContainer"; -const std::string ExperimentalScanItemType = "ExperimentalScan"; -const std::string JobItemType = "Job"; -const std::string LayerItemType = "Layer"; -const std::string MaterialContainerItemType = "MaterialContainer"; -const std::string MultiLayerItemType = "MultiLayer"; -const std::string QSpecScanItemType = "QSpecScan"; -const std::string RoughnessItemType = "Roughness"; -const std::string SLDCanvasItemType = "SLDCanvas"; -const std::string SLDMaterialItemType = "SLDMaterial"; -const std::string SpecularBeamItemType = "SpecularBeam"; -const std::string SpecularInstrumentItemType = "SpecularInstrument"; -const std::string SpecularScanGroupItemType = "SpecularScanGroup"; - -} // namespace gui2::Constants - -#endif // BORNAGAIN_GUI2_MODEL_ITEM_CONSTANTS_H diff --git a/gui2/model/jobitem.cpp b/gui2/model/jobitem.cpp deleted file mode 100644 index 2ca4e15f1726df6b52d950df69223995c67c70da..0000000000000000000000000000000000000000 --- a/gui2/model/jobitem.cpp +++ /dev/null @@ -1,227 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/model/jobitem.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/model/jobitem.h" -#include "gui2/model/experimentaldataitems.h" -#include "gui2/model/item_constants.h" -#include "gui2/model/jobmodel.h" -#include "gui2/model/modelutils.h" -#include "mvvm/model/modelutils.h" -#include "mvvm/standarditems/axisitems.h" -#include "mvvm/standarditems/data1ditem.h" -#include "mvvm/standarditems/graphitem.h" -#include "mvvm/standarditems/graphviewportitem.h" -#include <QColor> - -using namespace ModelView; - -namespace gui2 { - -namespace { -const int row_sim_graph = 0; -const int row_reference_graph = 1; - -GraphItem* create_reference_graph(JobItem* item) -{ - auto model = item->model(); - return model->insertItem<GraphItem>(item->specularViewport(), - {ViewportItem::T_ITEMS, row_reference_graph}); -} - -GraphItem* create_difference_graph(JobItem* item) -{ - auto model = item->model(); - return model->insertItem<GraphItem>(item->diffViewport(), {ViewportItem::T_ITEMS, 0}); -} - -//! Creates viewport and data properties. Creates graph, adds data to the graph, and graph -//! to viewport. -//! TODO consider to replace it with classes, when JobItem structure becomes clear. - -template <typename Data, typename Graph, typename Viewport> -void initViewport(CompoundItem* item, const std::string& data_name, - const std::string& viewport_name) -{ - auto data = item->addProperty<Data>(data_name); - auto viewport = item->addProperty<Viewport>(viewport_name); - auto graph = std::make_unique<GraphItem>(); - graph->setDataItem(data); - viewport->insertItem(graph.release(), {ViewportItem::T_ITEMS, 0}); -} - -} // namespace - -SLDCanvasItem::SLDCanvasItem() : GraphViewportItem(GUI::Constants::SLDCanvasItemType) {} - -std::pair<double, double> SLDCanvasItem::data_yaxis_range() const -{ - auto [ymin, ymax] = GraphViewportItem::data_yaxis_range(); - double range = ymax - ymin; - return {ymin - range / 10.0, ymax + range / 10.0}; -} - -// ---------------------------------------------------------------------------- - -JobItem::JobItem() : ModelView::CompoundItem(GUI::Constants::JobItemType) -{ - setup_sld_viewport(); - setup_specular_viewport(); - setup_diff_viewport(); -} - -Data1DItem* JobItem::sldData() const -{ - return item<Data1DItem>(P_SLD_DATA); -} - -SLDCanvasItem* JobItem::sldViewport() const -{ - return item<SLDCanvasItem>(P_SLD_VIEWPORT); -} - -Data1DItem* JobItem::specularData() const -{ - return item<Data1DItem>(P_SPECULAR_DATA); -} - -CanvasItem* JobItem::specularViewport() const -{ - return item<CanvasItem>(P_SPECULAR_VIEWPORT); -} - -GraphViewportItem* JobItem::diffViewport() const -{ - return item<GraphViewportItem>(P_DIFF_VIEWPORT); -} - -//! Updates reference graph in specular viewport from external graph. -//! External graph represents user imported data, it will be used to -//! is comming from another viewport (i.e. containing user imported data), -//! and it is used - -void JobItem::updateReferenceGraph(const GraphItem* graph) -{ - if (graph) { - setupReferenceGraphFrom(graph); - setupDifferenceGraphFrom(graph); - } else { - removeReferenceGraph(); - removeDifferenceGraph(); - } -} - -//! Updates values stored in Data1DItem representing the difference between specular and reference -//! graphs. - -void JobItem::updateDifferenceData() -{ - if (auto reference_graph = referenceGraph(); reference_graph) { - const auto reference_data = reference_graph->dataItem(); - const auto specular_data = specularData(); - auto diff_data = differenceData(); - Utils::SetDifference(specular_data, reference_data, diff_data); - } -} - -Data1DItem* JobItem::differenceData() const -{ - return item<Data1DItem>(P_DIFF_DATA); -} - -//! Returns specular graph. - -GraphItem* JobItem::specularGraph() const -{ - auto graphs = specularViewport()->graphItems(); - return graphs.size() > 0 ? graphs.at(row_sim_graph) : nullptr; -} - -//! Returns reference graph, if exists. It represents imported user data from ExperimentalScanItem. -//! Here it is stored in SpecularViewport. - -GraphItem* JobItem::referenceGraph() const -{ - auto graphs = specularViewport()->graphItems(); - return graphs.size() > 1 ? graphs.at(row_reference_graph) : nullptr; -} - -//! Returns graph representing a numeric difference between simulated and reference curve. - -GraphItem* JobItem::differenceGraph() const -{ - auto graphs = diffViewport()->graphItems(); - return graphs.size() > 0 ? graphs.at(0) : nullptr; -} - -void JobItem::setupReferenceGraphFrom(const GraphItem* graph) -{ - assert(graph); - auto reference_graph = referenceGraph() ? referenceGraph() : create_reference_graph(this); - reference_graph->setFromGraphItem(graph); -} - -void JobItem::setupDifferenceGraphFrom(const GraphItem* /*graph*/) -{ - // FIXME rename unused graph - if (!differenceGraph()) { - create_difference_graph(this); - differenceGraph()->setDataItem(differenceData()); - } - - updateDifferenceData(); -} - -//! Removes reference graph from specular viewport. - -void JobItem::removeReferenceGraph() -{ - if (auto graph = referenceGraph(); graph) - ModelView::Utils::DeleteItemFromModel(graph); -} - -//! Removes difference graph from specular viewport. - -void JobItem::removeDifferenceGraph() -{ - if (auto graph = differenceGraph(); graph) - ModelView::Utils::DeleteItemFromModel(graph); -} - -void JobItem::setup_sld_viewport() -{ - initViewport<Data1DItem, GraphItem, SLDCanvasItem>(this, P_SLD_DATA, P_SLD_VIEWPORT); - sldData()->setAxis<FixedBinAxisItem>(1, 0.0, 1.0); -} - -//! Setups a specular viewport together with a single graph in it and corresponding data item. -//! Intended to store simulated specular curve, and possibly reference graphs. - -void JobItem::setup_specular_viewport() -{ - initViewport<Data1DItem, GraphItem, CanvasItem>(this, P_SPECULAR_DATA, P_SPECULAR_VIEWPORT); - auto graph = specularGraph(); - graph->setNamedColor("cornflowerblue"); - specularData()->setAxis<PointwiseAxisItem>(std::vector<double>()); -} - -//! Setups viewport, difference graph, and its underlying data to show the difference between -//! simulated and reference curves. - -void JobItem::setup_diff_viewport() -{ - initViewport<Data1DItem, GraphItem, GraphViewportItem>(this, P_DIFF_DATA, P_DIFF_VIEWPORT); - differenceData()->setAxis<PointwiseAxisItem>(std::vector<double>()); -} - -} // namespace gui2 diff --git a/gui2/model/jobitem.h b/gui2/model/jobitem.h deleted file mode 100644 index a7ca161c0536f348567bef704c6009551e8f92c7..0000000000000000000000000000000000000000 --- a/gui2/model/jobitem.h +++ /dev/null @@ -1,87 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/model/jobitem.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_MODEL_JOBITEM_H -#define BORNAGAIN_GUI2_MODEL_JOBITEM_H - -#include "darefl_export.h" -#include "mvvm/model/compounditem.h" -#include "mvvm/standarditems/graphviewportitem.h" - -namespace ModelView { -class Data1DItem; -class GraphViewportItem; -class GraphItem; -} // namespace ModelView - -namespace gui2 { - -class CanvasItem; - -//! Viewport intended for showing SLD profile. -//! Provides custom y-axis range. - -class DAREFLCORE_EXPORT SLDCanvasItem : public ModelView::GraphViewportItem { -public: - SLDCanvasItem(); - -protected: - std::pair<double, double> data_yaxis_range() const override; -}; - -//! Represents state of QuickSimEditor. -//! Holds results of realtime simulation, SLD profiles and difference plot. - -class DAREFLCORE_EXPORT JobItem : public ModelView::CompoundItem { -public: - static inline const std::string P_SLD_DATA = "P_SLD_DATA"; - static inline const std::string P_SLD_VIEWPORT = "P_SLD_VIEWPORT"; - static inline const std::string P_SPECULAR_DATA = "P_SPECULAR_DATA"; - static inline const std::string P_SPECULAR_VIEWPORT = "P_SPECULAR_VIEWPORT"; - static inline const std::string P_DIFF_DATA = "P_DIFF_DATA"; - static inline const std::string P_DIFF_VIEWPORT = "P_DIFF_VIEWPORT"; - - JobItem(); - - ModelView::Data1DItem* sldData() const; - SLDCanvasItem* sldViewport() const; - - ModelView::Data1DItem* specularData() const; - CanvasItem* specularViewport() const; - - ModelView::GraphViewportItem* diffViewport() const; - - void updateReferenceGraph(const ModelView::GraphItem* graph); - - void updateDifferenceData(); - -private: - ModelView::Data1DItem* differenceData() const; - ModelView::GraphItem* specularGraph() const; - ModelView::GraphItem* referenceGraph() const; - ModelView::GraphItem* differenceGraph() const; - - void setupReferenceGraphFrom(const ModelView::GraphItem* graph); - void setupDifferenceGraphFrom(const ModelView::GraphItem* graph); - void removeReferenceGraph(); - void removeDifferenceGraph(); - - void setup_sld_viewport(); - void setup_specular_viewport(); - void setup_diff_viewport(); -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_MODEL_JOBITEM_H diff --git a/gui2/model/jobmodel.cpp b/gui2/model/jobmodel.cpp deleted file mode 100644 index cf0f79838a001539132310814cd62d935b1656bc..0000000000000000000000000000000000000000 --- a/gui2/model/jobmodel.cpp +++ /dev/null @@ -1,97 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/model/jobmodel.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/model/jobmodel.h" -#include "gui2/model/experimentaldataitems.h" -#include "gui2/model/jobitem.h" -#include "gui2/quicksimeditor/quicksim_types.h" -#include "mvvm/model/itemcatalogue.h" -#include "mvvm/model/modelutils.h" -#include "mvvm/standarditems/axisitems.h" -#include "mvvm/standarditems/data1ditem.h" -#include "mvvm/standarditems/graphitem.h" -#include "mvvm/standarditems/graphviewportitem.h" - -using namespace ModelView; - -namespace gui2 { - -namespace { - -std::unique_ptr<ItemCatalogue> CreateItemCatalogue() -{ - auto result = std::make_unique<ModelView::ItemCatalogue>(); - result->registerItem<JobItem>(); - result->registerItem<CanvasItem>(); - result->registerItem<SLDCanvasItem>(); - return result; -} - -} // namespace - -JobModel::JobModel(std::shared_ptr<ItemPool> pool) : SessionModel("JobModel", pool) -{ - setItemCatalogue(CreateItemCatalogue()); - insertItem<JobItem>(); -} - -GraphViewportItem* JobModel::sldViewport() const -{ - return jobItem()->sldViewport(); -} - -CanvasItem* JobModel::specularViewport() const -{ - return jobItem()->specularViewport(); -} - -GraphViewportItem* JobModel::diffViewport() const -{ - return jobItem()->diffViewport(); -} - -void JobModel::updateReferenceGraph(const ModelView::GraphItem* graph) -{ - jobItem()->updateReferenceGraph(graph); -} - -//! Updates specular data in JobItem from simulation results. - -void JobModel::updateSpecularData(const SimulationResult& data) -{ - auto specularData = jobItem()->specularData(); - specularData->item<PointwiseAxisItem>(Data1DItem::T_AXIS)->setParameters(data.qvalues); - specularData->setValues(data.amplitudes); - - // updating difference graph - jobItem()->updateDifferenceData(); -} - -//! Updates SLD profile data. - -void JobModel::updateSLDProfile(const SLDProfile& data) -{ - auto sldData = jobItem()->sldData(); - // sldData->setAxis<FixedBinAxisItem>(data.sld_real_values.size(), data.zmin, data.zmax); - sldData->item<FixedBinAxisItem>(Data1DItem::T_AXIS) - ->setParameters(data.sld_real_values.size(), data.zmin, data.zmax); - sldData->setValues(data.sld_real_values); -} - -JobItem* JobModel::jobItem() const -{ - return Utils::TopItem<JobItem>(this); -} - -} // namespace gui2 diff --git a/gui2/model/jobmodel.h b/gui2/model/jobmodel.h deleted file mode 100644 index 929c385b51ea3c8641345c2cd5b1fb86f3f66d9d..0000000000000000000000000000000000000000 --- a/gui2/model/jobmodel.h +++ /dev/null @@ -1,58 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/model/jobmodel.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_MODEL_JOBMODEL_H -#define BORNAGAIN_GUI2_MODEL_JOBMODEL_H - -#include "darefl_export.h" -#include "mvvm/model/sessionmodel.h" - -namespace ModelView { -class GraphViewportItem; -class GraphItem; -} // namespace ModelView - -namespace gui2 { - -class JobItem; -class CanvasItem; -struct SimulationResult; -struct SLDProfile; - -//! The model to store results of (possibly) multiple reflectometry simulation, and all -//! viewports, representing various graphs in QuickSimEditor widgets. - -class DAREFLCORE_EXPORT JobModel : public ModelView::SessionModel { -public: - JobModel(std::shared_ptr<ModelView::ItemPool> pool = {}); - - ModelView::GraphViewportItem* sldViewport() const; - - CanvasItem* specularViewport() const; - - ModelView::GraphViewportItem* diffViewport() const; - - void updateReferenceGraph(const ModelView::GraphItem* graph); - - void updateSpecularData(const SimulationResult& data); - - void updateSLDProfile(const SLDProfile& data); - -private: - JobItem* jobItem() const; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_MODEL_JOBMODEL_H diff --git a/gui2/model/materialitems.cpp b/gui2/model/materialitems.cpp deleted file mode 100644 index 36a6bd2aa517884983d123151c4093a6e10bbe9f..0000000000000000000000000000000000000000 --- a/gui2/model/materialitems.cpp +++ /dev/null @@ -1,82 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/model/materialitems.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/model/materialitems.h" -#include "gui2/model/item_constants.h" -#include "mvvm/model/externalproperty.h" -#include "mvvm/model/itemutils.h" -#include <QColor> - -using namespace ModelView; - -namespace gui2 { - -MaterialContainerItem::MaterialContainerItem() - : ModelView::CompoundItem(GUI::Constants::MaterialContainerItemType) -{ - registerTag(TagInfo::universalTag(T_MATERIALS, {GUI::Constants::SLDMaterialItemType}), - /*set_as_default*/ true); -} - -// ---------------------------------------------------------------------------- - -MaterialBaseItem::MaterialBaseItem(const std::string& model_type) - : ModelView::CompoundItem(model_type) -{ - addProperty(P_COLOR, QColor(Qt::green))->setDisplayName("Color"); - addProperty(P_NAME, "Unnamed")->setDisplayName("Name"); -} - -//! Returns ExternalProperty representing this material. - -ModelView::ExternalProperty MaterialBaseItem::external_property() const -{ - QColor color = Utils::HasTag(*this, P_COLOR) ? property<QColor>(P_COLOR) : QColor(Qt::red); - std::string name = Utils::HasTag(*this, P_NAME) ? property<std::string>(P_NAME) : ""; - return ModelView::ExternalProperty(name, color, identifier()); -} - -/*! Creates mag. field-related properties. - * Should be called from descendants' constructors in order - * to preserve view-oriented property sequence. - * The same can be achieved with a proper - * ModelView::RowStrategyInterface::constructRow - * implementation. - */ -void MaterialBaseItem::init_magnetic_field() -{ - addProperty(P_H_X, 0.0)->setDisplayName("H, x"); - addProperty(P_H_Y, 0.0)->setDisplayName("H, y"); - addProperty(P_H_Z, 0.0)->setDisplayName("H, z"); -} - -// ---------------------------------------------------------------------------- - -SLDMaterialItem::SLDMaterialItem() : MaterialBaseItem(GUI::Constants::SLDMaterialItemType) -{ - addProperty(P_SLD_REAL, 1e-06)->setDisplayName("Re(SLD)")->setLimits(RealLimits::limitless()); - addProperty(P_SLD_IMAG, 1e-08)->setDisplayName("Im(SLD)")->setLimits(RealLimits::limitless()); - init_magnetic_field(); -} - -void SLDMaterialItem::set_properties(const std::string& name, const QColor& color, double real, - double imag) -{ - setProperty(P_NAME, name); - setProperty(P_COLOR, color); - setProperty(P_SLD_REAL, real); - setProperty(P_SLD_IMAG, imag); -} - -} // namespace gui2 diff --git a/gui2/model/materialitems.h b/gui2/model/materialitems.h deleted file mode 100644 index fb3f76730556e5c2f1100f832339d592234cdc6a..0000000000000000000000000000000000000000 --- a/gui2/model/materialitems.h +++ /dev/null @@ -1,69 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/model/materialitems.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_MODEL_MATERIALITEMS_H -#define BORNAGAIN_GUI2_MODEL_MATERIALITEMS_H - -//! materialitems.h -//! Collection of materials to populate MaterialModel. - -#include "darefl_export.h" -#include "mvvm/model/compounditem.h" - -namespace ModelView { -class ExternalProperty; -} - -namespace gui2 { - -//! Container to hold MaterialItems. - -class DAREFLCORE_EXPORT MaterialContainerItem : public ModelView::CompoundItem { -public: - static inline const std::string T_MATERIALS = "T_MATERIALS"; - MaterialContainerItem(); -}; - -//! Base class with all materials with name and color defined. - -class DAREFLCORE_EXPORT MaterialBaseItem : public ModelView::CompoundItem { -public: - static inline const std::string P_COLOR = "P_COLOR"; - static inline const std::string P_NAME = "P_NAME"; - static inline const std::string P_H_X = "P_H_X"; - static inline const std::string P_H_Y = "P_H_Y"; - static inline const std::string P_H_Z = "P_H_Z"; - - ModelView::ExternalProperty external_property() const; - -protected: - MaterialBaseItem(const std::string& model_type); - void init_magnetic_field(); -}; - -//! Represents material based on scattering length density. - -class DAREFLCORE_EXPORT SLDMaterialItem : public MaterialBaseItem { -public: - static inline const std::string P_SLD_REAL = "P_SLD_REAL"; - static inline const std::string P_SLD_IMAG = "P_SLD_IMAG"; - - SLDMaterialItem(); - - void set_properties(const std::string& name, const QColor& color, double real, double imag); -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_MODEL_MATERIALITEMS_H diff --git a/gui2/model/materialmodel.cpp b/gui2/model/materialmodel.cpp deleted file mode 100644 index a9b071c3fefeb50504c5e3488d7034ea3bb6600f..0000000000000000000000000000000000000000 --- a/gui2/model/materialmodel.cpp +++ /dev/null @@ -1,146 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/model/materialmodel.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/model/materialmodel.h" -#include "gui2/model/item_constants.h" -#include "gui2/model/materialitems.h" -#include "mvvm/model/externalproperty.h" -#include "mvvm/model/itemcatalogue.h" -#include "mvvm/widgets/widgetutils.h" -#include <QColor> - -using namespace ModelView; - -namespace { - -std::unique_ptr<ItemCatalogue> CreateItemCatalogue() -{ - auto result = std::make_unique<ModelView::ItemCatalogue>(); - result->registerItem<gui2::MaterialContainerItem>(); - result->registerItem<gui2::SLDMaterialItem>(); - return result; -} - -const double rho_si = 2.0704e-06; -const double mu_si = 5.96e-07; - -const double rho_default = 9.4245e-06; -const double mu_default = 0.0; - -const std::string air_material_name = "Air"; -const std::string substrate_material_name = "Si"; -const std::string default_material_name = "Default"; - -//! Returns map of good looking colors for standard material names. - -std::map<std::string, QColor> name_to_color_map() -{ - std::map<std::string, QColor> result = {{air_material_name, QColor(179, 242, 255)}, - {substrate_material_name, QColor(205, 102, 0)}, - {default_material_name, QColor(Qt::green)}}; - return result; -} - -QColor suggestMaterialColor(const std::string& name) -{ - static auto color_map = name_to_color_map(); - auto it = color_map.find(name); - return it != color_map.end() ? it->second : Utils::RandomColor(); -} - -} // namespace - -namespace gui2 { - -MaterialModel::MaterialModel(std::shared_ptr<ModelView::ItemPool> pool) - : SessionModel("MaterialModel", pool) -{ - init_model(); -} - -//! Returns vector of properties representing possible choice of materials for the given container. -//! Here we assume that all materials seats in top level material containers. -//! If no container_id was given, the very first container is examined. - -// TODO Simplify and cover with unit tests. - -std::vector<ExternalProperty> MaterialModel::material_data(std::string container_id) const -{ - std::vector<ExternalProperty> result; - const auto containers = rootItem()->children(); - if (!containers.empty() && container_id.empty()) - container_id = topItem<MaterialContainerItem>()->identifier(); - - for (auto container : containers) { - if (container->identifier() != container_id) - continue; - for (auto item : container->children()) { - if (auto material = dynamic_cast<MaterialBaseItem*>(item)) - result.push_back(material->external_property()); - } - } - return result; -} - -//! Returns property from given material id. - -ExternalProperty MaterialModel::material_property(const std::string& id) -{ - for (const auto& prop : material_data()) - if (prop.identifier() == id) - return prop; - - return ExternalProperty::undefined(); -} - -//! Clones material and adds it at the bottom of MaterialContainerItem. - -MaterialBaseItem* MaterialModel::cloneMaterial(const MaterialBaseItem* item) -{ - auto tagrow = item->tagRow().next(); - return static_cast<MaterialBaseItem*>(SessionModel::copyItem(item, item->parent(), tagrow)); -} - -//! Adds default material. - -SLDMaterialItem* MaterialModel::addDefaultMaterial(const ModelView::TagRow& tagrow) -{ - auto material = insertItem<SLDMaterialItem>(materialContainer(), tagrow); - material->set_properties("Default", QColor(Qt::green), rho_default, mu_default); - return material; -} - -//! Populates the model with some default content. - -void MaterialModel::init_model() -{ - setItemCatalogue(CreateItemCatalogue()); - - auto container = insertItem<MaterialContainerItem>(); - auto material = insertItem<SLDMaterialItem>(container); - material->set_properties(air_material_name, suggestMaterialColor(air_material_name), 0.0, 0.0); - material = insertItem<SLDMaterialItem>(container); - material->set_properties(default_material_name, suggestMaterialColor(default_material_name), - rho_default, mu_default); - material = insertItem<SLDMaterialItem>(container); - material->set_properties(substrate_material_name, suggestMaterialColor(substrate_material_name), - rho_si, mu_si); -} - -MaterialContainerItem* MaterialModel::materialContainer() -{ - return topItem<MaterialContainerItem>(); -} - -} // namespace gui2 diff --git a/gui2/model/materialmodel.h b/gui2/model/materialmodel.h deleted file mode 100644 index e3baab611d795baaee1413c778d7a087b6da046f..0000000000000000000000000000000000000000 --- a/gui2/model/materialmodel.h +++ /dev/null @@ -1,54 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/model/materialmodel.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_MODEL_MATERIALMODEL_H -#define BORNAGAIN_GUI2_MODEL_MATERIALMODEL_H - -#include "darefl_export.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/model/tagrow.h" -#include <vector> - -namespace ModelView { -class ExternalProperty; -} - -namespace gui2 { - -class MaterialBaseItem; -class MaterialContainerItem; -class SLDMaterialItem; - -//! Model to hold MaterialItems. - -class DAREFLCORE_EXPORT MaterialModel : public ModelView::SessionModel { -public: - MaterialModel(std::shared_ptr<ModelView::ItemPool> pool = {}); - - std::vector<ModelView::ExternalProperty> material_data(std::string container_id = "") const; - - ModelView::ExternalProperty material_property(const std::string& id); - - MaterialBaseItem* cloneMaterial(const MaterialBaseItem* item); - - SLDMaterialItem* addDefaultMaterial(const ModelView::TagRow& tagrow = {}); - -private: - void init_model(); - MaterialContainerItem* materialContainer(); -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_MODEL_MATERIALMODEL_H diff --git a/gui2/model/materialpropertycontroller.cpp b/gui2/model/materialpropertycontroller.cpp deleted file mode 100644 index 0088c25043eb99538917048c21c45abb5d1c318d..0000000000000000000000000000000000000000 --- a/gui2/model/materialpropertycontroller.cpp +++ /dev/null @@ -1,50 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/model/materialpropertycontroller.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/model/materialpropertycontroller.h" -#include "gui2/model/materialmodel.h" -#include "gui2/model/sampleitems.h" -#include "gui2/model/samplemodel.h" -#include "mvvm/model/externalproperty.h" -#include "mvvm/model/modelutils.h" - -using namespace ModelView; - -namespace gui2 { - -MaterialPropertyController::MaterialPropertyController(MaterialModel* material_model, - SampleModel* sample_model) - : ModelListener(material_model), m_sample_model(sample_model) -{ - setOnDataChange([this](auto, auto) { update_all(); }); - setOnItemInserted([this](auto, auto) { update_all(); }); - setOnItemRemoved([this](auto, auto) { update_all(); }); - setOnModelReset([this](auto) { update_all(); }); - - update_all(); -} - -//! Updates all material properties in LayerItems to get new material colors and labels. - -void MaterialPropertyController::update_all() -{ - for (auto layer : Utils::FindItems<LayerItem>(m_sample_model)) { - auto property = layer->property<ExternalProperty>(LayerItem::P_MATERIAL); - auto updated = model()->material_property(property.identifier()); - if (property != updated) - layer->setProperty(LayerItem::P_MATERIAL, updated); - } -} - -} // namespace gui2 diff --git a/gui2/model/materialpropertycontroller.h b/gui2/model/materialpropertycontroller.h deleted file mode 100644 index aaf8215105aac3f4cceb9839e97fae3ae7461a31..0000000000000000000000000000000000000000 --- a/gui2/model/materialpropertycontroller.h +++ /dev/null @@ -1,41 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/model/materialpropertycontroller.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_MODEL_MATERIALPROPERTYCONTROLLER_H -#define BORNAGAIN_GUI2_MODEL_MATERIALPROPERTYCONTROLLER_H - -#include "darefl_export.h" -#include "mvvm/signals/modellistener.h" - -namespace gui2 { - -class SampleModel; -class MaterialModel; - -//! Listens for all changes in material model and updates properties in SampleModel. - -class DAREFLCORE_EXPORT MaterialPropertyController - : public ModelView::ModelListener<MaterialModel> { -public: - MaterialPropertyController(MaterialModel* material_model, SampleModel* sample_model); - -private: - void update_all(); - - SampleModel* m_sample_model{nullptr}; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_MODEL_MATERIALPROPERTYCONTROLLER_H diff --git a/gui2/model/modelutils.cpp b/gui2/model/modelutils.cpp deleted file mode 100644 index ae871453cf348be9d2afb334f560528c55072cf9..0000000000000000000000000000000000000000 --- a/gui2/model/modelutils.cpp +++ /dev/null @@ -1,95 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/model/modelutils.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/model/modelutils.h" -#include "gui2/model/experimentaldatamodel.h" -#include "mvvm/model/externalproperty.h" -#include "mvvm/model/modelutils.h" -#include "mvvm/standarditems/axisitems.h" -#include "mvvm/standarditems/data1ditem.h" -#include "mvvm/standarditems/graphitem.h" - -namespace { -bool areCompatibleAxes(const ModelView::Data1DItem& item1, const ModelView::Data1DItem& item2) -{ - // TODO consider moving the logic on board of Data1DItem, consider implement getAxis() getter. - auto axis1 = item1.getItem(ModelView::Data1DItem::T_AXIS); - auto axis2 = item2.getItem(ModelView::Data1DItem::T_AXIS); - if (!axis1 || !axis2) - return false; - - return axis1->modelType() == axis2->modelType(); -} - -} // namespace - -namespace gui2 { - -ModelView::ExternalProperty Utils::CreateProperty(const ModelView::GraphItem* graph) -{ - std::string name = graph->parent()->displayName() + "/" + graph->displayName(); - auto colorName = QString::fromStdString(graph->colorName()); - return ModelView::ExternalProperty(name, QColor(colorName), graph->identifier()); -} - -std::vector<ModelView::ExternalProperty> Utils::CreateGraphProperties(ExperimentalDataModel* model) -{ - std::vector<ModelView::ExternalProperty> result; - for (auto graph : ModelView::Utils::FindItems<ModelView::GraphItem>(model)) - result.push_back(Utils::CreateProperty(graph)); - return result; -} - -// FIXME unit tests -ModelView::ExternalProperty -Utils::FindProperty(const std::vector<ModelView::ExternalProperty>& properties, - const std::string& id) -{ - for (const auto& prop : properties) - if (prop.identifier() == id) - return prop; - - return ModelView::ExternalProperty::undefined(); -} - -std::vector<double> Utils::CreateDiffVector(const std::vector<double>& a, - const std::vector<double>& b) -{ - size_t length = std::min(a.size(), b.size()); - std::vector<double> result(length, 0.0); - for (size_t i = 0; i < length; ++i) { - double denom = a[i] + b[i]; - result[i] = denom != 0.0 ? 2 * (a[i] - b[i]) / (a[i] + b[i]) : 0.0; - } - return result; -} - -void Utils::SetDifference(const ModelView::Data1DItem* data1, const ModelView::Data1DItem* data2, - ModelView::Data1DItem* target) -{ - if (!areCompatibleAxes(*data1, *data2) || !areCompatibleAxes(*data1, *target)) - return; - - // We expect same number of points to caclulate the difference graph. - if (data1->binCenters().size() != data2->binCenters().size()) - return; - - if (data1->binCenters() != target->binCenters()) { - target->item<ModelView::PointwiseAxisItem>(ModelView::Data1DItem::T_AXIS) - ->setParameters(data1->binCenters()); - } - target->setValues(CreateDiffVector(data1->binValues(), data2->binValues())); -} - -} // namespace gui2 diff --git a/gui2/model/modelutils.h b/gui2/model/modelutils.h deleted file mode 100644 index 66815d8b6ce0b19299d7d60001889ae30ba02173..0000000000000000000000000000000000000000 --- a/gui2/model/modelutils.h +++ /dev/null @@ -1,59 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/model/modelutils.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_MODEL_MODELUTILS_H -#define BORNAGAIN_GUI2_MODEL_MODELUTILS_H - -#include "darefl_export.h" -#include <string> -#include <vector> - -namespace ModelView { -class GraphItem; -class Data1DItem; -class ExternalProperty; -} // namespace ModelView - -namespace gui2 { - -class ExperimentalDataModel; - -namespace Utils { - -//! Returns property representing given graph. -//! Used to link with the graph from various editors. -DAREFLCORE_EXPORT ModelView::ExternalProperty CreateProperty(const ModelView::GraphItem* graph); - -//! Returns vector of properties representing GraphItem content of the model. -DAREFLCORE_EXPORT std::vector<ModelView::ExternalProperty> -CreateGraphProperties(ExperimentalDataModel* model); - -//! Finds the property with the same `id` in given vector and returns it. -DAREFLCORE_EXPORT ModelView::ExternalProperty -FindProperty(const std::vector<ModelView::ExternalProperty>& properties, const std::string& id); - -//! Returns vector representing elementwise 2*(a-b)/(a+b) difference over two vectors. -//! Resulting vector will have size equal to min(a.size(), b.size()) -DAREFLCORE_EXPORT std::vector<double> CreateDiffVector(const std::vector<double>& a, - const std::vector<double>& b); - -//! Make target item represent difference of two Data1DItems. Target will get an axis as in data1. -DAREFLCORE_EXPORT void SetDifference(const ModelView::Data1DItem* data1, - const ModelView::Data1DItem* data2, - ModelView::Data1DItem* target); -} // namespace Utils - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_MODEL_MODELUTILS_H diff --git a/gui2/model/sampleitems.cpp b/gui2/model/sampleitems.cpp deleted file mode 100644 index dfd84641890823dfd87da3eebe90e88dc86dae61..0000000000000000000000000000000000000000 --- a/gui2/model/sampleitems.cpp +++ /dev/null @@ -1,98 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/model/sampleitems.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/model/sampleitems.h" -#include "gui2/model/item_constants.h" -#include "gui2/model/materialitems.h" -#include "gui2/model/materialmodel.h" -#include "mvvm/model/externalproperty.h" -#include "mvvm/signals/itemmapper.h" -#include <QVariant> - -namespace gui2 { - -RoughnessItem::RoughnessItem() : ModelView::CompoundItem(GUI::Constants::RoughnessItemType) -{ - addProperty(P_SIGMA, 0.0)->setDisplayName("Sigma"); - addProperty(P_HURST, 0.5)->setDisplayName("Hurst"); - addProperty(P_LATERAL_CORR_LENGTH, 0.0)->setDisplayName("Correlation length"); -} - -//! --------------------------------------------------------------------------- - -LayerItem::LayerItem() : ModelView::CompoundItem(GUI::Constants::LayerItemType) -{ - addProperty(P_NAME, "Unnamed")->setDisplayName("Name"); - addProperty(P_MATERIAL, ModelView::ExternalProperty::undefined())->setDisplayName("Material"); - addProperty(P_THICKNESS, 0.0) - ->setDisplayName("Thickness") - ->setToolTip("Layer thickness in [nm]"); - addProperty<RoughnessItem>(P_ROUGHNESS); -} - -//! --------------------------------------------------------------------------- - -MultiLayerItem::MultiLayerItem() : ModelView::CompoundItem(GUI::Constants::MultiLayerItemType) -{ - addProperty(P_NAME, "Unnamed")->setDisplayName("Name"); - addProperty(P_NREPETITIONS, 1)->setDisplayName("Nr."); - std::vector<std::string> allowed_child = {GUI::Constants::MultiLayerItemType, - GUI::Constants::LayerItemType}; - registerTag(ModelView::TagInfo::universalTag(T_LAYERS, allowed_child), /*set_default*/ true); - - void update_layer_appearance(); -} - -void MultiLayerItem::activate() -{ - auto on_item_inserted = [this](ModelView::SessionItem*, ModelView::TagRow) { - update_layer_appearance(); - }; - mapper()->setOnItemInserted(on_item_inserted, this); - - auto on_item_removed = [this](ModelView::SessionItem*, ModelView::TagRow) { - update_layer_appearance(); - }; - mapper()->setOnItemRemoved(on_item_removed, this); -} - -//! Sets thickness property of top and bottom layers to disabled state. -//! Reset thickness of top and bottom layer to 0. - -void MultiLayerItem::update_layer_appearance() -{ - // FIXME restore correct enabling/disabling of thickness and roughness of top and bottom layers - // FIXME together with tests in layeritems.test.cpp - if (parent() != model()->rootItem()) - return; - - auto layers = items<LayerItem>(T_LAYERS); - for (auto it = layers.begin(); it != layers.end(); ++it) { - if (it == layers.begin()) { - (*it)->getItem(LayerItem::P_THICKNESS)->setEnabled(false); - (*it) - ->getItem(LayerItem::P_ROUGHNESS) - ->getItem(RoughnessItem::P_SIGMA) - ->setEnabled(false); - (*it)->setProperty(LayerItem::P_THICKNESS, 0.0); - } else if (std::next(it) == layers.end()) { - (*it)->getItem(LayerItem::P_THICKNESS)->setEnabled(false); - (*it)->setProperty(LayerItem::P_THICKNESS, 0.0); - } else { - (*it)->getItem(LayerItem::P_THICKNESS)->setEnabled(true); - } - } -} - -} // namespace gui2 diff --git a/gui2/model/sampleitems.h b/gui2/model/sampleitems.h deleted file mode 100644 index 5e086d98011b6ad25874f0a8267e84f839be6c34..0000000000000000000000000000000000000000 --- a/gui2/model/sampleitems.h +++ /dev/null @@ -1,67 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/model/sampleitems.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_MODEL_SAMPLEITEMS_H -#define BORNAGAIN_GUI2_MODEL_SAMPLEITEMS_H - -//! @file gui2/model/sampleitems.h -//! Collection of layer and multi-layer items to populate SampleModel. - -#include "darefl_export.h" -#include "mvvm/model/compounditem.h" - -namespace gui2 { - -//! Item to represent the roughness of the layer. - -class DAREFLCORE_EXPORT RoughnessItem : public ModelView::CompoundItem { -public: - static inline const std::string P_SIGMA = "P_SIGMA"; - static inline const std::string P_HURST = "P_HURST"; - static inline const std::string P_LATERAL_CORR_LENGTH = "P_LATERAL_CORR_LENGTH"; - - RoughnessItem(); -}; - -//! Layer with name, thickness and reference to material. - -class DAREFLCORE_EXPORT LayerItem : public ModelView::CompoundItem { -public: - static inline const std::string P_NAME = "P_NAME"; - static inline const std::string P_MATERIAL = "P_MATERIAL"; - static inline const std::string P_THICKNESS = "P_THICKNESS"; - static inline const std::string P_ROUGHNESS = "P_ROUGHNESS"; - - LayerItem(); -}; - -//! Multi layer capable of holding layers and other multi-layers. - -class DAREFLCORE_EXPORT MultiLayerItem : public ModelView::CompoundItem { -public: - static inline const std::string P_NAME = "P_NAME"; - static inline const std::string T_LAYERS = "T_LAYERS"; - static inline const std::string P_NREPETITIONS = "P_NREPETITIONS"; - - MultiLayerItem(); - - void activate() override; - -private: - void update_layer_appearance(); -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_MODEL_SAMPLEITEMS_H diff --git a/gui2/model/samplemodel.cpp b/gui2/model/samplemodel.cpp deleted file mode 100644 index fde1cb7a1ef31996ca52246a7d5614a57c2a0e70..0000000000000000000000000000000000000000 --- a/gui2/model/samplemodel.cpp +++ /dev/null @@ -1,56 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/model/samplemodel.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/model/samplemodel.h" -#include "gui2/model/sampleitems.h" -#include "mvvm/model/itemcatalogue.h" - -using namespace ModelView; - -namespace gui2 { - -namespace { -std::unique_ptr<ItemCatalogue> CreateItemCatalogue() -{ - auto result = std::make_unique<ItemCatalogue>(); - result->registerItem<MultiLayerItem>(); - result->registerItem<LayerItem>(); - result->registerItem<RoughnessItem>(); - return result; -} -} // namespace - -SampleModel::SampleModel(std::shared_ptr<ModelView::ItemPool> pool) - : SessionModel("SampleModel", pool) -{ - setItemCatalogue(CreateItemCatalogue()); -} - -//! Populate the model with default MultiLayer with 3 layers. - -void SampleModel::create_default_multilayer() -{ - auto multilayer = insertItem<MultiLayerItem>(); - - auto top = insertItem<LayerItem>(multilayer); - top->setProperty(LayerItem::P_NAME, std::string("Ambient")); - auto middle = insertItem<LayerItem>(multilayer); - middle->setProperty(LayerItem::P_NAME, std::string("Middle")); - auto substrate = insertItem<LayerItem>(multilayer); - substrate->setProperty(LayerItem::P_NAME, std::string("Substrate")); - - middle->setProperty(LayerItem::P_THICKNESS, 42.0); -} - -} // namespace gui2 diff --git a/gui2/model/samplemodel.h b/gui2/model/samplemodel.h deleted file mode 100644 index 508bab2125a7edb00377ad19de4b83a9f957d48d..0000000000000000000000000000000000000000 --- a/gui2/model/samplemodel.h +++ /dev/null @@ -1,33 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/model/samplemodel.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_MODEL_SAMPLEMODEL_H -#define BORNAGAIN_GUI2_MODEL_SAMPLEMODEL_H - -#include "darefl_export.h" -#include "mvvm/model/sessionmodel.h" - -namespace gui2 { - -//! Model to hold layers and multi-layers. -class DAREFLCORE_EXPORT SampleModel : public ModelView::SessionModel { -public: - SampleModel(std::shared_ptr<ModelView::ItemPool> pool = {}); - - void create_default_multilayer(); -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_MODEL_SAMPLEMODEL_H diff --git a/gui2/quicksimeditor/CMakeLists.txt b/gui2/quicksimeditor/CMakeLists.txt deleted file mode 100644 index b65f4ddec909a6e1c0c89630f451b72442dd09fe..0000000000000000000000000000000000000000 --- a/gui2/quicksimeditor/CMakeLists.txt +++ /dev/null @@ -1,27 +0,0 @@ -target_sources(${library_name} PRIVATE - custombeampropertyeditorfactory.cpp - custombeampropertyeditorfactory.h - instrumentpropertyeditor.cpp - instrumentpropertyeditor.h - jobmanager.cpp - jobmanager.h - materialprofile.cpp - materialprofile.h - profilehelper.cpp - profilehelper.h - quicksim_types.h - quicksimcontroller.cpp - quicksimcontroller.h - quicksimeditor.cpp - quicksimeditor.h - quicksimeditortoolbar.cpp - quicksimeditortoolbar.h - quicksimutils.cpp - quicksimutils.h - simplotcontroller.cpp - simplotcontroller.h - simplotwidget.cpp - simplotwidget.h - speculartoysimulation.cpp - speculartoysimulation.h -) diff --git a/gui2/quicksimeditor/custombeampropertyeditorfactory.cpp b/gui2/quicksimeditor/custombeampropertyeditorfactory.cpp deleted file mode 100644 index 9a88cd354789d941ff9d5e5cca658c402e201be2..0000000000000000000000000000000000000000 --- a/gui2/quicksimeditor/custombeampropertyeditorfactory.cpp +++ /dev/null @@ -1,68 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/quicksimeditor/custombeampropertyeditorfactory.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/quicksimeditor/custombeampropertyeditorfactory.h" -#include "gui2/model/applicationmodels.h" -#include "gui2/model/experimentaldataitems.h" -#include "gui2/model/experimentaldatamodel.h" -#include "gui2/model/materialmodel.h" -#include "gui2/model/modelutils.h" -#include "mvvm/editors/externalpropertycomboeditor.h" -#include "mvvm/model/externalproperty.h" -#include "mvvm/model/modelutils.h" -#include "mvvm/standarditems/graphitem.h" -#include <QModelIndex> -#include <algorithm> - -using namespace ModelView; - -namespace gui2 { - -namespace { - -//! Returns vector of ExternalProperty representing imported graphs. -//! Use "Undefined graph" as a first item in a list. - -std::vector<ModelView::ExternalProperty> available_graph_properties(ExperimentalDataModel* model) -{ - std::vector<ModelView::ExternalProperty> result{ExternalProperty::undefined()}; - auto properties = Utils::CreateGraphProperties(model); - std::copy(properties.begin(), properties.end(), std::back_inserter(result)); - return result; -} -} // namespace - -CustomBeamGUI::View::PropertyEditorFactory::~CustomBeamPropertyEditorFactory() = default; - -CustomBeamGUI::View::PropertyEditorFactory::CustomBeamPropertyEditorFactory( - ApplicationModels* models) - : m_models(models) -{ -} - -std::unique_ptr<CustomEditor> -CustomBeamGUI::View::PropertyEditorFactory::createEditor(const QModelIndex& index) const -{ - auto value = index.data(Qt::EditRole); - if (ModelView::Utils::IsExtPropertyVariant(value)) { - auto choice_callback = [this]() { - return available_graph_properties(m_models->experimentalDataModel()); - }; - return std::make_unique<ExternalPropertyComboEditor>(choice_callback); - } else { - return DefaultEditorFactory::createEditor(index); - } -} - -} // namespace gui2 diff --git a/gui2/quicksimeditor/custombeampropertyeditorfactory.h b/gui2/quicksimeditor/custombeampropertyeditorfactory.h deleted file mode 100644 index 8ec16b4a53aa71529ca4da671d20e2ba6a95541f..0000000000000000000000000000000000000000 --- a/gui2/quicksimeditor/custombeampropertyeditorfactory.h +++ /dev/null @@ -1,41 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/quicksimeditor/custombeampropertyeditorfactory.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_QUICKSIMEDITOR_CUSTOMBEAMPROPERTYEDITORFACTORY_H -#define BORNAGAIN_GUI2_QUICKSIMEDITOR_CUSTOMBEAMPROPERTYEDITORFACTORY_H - -#include "darefl_export.h" -#include "mvvm/editors/defaulteditorfactory.h" - -namespace gui2 { - -class ApplicationModels; - -//! Custom editor factory for LayerTreeView. Substitutes default ExternalProperty editor -//! with custom one, which will offer the choice between all defined materials. - -class DAREFLCORE_EXPORT CustomBeamPropertyEditorFactory : public ModelView::DefaultEditorFactory { -public: - CustomBeamPropertyEditorFactory(ApplicationModels* models); - ~CustomBeamPropertyEditorFactory(); - - std::unique_ptr<ModelView::CustomEditor> createEditor(const QModelIndex& index) const; - -private: - ApplicationModels* m_models{nullptr}; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_QUICKSIMEDITOR_CUSTOMBEAMPROPERTYEDITORFACTORY_H diff --git a/gui2/quicksimeditor/instrumentpropertyeditor.cpp b/gui2/quicksimeditor/instrumentpropertyeditor.cpp deleted file mode 100644 index 22b4a78702eb5667ef6adb460af1024abc5faf84..0000000000000000000000000000000000000000 --- a/gui2/quicksimeditor/instrumentpropertyeditor.cpp +++ /dev/null @@ -1,65 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/quicksimeditor/instrumentpropertyeditor.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/quicksimeditor/instrumentpropertyeditor.h" -#include "gui2/mainwindow/styleutils.h" -#include "gui2/model/applicationmodels.h" -#include "gui2/model/instrumentitems.h" -#include "gui2/model/instrumentmodel.h" -#include "gui2/quicksimeditor/custombeampropertyeditorfactory.h" -#include "mvvm/viewmodel/viewmodeldelegate.h" -#include "mvvm/widgets/propertytreeview.h" -#include <QTreeView> -#include <QVBoxLayout> - -using namespace ModelView; - -namespace gui2 { - -InstrumentPropertyEditor::InstrumentPropertyEditor(QWidget* parent) - : QWidget(parent), m_beamPropertyEditor(new ModelView::PropertyTreeView) - -{ - auto layout = new QVBoxLayout(this); - layout->addWidget(m_beamPropertyEditor); -} - -InstrumentPropertyEditor::~InstrumentPropertyEditor() = default; - -void InstrumentPropertyEditor::setModels(ApplicationModels* models) -{ - auto instrument = models->instrumentModel()->topItem<SpecularInstrumentItem>(); - - auto delegate = std::make_unique<ViewModelDelegate>(); - delegate->setEditorFactory(std::make_unique<CustomBeamPropertyEditorFactory>(models)); - m_beamPropertyEditor->setViewModelDelegate(std::move(delegate)); - - m_beamPropertyEditor->setItem( - instrument->item<SpecularBeamItem>(SpecularInstrumentItem::P_BEAM)); - - m_beamPropertyEditor->treeView()->setRootIsDecorated(true); - m_beamPropertyEditor->treeView()->expandAll(); -} - -QSize InstrumentPropertyEditor::sizeHint() const -{ - return GUI::Utils::Style::DockSizeHint(); -} - -QSize InstrumentPropertyEditor::minimumSizeHint() const -{ - return GUI::Utils::Style::DockMinimumSizeHint(); -} - -} // namespace gui2 diff --git a/gui2/quicksimeditor/instrumentpropertyeditor.h b/gui2/quicksimeditor/instrumentpropertyeditor.h deleted file mode 100644 index 78c1bb72cdab27717c2ba850278b2788b4ff8a07..0000000000000000000000000000000000000000 --- a/gui2/quicksimeditor/instrumentpropertyeditor.h +++ /dev/null @@ -1,50 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/quicksimeditor/instrumentpropertyeditor.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_QUICKSIMEDITOR_INSTRUMENTPROPERTYEDITOR_H -#define BORNAGAIN_GUI2_QUICKSIMEDITOR_INSTRUMENTPROPERTYEDITOR_H - -#include "darefl_export.h" -#include <QWidget> - -namespace ModelView { -class PropertyTreeView; -} - -namespace gui2 { - -class ApplicationModels; - -//! Widget with InstrumentItem properties. -//! Used to modify q-scan parameters, located under QuickSimEditor. - -class DAREFLCORE_EXPORT InstrumentPropertyEditor : public QWidget { - Q_OBJECT - -public: - InstrumentPropertyEditor(QWidget* parent = nullptr); - ~InstrumentPropertyEditor(); - - void setModels(ApplicationModels* models); - - QSize sizeHint() const override; - QSize minimumSizeHint() const override; - -private: - ModelView::PropertyTreeView* m_beamPropertyEditor{nullptr}; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_QUICKSIMEDITOR_INSTRUMENTPROPERTYEDITOR_H diff --git a/gui2/quicksimeditor/jobmanager.cpp b/gui2/quicksimeditor/jobmanager.cpp deleted file mode 100644 index c9e10661f6a9ed9d2d11e15410e41056d9d349c4..0000000000000000000000000000000000000000 --- a/gui2/quicksimeditor/jobmanager.cpp +++ /dev/null @@ -1,101 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/quicksimeditor/jobmanager.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/quicksimeditor/jobmanager.h" -#include "gui2/quicksimeditor/speculartoysimulation.h" - -namespace gui2 { - -JobManager::JobManager(QObject* parent) : QObject(parent), m_isRunning(true) -{ - // starting thread to run consequent simulations - m_simThread = std::thread{&JobManager::wait_and_run, this}; -} - -JobManager::~JobManager() -{ - m_isRunning = false; - // making stack throw to stops waiting in JobManager::wait_and_run - m_requestedInputValues.stop(); - m_simThread.join(); -} - -//! Returns vector representing results of a simulation. - -SimulationResult JobManager::simulationResult() -{ - auto result = m_simulationResult.try_pop(); - return result ? *result.get() : SimulationResult(); -} - -//! Performs simulation request. Given multislice will be stored in a stack of values to trigger -//! a waiting thread. - -void JobManager::requestSimulation(const multislice_t& multislice, - const std::vector<double>& qvalues, double intensity) -{ - // At this point, non-empty stack means that currently simulation thread is busy. - // Replacing top value in a stack, meaning that we are droping previous request. - SimulationInput input_data; - input_data.slice_data = multislice; - input_data.qvalues = qvalues; - input_data.intensity = intensity; - m_requestedInputValues.update_top(input_data); -} - -//! Processes interrupt request by setting corresponding flag. - -void JobManager::onInterruptRequest() -{ - m_interruptRequest = true; -} - -//! Performs concequent simulations for given simulation parameter. Waits for simulation input -//! parameter to appear in a stack, starts new simulation as soon as input data is ready. -//! Method is intended for execution in a thread. - -void JobManager::wait_and_run() -{ - while (m_isRunning) { - try { - // Waiting here for the value which we will use as simulation input parameter. - auto value = m_requestedInputValues.wait_and_pop(); - - // preparing simulation - SpecularToySimulation simulation(*value.get()); - auto on_progress = [this](int value) { - progressChanged(value); - return m_interruptRequest; - }; - simulation.setProgressCallback(on_progress); - - // running simulation - simulation.runSimulation(); - - // Saving simulation result, overwrite previous if exists. If at this point stack - // with results is not empty it means that plotting is disabled or running too slow. - m_simulationResult.update_top(simulation.simulationResult()); - simulationCompleted(); - - } catch (std::exception& ex) { - // Exception is thrown - // a) If waiting on stack was stopped my calling threadsafe_stack::stop. - // b) If simulation was interrupted via interrupt_request - m_interruptRequest = false; - progressChanged(0); - } - } -} - -} // namespace gui2 diff --git a/gui2/quicksimeditor/jobmanager.h b/gui2/quicksimeditor/jobmanager.h deleted file mode 100644 index 7341c1178425392259438cedc6d743f57686dc4a..0000000000000000000000000000000000000000 --- a/gui2/quicksimeditor/jobmanager.h +++ /dev/null @@ -1,57 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/quicksimeditor/jobmanager.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_QUICKSIMEDITOR_JOBMANAGER_H -#define BORNAGAIN_GUI2_QUICKSIMEDITOR_JOBMANAGER_H - -#include "darefl_export.h" -#include "gui2/quicksimeditor/quicksim_types.h" -#include "mvvm/utils/threadsafestack.h" -#include <QObject> - -namespace gui2 { - -//! Handles all thread activity for running job simulation in the background. - -class DAREFLCORE_EXPORT JobManager : public QObject { - Q_OBJECT - -public: - JobManager(QObject* parent = nullptr); - ~JobManager() override; - - SimulationResult simulationResult(); - -signals: - void progressChanged(int value); - void simulationCompleted(); - -public slots: - void requestSimulation(const multislice_t& multislice, const std::vector<double>& qvalues, - double intensity); - void onInterruptRequest(); - -private: - void wait_and_run(); - - std::thread m_simThread; - ModelView::threadsafe_stack<SimulationInput> m_requestedInputValues; - ModelView::threadsafe_stack<SimulationResult> m_simulationResult; - std::atomic<bool> m_isRunning; - bool m_interruptRequest{false}; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_QUICKSIMEDITOR_JOBMANAGER_H diff --git a/gui2/quicksimeditor/materialprofile.cpp b/gui2/quicksimeditor/materialprofile.cpp deleted file mode 100644 index 0b1e11836a51f28ad57095100be1792c95e36a41..0000000000000000000000000000000000000000 --- a/gui2/quicksimeditor/materialprofile.cpp +++ /dev/null @@ -1,51 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/quicksimeditor/materialprofile.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/quicksimeditor/materialprofile.h" -#include "gui2/quicksimeditor/profilehelper.h" -#include "gui2/quicksimeditor/quicksimutils.h" -#include <Resample/Slice/Slice.h> - -namespace gui2 { - -std::vector<complex_t> MaterialProfile::CalculateProfile(const multislice_t& multilayer, - int n_points, double z_min, double z_max) -{ - auto baSlices = Utils::createBornAgainSlices(multilayer); - ProfileHelper helper(baSlices); - std::vector<double> z_values = GenerateZValues(n_points, z_min, z_max); - return helper.calculateProfile(z_values); -} - -std::pair<double, double> -MaterialProfile::DefaultMaterialProfileLimits(const multislice_t& multilayer) -{ - auto baSlices = Utils::createBornAgainSlices(multilayer); - ProfileHelper helper(baSlices); - return helper.defaultLimits(); -} - -std::vector<double> MaterialProfile::GenerateZValues(int n_points, double z_min, double z_max) -{ - std::vector<double> result; - if (n_points < 1) - return result; - double step = n_points > 1 ? (z_max - z_min) / (n_points - 1) : 0.0; - for (int i = 0; i < n_points; ++i) { - result.push_back(z_min + i * step); - } - return result; -} - -} // namespace gui2 diff --git a/gui2/quicksimeditor/materialprofile.h b/gui2/quicksimeditor/materialprofile.h deleted file mode 100644 index 846eb8e94b97cd3a04f39d8be14eb9f287f63008..0000000000000000000000000000000000000000 --- a/gui2/quicksimeditor/materialprofile.h +++ /dev/null @@ -1,42 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/quicksimeditor/materialprofile.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_QUICKSIMEDITOR_MATERIALPROFILE_H -#define BORNAGAIN_GUI2_QUICKSIMEDITOR_MATERIALPROFILE_H - -#include "darefl_export.h" -#include "gui2/quicksimeditor/quicksim_types.h" - -namespace gui2 { - -//! Collection of methods borrowed from BornAgain for material profile calculations. - -namespace MaterialProfile { - -//! Calculate average material profile for given multilayer -DAREFLCORE_EXPORT std::vector<complex_t> CalculateProfile(const multislice_t& multilayer, - int n_points, double z_min, double z_max); - -//! Get default z limits for generating a material profile -DAREFLCORE_EXPORT std::pair<double, double> -DefaultMaterialProfileLimits(const multislice_t& multilayer); - -//! Generate z values (equidistant) for use in MaterialProfile -DAREFLCORE_EXPORT std::vector<double> GenerateZValues(int n_points, double z_min, double z_max); - -} // namespace MaterialProfile - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_QUICKSIMEDITOR_MATERIALPROFILE_H diff --git a/gui2/quicksimeditor/profilehelper.cpp b/gui2/quicksimeditor/profilehelper.cpp deleted file mode 100644 index 211e1649d412222b57a5a06e335961b7b399be0c..0000000000000000000000000000000000000000 --- a/gui2/quicksimeditor/profilehelper.cpp +++ /dev/null @@ -1,93 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/quicksimeditor/profilehelper.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/quicksimeditor/profilehelper.h" -#include <Resample/Slice/Slice.h> -#include <Sample/Interface/LayerRoughness.h> - -namespace { -const double prefactor = std::sqrt(2.0 / M_PI); -double Transition(double x, double sigma); -double TransitionTanh(double x); -} // namespace - -gui2::ProfileHelper::ProfileHelper(const SliceStack& sample) -{ - auto N = sample.size(); - m_materialdata.reserve(N); - if (N > 1) { - m_zlimits.reserve(N - 1); - m_sigmas.reserve(N - 1); - } - double bottom_z{0}; - for (size_t i = 0; i < N; ++i) { - m_materialdata.push_back(sample[i].material().materialData()); - bottom_z -= sample[i].thickness(); - if (i + 1 < N) { - m_zlimits.push_back(bottom_z); - auto sigma = 0.; - if (auto roughness = sample[i + 1].topRoughness()) - sigma = roughness->getSigma(); - - m_sigmas.push_back(sigma); - } - } -} - -// Note: for refractive index materials, the material interpolation actually happens at the level -// of n^2. To first order in delta and beta, this implies the same smooth interpolation of delta -// and beta, as is done here. -std::vector<complex_t> -gui2::ProfileHelper::calculateProfile(const std::vector<double>& z_values) const -{ - complex_t top_value = m_materialdata.size() ? m_materialdata[0] : 0.0; - std::vector<complex_t> result(z_values.size(), top_value); - for (size_t i = 0; i < m_zlimits.size(); ++i) { - auto sld_diff = m_materialdata[i + 1] - m_materialdata[i]; - for (size_t j = 0; j < z_values.size(); ++j) { - auto arg = (z_values[j] - m_zlimits[i]); - auto t = Transition(arg, m_sigmas[i]); - result[j] += sld_diff * t; - } - } - return result; -} - -std::pair<double, double> gui2::ProfileHelper::defaultLimits() const -{ - if (m_zlimits.size() < 1) - return {0.0, 0.0}; - double interface_span = m_zlimits.front() - m_zlimits.back(); - double default_margin = interface_span > 0.0 ? interface_span / 20.0 : 10.0; - double top_margin = m_sigmas.front() > 0.0 ? 5.0 * m_sigmas.front() : default_margin; - double bottom_margin = m_sigmas.back() > 0.0 ? 5.0 * m_sigmas.back() : default_margin; - double z_min = m_zlimits.back() - bottom_margin; - double z_max = m_zlimits.front() + top_margin; - return {z_min, z_max}; -} - -gui2::ProfileHelper::~ProfileHelper() = default; - -namespace { -double Transition(double x, double sigma) -{ - if (sigma <= 0.0) - return x < 0.0 ? 1.0 : 0.0; - return TransitionTanh(x / sigma); -} -double TransitionTanh(double x) -{ - return (1.0 - std::tanh(prefactor * x)) / 2.0; -} -} // namespace diff --git a/gui2/quicksimeditor/profilehelper.h b/gui2/quicksimeditor/profilehelper.h deleted file mode 100644 index 34b3bf93e566afc8e9b725e674019a659848e632..0000000000000000000000000000000000000000 --- a/gui2/quicksimeditor/profilehelper.h +++ /dev/null @@ -1,42 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/quicksimeditor/profilehelper.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_QUICKSIMEDITOR_PROFILEHELPER_H -#define BORNAGAIN_GUI2_QUICKSIMEDITOR_PROFILEHELPER_H - -#include "darefl_export.h" -#include <Resample/Slice/Slice.h> -#include <utility> -#include <vector> - -//! Object that can generate the material profile of a sample as a function of depth. -namespace gui2 { - -class DAREFLCORE_EXPORT ProfileHelper { -public: - ProfileHelper(const SliceStack& sample); - ~ProfileHelper(); - - std::vector<complex_t> calculateProfile(const std::vector<double>& z_values) const; - std::pair<double, double> defaultLimits() const; - -private: - std::vector<complex_t> m_materialdata; - std::vector<double> m_zlimits; - std::vector<double> m_sigmas; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_QUICKSIMEDITOR_PROFILEHELPER_H diff --git a/gui2/quicksimeditor/quicksim_types.h b/gui2/quicksimeditor/quicksim_types.h deleted file mode 100644 index 0a0b75a4b95ae575606a7b837a6c50119eb2d3ce..0000000000000000000000000000000000000000 --- a/gui2/quicksimeditor/quicksim_types.h +++ /dev/null @@ -1,56 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/quicksimeditor/quicksim_types.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_QUICKSIMEDITOR_QUICKSIM_TYPES_H -#define BORNAGAIN_GUI2_QUICKSIMEDITOR_QUICKSIM_TYPES_H - -#include "darefl_export.h" -#include <complex> -#include <vector> - -namespace gui2 { - -using complex_t = std::complex<double>; - -//! Data structure for simple multilayer representation. -struct DAREFLCORE_EXPORT SliceData { - complex_t material; - double thickness{0.0}; - double sigma{0.0}; // top interface sigma -}; -using multislice_t = std::vector<SliceData>; - -//! Represents data to run specular simulations. -struct DAREFLCORE_EXPORT SimulationInput { - std::vector<double> qvalues; - multislice_t slice_data; - double intensity; -}; - -//! Represents results of the simulation. -struct DAREFLCORE_EXPORT SimulationResult { - std::vector<double> qvalues; - std::vector<double> amplitudes; -}; - -//! Represents results of SLD profile calculations. -struct DAREFLCORE_EXPORT SLDProfile { - double zmin{0.0}; - double zmax{0.0}; - std::vector<double> sld_real_values; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_QUICKSIMEDITOR_QUICKSIM_TYPES_H diff --git a/gui2/quicksimeditor/quicksimcontroller.cpp b/gui2/quicksimeditor/quicksimcontroller.cpp deleted file mode 100644 index f9ad53d89da137cf7437783ea1e4c8f7e37dc6d2..0000000000000000000000000000000000000000 --- a/gui2/quicksimeditor/quicksimcontroller.cpp +++ /dev/null @@ -1,151 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/quicksimeditor/quicksimcontroller.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/quicksimeditor/quicksimcontroller.h" -#include "gui2/core/app_constants.h" -#include "gui2/model/applicationmodels.h" -#include "gui2/model/instrumentitems.h" -#include "gui2/model/instrumentmodel.h" -#include "gui2/model/jobitem.h" -#include "gui2/model/jobmodel.h" -#include "gui2/model/materialmodel.h" -#include "gui2/model/sampleitems.h" -#include "gui2/model/samplemodel.h" -#include "gui2/quicksimeditor/jobmanager.h" -#include "gui2/quicksimeditor/quicksimutils.h" -#include "gui2/quicksimeditor/speculartoysimulation.h" -#include "mvvm/project/modelhaschangedcontroller.h" -#include "mvvm/standarditems/axisitems.h" -#include "mvvm/standarditems/data1ditem.h" - -namespace { -const int profile_points_count = 1000; -} - -namespace gui2 { - -QuickSimController::QuickSimController(QObject* parent) - : QObject(parent) - , m_jobManager(new JobManager(this)) - , m_isRealTimeMode(GUI::Constants::live_simulation_default_on) -{ -} - -QuickSimController::~QuickSimController() = default; - -void QuickSimController::setModels(ApplicationModels* models) -{ - m_models = models; - - auto on_model_change = [this]() { onMultiLayerChange(); }; - m_materialChangedController = std::make_unique<ModelView::ModelHasChangedController>( - m_models->materialModel(), on_model_change); - m_sampleChangedController = std::make_unique<ModelView::ModelHasChangedController>( - m_models->sampleModel(), on_model_change); - m_instrumentChangedController = std::make_unique<ModelView::ModelHasChangedController>( - m_models->instrumentModel(), on_model_change); - - setup_jobmanager_connections(); - - onMultiLayerChange(); - jobModel()->sldViewport()->setViewportToContent(); -} - -//! Requests interruption of running simulaitons. - -void QuickSimController::onInterruptRequest() -{ - m_jobManager->onInterruptRequest(); -} - -void QuickSimController::onRealTimeRequest(bool status) -{ - m_isRealTimeMode = status; -} - -//! Processes multilayer on request. Doesn't work in real time mode. - -void QuickSimController::onRunSimulationRequest() -{ - process_multilayer(/*submit_simulation*/ true); -} - -//! Processes multilayer on any model change. Works only in realtime mode. - -void QuickSimController::onMultiLayerChange() -{ - process_multilayer(/*submit_simulation*/ m_isRealTimeMode); -} - -//! Takes simulation results from JobManager and write into the model. - -void QuickSimController::onSimulationCompleted() -{ - jobModel()->updateSpecularData(m_jobManager->simulationResult()); -} - -//! Constructs multislice, calculates profile and submits specular simulation. - -void QuickSimController::process_multilayer(bool submit_simulation) -{ - auto multilayer = m_models->sampleModel()->topItem<MultiLayerItem>(); - auto slices = Utils::CreateMultiSlice(*multilayer); - update_sld_profile(slices); - if (submit_simulation) - submit_specular_simulation(slices); -} - -//! Calculates sld profile from slice and immediately update data items. - -void QuickSimController::update_sld_profile(const multislice_t& multislice) -{ - auto data = SpecularToySimulation::sld_profile(multislice, profile_points_count); - jobModel()->updateSLDProfile(data); -} - -//! Submit data to JobManager for consequent specular simulation in a separate thread. - -void QuickSimController::submit_specular_simulation(const multislice_t& multislice) -{ - auto instrument = instrumentModel()->topItem<SpecularInstrumentItem>(); - auto beam = instrument->beamItem(); - m_jobManager->requestSimulation(multislice, beam->qScanValues(), beam->intensity()); -} - -//! Connect signals going from JobManager. Connections are made queued since signals are emitted -//! from non-GUI thread and we want to deal with widgets. - -void QuickSimController::setup_jobmanager_connections() -{ - - // Simulation progress is propagated from JobManager to this controller for further forwarding. - connect(m_jobManager, &JobManager::progressChanged, this, &QuickSimController::progressChanged, - Qt::QueuedConnection); - - // Notification about completed simulation from jobManager to this controller. - connect(m_jobManager, &JobManager::simulationCompleted, this, - &QuickSimController::onSimulationCompleted, Qt::QueuedConnection); -} - -JobModel* QuickSimController::jobModel() const -{ - return m_models->jobModel(); -} - -InstrumentModel* QuickSimController::instrumentModel() const -{ - return m_models->instrumentModel(); -} - -} // namespace gui2 diff --git a/gui2/quicksimeditor/quicksimcontroller.h b/gui2/quicksimeditor/quicksimcontroller.h deleted file mode 100644 index 8330ca9e3a3fc12268ec1ff96a7f695dd444ef11..0000000000000000000000000000000000000000 --- a/gui2/quicksimeditor/quicksimcontroller.h +++ /dev/null @@ -1,81 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/quicksimeditor/quicksimcontroller.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_QUICKSIMEDITOR_QUICKSIMCONTROLLER_H -#define BORNAGAIN_GUI2_QUICKSIMEDITOR_QUICKSIMCONTROLLER_H - -#include "darefl_export.h" -#include "gui2/quicksimeditor/quicksim_types.h" -#include <QObject> -#include <memory> - -namespace ModelView { -class ModelHasChangedController; -} - -namespace gui2 { - -class ApplicationModels; -class JobManager; -class JobModel; -class InstrumentModel; - -//! Provides quick reflectometry simulations on any change of SampleModel and MaterialModel. -//! Listens for any change in SampleModel and MaterialModel, extracts the data needed for -//! the simulation, and then submit simulation request to JobManager. As soon as JobManager reports -//! about completed simulations, extract results from there and put them into JobModel. - -class DAREFLCORE_EXPORT QuickSimController : public QObject { - Q_OBJECT - -public: - QuickSimController(QObject* parent = nullptr); - ~QuickSimController(); - - void setModels(ApplicationModels* models); - -signals: - void progressChanged(int value); - -public slots: - void onInterruptRequest(); - void onRealTimeRequest(bool status); - void onRunSimulationRequest(); - -private slots: - void onMultiLayerChange(); - void onSimulationCompleted(); - -private: - void process_multilayer(bool submit_simulation = false); - void update_sld_profile(const multislice_t& multilayer); - void submit_specular_simulation(const multislice_t& multislice); - void setup_jobmanager_connections(); - - JobModel* jobModel() const; - InstrumentModel* instrumentModel() const; - - ApplicationModels* m_models{nullptr}; - JobManager* m_jobManager{nullptr}; - - bool m_isRealTimeMode; //! Run simulation on every parameter change. - - std::unique_ptr<ModelView::ModelHasChangedController> m_materialChangedController; - std::unique_ptr<ModelView::ModelHasChangedController> m_sampleChangedController; - std::unique_ptr<ModelView::ModelHasChangedController> m_instrumentChangedController; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_QUICKSIMEDITOR_QUICKSIMCONTROLLER_H diff --git a/gui2/quicksimeditor/quicksimeditor.cpp b/gui2/quicksimeditor/quicksimeditor.cpp deleted file mode 100644 index 2621d9ab29b038e45e53b19eadc6bac7d673d82d..0000000000000000000000000000000000000000 --- a/gui2/quicksimeditor/quicksimeditor.cpp +++ /dev/null @@ -1,107 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/quicksimeditor/quicksimeditor.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/quicksimeditor/quicksimeditor.h" -#include "gui2/mainwindow/styleutils.h" -#include "gui2/model/applicationmodels.h" -#include "gui2/model/experimentaldataitems.h" -#include "gui2/model/jobmodel.h" -#include "gui2/quicksimeditor/quicksimcontroller.h" -#include "gui2/quicksimeditor/quicksimeditortoolbar.h" -#include "gui2/quicksimeditor/simplotcontroller.h" -#include "gui2/quicksimeditor/simplotwidget.h" -#include "mvvm/model/modelutils.h" -#include "mvvm/plotting/graphcanvas.h" -#include "mvvm/standarditems/graphviewportitem.h" -#include <QTabWidget> -#include <QVBoxLayout> - -using namespace ModelView; - -namespace gui2 { - -QuickSimEditor::QuickSimEditor(QWidget* parent) - : QWidget(parent) - , m_simController(new QuickSimController(this)) - , m_plotController(new SimPlotController(this)) - , m_plotWidget(new SimPlotWidget) - , m_toolBar(new QuickSimEditorToolBar) -{ - setWindowTitle(QString("Reflectivity plot")); - auto layout = new QVBoxLayout(this); - layout->addWidget(m_toolBar); - layout->addWidget(m_plotWidget); - layout->setContentsMargins(0, 0, 0, 0); - layout->setSpacing(0); - - setup_toolbar_connections(); - setup_controller_connections(); -} - -QuickSimEditor::~QuickSimEditor() = default; - -//! Set the mododel for the different items -void QuickSimEditor::setModels(ApplicationModels* models) -{ - m_appModels = models; - m_simController->setModels(models); - m_plotController->setModels(models); - m_plotWidget->setModels(models); -} - -QSize QuickSimEditor::sizeHint() const -{ - return GUI::Utils::Style::DockSizeHint(); -} - -QSize QuickSimEditor::minimumSizeHint() const -{ - return GUI::Utils::Style::DockMinimumSizeHint(); -} - -//! Connects signals from toolbar. - -void QuickSimEditor::setup_toolbar_connections() -{ - // Request to reset plot is propagated from toolbar to viewports. - auto on_reset_view = [this]() { m_plotWidget->updateViewport(); }; - connect(dynamic_cast<QuickSimEditorToolBar*>(m_toolBar), - &QuickSimEditorToolBar::resetViewRequest, on_reset_view); - - // Simulation interrupt request is propagated from toolbar to controller. - connect(dynamic_cast<QuickSimEditorToolBar*>(m_toolBar), &QuickSimEditorToolBar::cancelPressed, - m_simController, &QuickSimController::onInterruptRequest); - - // Request for real time mode is propagated from toobar to controller. - connect(dynamic_cast<QuickSimEditorToolBar*>(m_toolBar), - &QuickSimEditorToolBar::realTimeRequest, m_simController, - &QuickSimController::onRealTimeRequest); - - // Run simulation is propagated from toobar to controller. - connect(dynamic_cast<QuickSimEditorToolBar*>(m_toolBar), - &QuickSimEditorToolBar::runSimulationRequest, m_simController, - &QuickSimController::onRunSimulationRequest); -} - -//! Connects signals from controller. - -void QuickSimEditor::setup_controller_connections() -{ - // Progress values propagated from controller to toolbar. - connect(m_simController, &QuickSimController::progressChanged, - dynamic_cast<QuickSimEditorToolBar*>(m_toolBar), - &QuickSimEditorToolBar::onProgressChanged); -} - -} // namespace gui2 diff --git a/gui2/quicksimeditor/quicksimeditor.h b/gui2/quicksimeditor/quicksimeditor.h deleted file mode 100644 index ca1267d0a98f17013c563024b90461edbed8ee89..0000000000000000000000000000000000000000 --- a/gui2/quicksimeditor/quicksimeditor.h +++ /dev/null @@ -1,57 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/quicksimeditor/quicksimeditor.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_QUICKSIMEDITOR_QUICKSIMEDITOR_H -#define BORNAGAIN_GUI2_QUICKSIMEDITOR_QUICKSIMEDITOR_H - -#include "darefl_export.h" -#include <QWidget> - -namespace gui2 { - -class JobModel; -class ApplicationModels; -class QuickSimController; -class QuickSimEditorToolBar; -class SimPlotController; -class SimPlotWidget; - -//! Quick reflectivity simulations. - -class DAREFLCORE_EXPORT QuickSimEditor : public QWidget { - Q_OBJECT - -public: - QuickSimEditor(QWidget* parent = nullptr); - ~QuickSimEditor(); - - void setModels(ApplicationModels* models); - - QSize sizeHint() const override; - QSize minimumSizeHint() const override; - -private: - void setup_toolbar_connections(); - void setup_controller_connections(); - - ApplicationModels* m_appModels{nullptr}; - QuickSimController* m_simController{nullptr}; - SimPlotController* m_plotController{nullptr}; - SimPlotWidget* m_plotWidget{nullptr}; - QuickSimEditorToolBar* m_toolBar{nullptr}; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_QUICKSIMEDITOR_QUICKSIMEDITOR_H diff --git a/gui2/quicksimeditor/quicksimeditortoolbar.cpp b/gui2/quicksimeditor/quicksimeditortoolbar.cpp deleted file mode 100644 index 6b2c4e67960e04ab529d73cf183b681c944abb04..0000000000000000000000000000000000000000 --- a/gui2/quicksimeditor/quicksimeditortoolbar.cpp +++ /dev/null @@ -1,100 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/quicksimeditor/quicksimeditortoolbar.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/quicksimeditor/quicksimeditortoolbar.h" -#include "gui2/core/app_constants.h" -#include <QAction> -#include <QCheckBox> -#include <QLabel> -#include <QProgressBar> -#include <QVBoxLayout> - -namespace gui2 { - -QuickSimEditorToolBar::QuickSimEditorToolBar(QWidget* parent) - : QToolBar(parent), m_liveCheckbox(new QCheckBox), m_progressBar(new QProgressBar) -{ - const int toolbar_icon_size = 24; - setIconSize(QSize(toolbar_icon_size, toolbar_icon_size)); - setToolButtonStyle(Qt::ToolButtonTextBesideIcon); - - setup_simulation_elements(); - add_wide_separator(); - - setup_plot_elements(); -} - -//! Set progress bar to given value. - -void QuickSimEditorToolBar::onProgressChanged(int value) -{ - m_progressBar->setValue(value); -} - -void QuickSimEditorToolBar::add_wide_separator() -{ - addWidget(new QLabel(" ")); - addSeparator(); - addWidget(new QLabel(" ")); -} - -//! Setups elements to run simulation. - -void QuickSimEditorToolBar::setup_simulation_elements() -{ - // live check box and label - const QString live_tooltip = "Automatically run simulation and update plot\n" - "on any multilayer change."; - m_liveCheckbox->setCheckState(GUI::Constants::live_simulation_default_on ? Qt::Checked - : Qt::Unchecked); - m_liveCheckbox->setToolTip(live_tooltip); - auto on_check_state = [this](int state) { realTimeRequest(state == Qt::Checked); }; - connect(m_liveCheckbox, &QCheckBox::stateChanged, on_check_state); - addWidget(m_liveCheckbox); - auto label = new QLabel("Live"); - label->setToolTip(live_tooltip); - addWidget(label); - - // run simulation - auto run_action = new QAction("Run", this); - run_action->setIcon(QIcon(":/icons/play-circle-outline.svg")); - run_action->setToolTip("Run simulation for current multilayer state"); - connect(run_action, &QAction::triggered, this, &QuickSimEditorToolBar::runSimulationRequest); - addAction(run_action); - - // progress bar - m_progressBar->setFixedWidth(150); - m_progressBar->setTextVisible(false); - addWidget(m_progressBar); - - // cancel simulation - auto cancel_action = new QAction("Cancel", this); - cancel_action->setIcon(QIcon(":/icons/close-circle-outline.svg")); - cancel_action->setToolTip("Cancel running simulation"); - connect(cancel_action, &QAction::triggered, this, &QuickSimEditorToolBar::cancelPressed); - addAction(cancel_action); -} - -//! Setups actions to reset plot and access its settings. - -void QuickSimEditorToolBar::setup_plot_elements() -{ - auto reset_view = new QAction("Replot", this); - reset_view->setToolTip("Set plot axes to default range"); - reset_view->setIcon(QIcon(":/icons/aspect-ratio.svg")); - connect(reset_view, &QAction::triggered, this, &QuickSimEditorToolBar::resetViewRequest); - addAction(reset_view); -} - -} // namespace gui2 diff --git a/gui2/quicksimeditor/quicksimeditortoolbar.h b/gui2/quicksimeditor/quicksimeditortoolbar.h deleted file mode 100644 index 21888f544ad04ba53e79919aa6d79da9d57d2719..0000000000000000000000000000000000000000 --- a/gui2/quicksimeditor/quicksimeditortoolbar.h +++ /dev/null @@ -1,57 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/quicksimeditor/quicksimeditortoolbar.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_QUICKSIMEDITOR_QUICKSIMEDITORTOOLBAR_H -#define BORNAGAIN_GUI2_QUICKSIMEDITOR_QUICKSIMEDITORTOOLBAR_H - -#include "darefl_export.h" -#include <QToolBar> - -class QProgressBar; -class QCheckBox; - -namespace gui2 { - -//! Toolbar for QuickSimEditor. -//! Contains live simulation button, cancel button, simulation progress bar and settings buttons. - -class DAREFLCORE_EXPORT QuickSimEditorToolBar : public QToolBar { - Q_OBJECT - -public: - explicit QuickSimEditorToolBar(QWidget* parent = nullptr); - -signals: - void realTimeRequest(bool); - void runSimulationRequest(); - void cancelPressed(); - void instrumentSettingsRequest(); - void resetViewRequest(); - void plotSettingsRequest(); - -public slots: - void onProgressChanged(int value); - -private: - void add_wide_separator(); - void setup_simulation_elements(); - void setup_plot_elements(); - - QCheckBox* m_liveCheckbox{nullptr}; - QProgressBar* m_progressBar{nullptr}; //! Simulation progressbar. -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_QUICKSIMEDITOR_QUICKSIMEDITORTOOLBAR_H diff --git a/gui2/quicksimeditor/quicksimutils.cpp b/gui2/quicksimeditor/quicksimutils.cpp deleted file mode 100644 index faeef5449eb42fd8470f8318a7d8e42a0433194e..0000000000000000000000000000000000000000 --- a/gui2/quicksimeditor/quicksimutils.cpp +++ /dev/null @@ -1,89 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/quicksimeditor/quicksimutils.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/quicksimeditor/quicksimutils.h" -#include "gui2/model/item_constants.h" -#include "gui2/model/materialitems.h" -#include "gui2/model/sampleitems.h" -#include "mvvm/model/externalproperty.h" -#include "mvvm/model/sessionmodel.h" -#include <Resample/Slice/Slice.h> -#include <Sample/Interface/LayerRoughness.h> -#include <Sample/Material/MaterialFactoryFuncs.h> -#include <stdexcept> - -namespace gui2 { - -namespace { - -//! Creates slice from layer content. -SliceData create_slice(const ModelView::SessionItem& layer) -{ - if (layer.modelType() != GUI::Constants::LayerItemType) - throw std::runtime_error("Error in create_slice(): not a layer."); - - double thickness = layer.property<double>(LayerItem::P_THICKNESS); - auto roughness = layer.item<RoughnessItem>(LayerItem::P_ROUGHNESS); - double sigma = roughness->property<double>(RoughnessItem::P_SIGMA); - - auto material_property = layer.property<ModelView::ExternalProperty>(LayerItem::P_MATERIAL); - auto material = layer.model()->findItem(material_property.identifier()); - // layer which is not linked with material will get (0,0) as SLD material. - double sld_real = material ? material->property<double>(SLDMaterialItem::P_SLD_REAL) : 0.0; - double sld_imag = material ? material->property<double>(SLDMaterialItem::P_SLD_IMAG) : 0.0; - return {complex_t{sld_real, sld_imag}, thickness, sigma}; -} - -//! Adds slices to existing vector of slices using content of a multilayer. -//! Will be called recursively for multilayers inside multilayers. -void AddToMultiSlice(multislice_t& result, const ModelView::SessionItem& multilayer) -{ - for (const auto item : multilayer.getItems(MultiLayerItem::T_LAYERS)) { - if (item->modelType() == GUI::Constants::LayerItemType) { - result.push_back(create_slice(*item)); - } else if (item->modelType() == GUI::Constants::MultiLayerItemType) { - const int rep_count = item->property<int>(MultiLayerItem::P_NREPETITIONS); - for (int i_rep = 0; i_rep < rep_count; ++i_rep) - AddToMultiSlice(result, *item); - } else { - throw std::runtime_error("Error in AddToMultiSlice: unsupported item type."); - } - } -} - -} // namespace - -multislice_t Utils::CreateMultiSlice(const MultiLayerItem& multilayer) -{ - multislice_t result; - AddToMultiSlice(result, multilayer); - return result; -} - -SliceStack Utils::createBornAgainSlices(const multislice_t& multislice) -{ - SliceStack result; - result.reserve(multislice.size()); - - for (auto& slice : multislice) { - auto material = MaterialBySLD("", slice.material.real(), slice.material.imag()); - auto roughness = LayerRoughness(slice.sigma, 0., 0.); - - result.emplace_back(slice.thickness, material, roughness); - } - - return result; -} - -} // namespace gui2 diff --git a/gui2/quicksimeditor/quicksimutils.h b/gui2/quicksimeditor/quicksimutils.h deleted file mode 100644 index fe90a749a53b7df34a1f72da5bc03532d6403357..0000000000000000000000000000000000000000 --- a/gui2/quicksimeditor/quicksimutils.h +++ /dev/null @@ -1,40 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/quicksimeditor/quicksimutils.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_QUICKSIMEDITOR_QUICKSIMUTILS_H -#define BORNAGAIN_GUI2_QUICKSIMEDITOR_QUICKSIMUTILS_H - -#include "darefl_export.h" -#include "gui2/quicksimeditor/quicksim_types.h" - -class Slice; -class SliceStack; - -namespace gui2 { - -class MultiLayerItem; - -//! Collection of utility functions for running quick simulations. -namespace Utils { - -//! Creates multi-slice presentation of internal multilayer structure. -DAREFLCORE_EXPORT multislice_t CreateMultiSlice(const MultiLayerItem& multilayer); - -DAREFLCORE_EXPORT SliceStack createBornAgainSlices(const multislice_t& multislice); - -} // namespace Utils - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_QUICKSIMEDITOR_QUICKSIMUTILS_H diff --git a/gui2/quicksimeditor/simplotcontroller.cpp b/gui2/quicksimeditor/simplotcontroller.cpp deleted file mode 100644 index e9e87dad47f40c3b773682bd2e3622f468afb918..0000000000000000000000000000000000000000 --- a/gui2/quicksimeditor/simplotcontroller.cpp +++ /dev/null @@ -1,45 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/quicksimeditor/simplotcontroller.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/quicksimeditor/simplotcontroller.h" -#include "gui2/model/applicationmodels.h" -#include "gui2/model/instrumentitems.h" -#include "gui2/model/instrumentmodel.h" -#include "gui2/model/jobitem.h" -#include "gui2/model/jobmodel.h" -#include "mvvm/project/modelhaschangedcontroller.h" - -namespace gui2 { - -SimPlotController::SimPlotController(QObject* parent) : QObject(parent) {} - -void SimPlotController::setModels(ApplicationModels* models) -{ - m_models = models; - - auto on_model_change = [this]() { onInstrumentChange(); }; - m_instrumentChangedController = std::make_unique<ModelView::ModelHasChangedController>( - m_models->instrumentModel(), on_model_change); -} - -void SimPlotController::onInstrumentChange() -{ - auto instrument = m_models->instrumentModel()->topItem<SpecularInstrumentItem>(); - auto graph = instrument->beamItem()->experimentalGraphItem(); - m_models->jobModel()->updateReferenceGraph(graph); -} - -SimPlotController::~SimPlotController() = default; - -} // namespace gui2 diff --git a/gui2/quicksimeditor/simplotcontroller.h b/gui2/quicksimeditor/simplotcontroller.h deleted file mode 100644 index 43496fc98babe4995182ba1425b15d237d9a9224..0000000000000000000000000000000000000000 --- a/gui2/quicksimeditor/simplotcontroller.h +++ /dev/null @@ -1,50 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/quicksimeditor/simplotcontroller.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_QUICKSIMEDITOR_SIMPLOTCONTROLLER_H -#define BORNAGAIN_GUI2_QUICKSIMEDITOR_SIMPLOTCONTROLLER_H - -#include "darefl_export.h" -#include <QObject> -#include <memory> - -namespace ModelView { -class ModelHasChangedController; -} - -namespace gui2 { - -class ApplicationModels; - -//! Updates reference curve in JobItem when BeamItem is changed. - -class DAREFLCORE_EXPORT SimPlotController : public QObject { - Q_OBJECT - -public: - SimPlotController(QObject* parent = nullptr); - ~SimPlotController(); - - void setModels(ApplicationModels* models); - -private: - void onInstrumentChange(); - - ApplicationModels* m_models{nullptr}; - std::unique_ptr<ModelView::ModelHasChangedController> m_instrumentChangedController; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_QUICKSIMEDITOR_SIMPLOTCONTROLLER_H diff --git a/gui2/quicksimeditor/simplotwidget.cpp b/gui2/quicksimeditor/simplotwidget.cpp deleted file mode 100644 index bc387bf435fa5d6d737878ccd734fb6a1468c34b..0000000000000000000000000000000000000000 --- a/gui2/quicksimeditor/simplotwidget.cpp +++ /dev/null @@ -1,68 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/quicksimeditor/simplotwidget.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/quicksimeditor/simplotwidget.h" -#include "gui2/model/applicationmodels.h" -#include "gui2/model/experimentaldataitems.h" -#include "gui2/model/jobmodel.h" -#include "mvvm/plotting/graphcanvas.h" -#include "mvvm/standarditems/graphviewportitem.h" -#include <QList> -#include <QSplitter> -#include <QVBoxLayout> - -namespace gui2 { - -SimPlotWidget::SimPlotWidget(QWidget* parent) - : QWidget(parent) - , m_specularCanvas(new ModelView::GraphCanvas) - , m_diffCanvas(new ModelView::GraphCanvas) -{ - auto layout = new QVBoxLayout(this); - layout->setContentsMargins(0, 5, 5, 5); - - auto splitter = new QSplitter; - splitter->setOrientation(Qt::Vertical); - - splitter->addWidget(m_specularCanvas); - splitter->addWidget(m_diffCanvas); - - // splitter->setStyleSheet("background-color:white;"); - splitter->setSizes(QList<int>() << 300 << 100); - - layout->addWidget(splitter); - - auto on_axis_margins = [this](int left, int, int right, int) { - // syncronizes left and right margins, leave top and bottom automatic - m_diffCanvas->setAxisMargins(left, -1, right, -1); - }; - connect(m_specularCanvas, &ModelView::GraphCanvas::axisMarginsChanged, on_axis_margins); -} - -SimPlotWidget::~SimPlotWidget() = default; - -void SimPlotWidget::setModels(ApplicationModels* models) -{ - m_models = models; - m_specularCanvas->setItem(m_models->jobModel()->specularViewport()); - m_diffCanvas->setItem(m_models->jobModel()->diffViewport()); -} - -void SimPlotWidget::updateViewport() -{ - m_specularCanvas->setViewportToContent(); - m_diffCanvas->setViewportToContent(); -} - -} // namespace gui2 diff --git a/gui2/quicksimeditor/simplotwidget.h b/gui2/quicksimeditor/simplotwidget.h deleted file mode 100644 index 5fd1c9ef51c6894d5e27eb3bfad6bb3db263869e..0000000000000000000000000000000000000000 --- a/gui2/quicksimeditor/simplotwidget.h +++ /dev/null @@ -1,53 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/quicksimeditor/simplotwidget.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_QUICKSIMEDITOR_SIMPLOTWIDGET_H -#define BORNAGAIN_GUI2_QUICKSIMEDITOR_SIMPLOTWIDGET_H - -#include "darefl_export.h" -#include <QWidget> - -namespace ModelView { -class GraphCanvas; -} // namespace ModelView - -namespace gui2 { - -class ApplicationModels; - -//! Presents simulation results together with reference experimental data on two canvas. -//! The top canvas contains graphs itself, bottom canvas their relative difference. - -class DAREFLCORE_EXPORT SimPlotWidget : public QWidget { - Q_OBJECT - -public: - SimPlotWidget(QWidget* parent = nullptr); - ~SimPlotWidget(); - - void setModels(ApplicationModels* models); - - void updateViewport(); - - void updateDiffPlot(); - -private: - ApplicationModels* m_models{nullptr}; - ModelView::GraphCanvas* m_specularCanvas{nullptr}; - ModelView::GraphCanvas* m_diffCanvas{nullptr}; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_QUICKSIMEDITOR_SIMPLOTWIDGET_H diff --git a/gui2/resources/CMakeLists.txt b/gui2/resources/CMakeLists.txt deleted file mode 100644 index c0cefab2c0cf3f3b77bcb1c059f13a093238947d..0000000000000000000000000000000000000000 --- a/gui2/resources/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -set(CMAKE_AUTORCC ON) - -target_sources(${library_name} PRIVATE - icons.qrc - resources.h -) - -target_include_directories(${library_name} PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}>) diff --git a/gui2/resources/icons.qrc b/gui2/resources/icons.qrc deleted file mode 100644 index b428b8994e9f2a009aa59a45e1fb9fc758a91738..0000000000000000000000000000000000000000 --- a/gui2/resources/icons.qrc +++ /dev/null @@ -1,28 +0,0 @@ -<RCC> - <qresource prefix="/"> - <file>icons</file> - <file>icons/arrow-down-circle-outline.svg</file> - <file>icons/arrow-up-circle-outline.svg</file> - <file>icons/aspect-ratio.svg</file> - <file>icons/beaker-remove-outline.svg</file> - <file>icons/beaker-remove-outline.svg</file> - <file>icons/close-circle-outline.svg</file> - <file>icons/cog-outline.svg</file> - <file>icons/export.svg</file> - <file>icons/import.svg</file> - <file>icons/layers-outline.svg</file> - <file>icons/layers-triple-outline.svg</file> - <file>icons/play-circle-outline.svg</file> - <file>icons/plus-box-multiple-outline.svg</file> - <file>icons/plus-box-outline.svg</file> - <file>icons/plus-circle-outline.svg</file> - <file>icons/redo.svg</file> - <file>icons/undo.svg</file> - <file>icons/set-merge.svg</file> - <file>icons/F-letter_1000x.png</file> - <file>icons/card-bulleted-outline.svg</file> - <file>icons/dock-left.svg</file> - <file>icons/dock-right.svg</file> - <file>icons/plus-circle-multiple-outline.svg</file> - </qresource> -</RCC> diff --git a/gui2/resources/icons/F-letter_1000x.png b/gui2/resources/icons/F-letter_1000x.png deleted file mode 100644 index df05f0de24c9525f53fcbeafd52ce8066c4eb522..0000000000000000000000000000000000000000 Binary files a/gui2/resources/icons/F-letter_1000x.png and /dev/null differ diff --git a/gui2/resources/icons/arrow-down-circle-outline.svg b/gui2/resources/icons/arrow-down-circle-outline.svg deleted file mode 100644 index a1054904f58771ffcfb36e7be03e9d036c43739b..0000000000000000000000000000000000000000 --- a/gui2/resources/icons/arrow-down-circle-outline.svg +++ /dev/null @@ -1 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M11,6H13V14L16.5,10.5L17.92,11.92L12,17.84L6.08,11.92L7.5,10.5L11,14V6M12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22M12,20A8,8 0 0,0 20,12A8,8 0 0,0 12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20Z" /></svg> \ No newline at end of file diff --git a/gui2/resources/icons/arrow-up-circle-outline.svg b/gui2/resources/icons/arrow-up-circle-outline.svg deleted file mode 100644 index ea6c393ffff37a897bb9ff528291c8d9f19cdae7..0000000000000000000000000000000000000000 --- a/gui2/resources/icons/arrow-up-circle-outline.svg +++ /dev/null @@ -1 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M13,18H11V10L7.5,13.5L6.08,12.08L12,6.16L17.92,12.08L16.5,13.5L13,10V18M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2M12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20A8,8 0 0,0 20,12A8,8 0 0,0 12,4Z" /></svg> \ No newline at end of file diff --git a/gui2/resources/icons/aspect-ratio.svg b/gui2/resources/icons/aspect-ratio.svg deleted file mode 100644 index 5fce7b199ebe47566d714cde61221576a0c81c1b..0000000000000000000000000000000000000000 --- a/gui2/resources/icons/aspect-ratio.svg +++ /dev/null @@ -1 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M19,12H17V15H14V17H19V12M7,9H10V7H5V12H7V9M21,3H3A2,2 0 0,0 1,5V19A2,2 0 0,0 3,21H21A2,2 0 0,0 23,19V5A2,2 0 0,0 21,3M21,19H3V5H21V19Z" /></svg> \ No newline at end of file diff --git a/gui2/resources/icons/beaker-remove-outline.svg b/gui2/resources/icons/beaker-remove-outline.svg deleted file mode 100644 index 931e4ad9fb70d01c35453b66db0a7d07347e9641..0000000000000000000000000000000000000000 --- a/gui2/resources/icons/beaker-remove-outline.svg +++ /dev/null @@ -1 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M15.46 15.88L16.88 14.46L19 16.59L21.12 14.47L22.53 15.88L20.41 18L22.54 20.12L21.12 21.54L19 19.41L16.88 21.53L15.47 20.12L17.59 18L15.46 15.88M3 3H21V5C19.9 5 19 5.9 19 7V12C18.3 12 17.63 12.12 17 12.34V5H7V7H12V8H7V9H10V10H7V11H10V12H7V13H12V14H7V15H10V16H7V19H13.08C13.2 19.72 13.45 20.39 13.8 21H7C5.9 21 5 20.11 5 19V7C5 5.9 4.11 5 3 5V3Z" /></svg> \ No newline at end of file diff --git a/gui2/resources/icons/card-bulleted-outline.svg b/gui2/resources/icons/card-bulleted-outline.svg deleted file mode 100644 index d09c415c8c7d3f7d647d6fd93249b8402f02fba4..0000000000000000000000000000000000000000 --- a/gui2/resources/icons/card-bulleted-outline.svg +++ /dev/null @@ -1,54 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<svg - xmlns:dc="http://purl.org/dc/elements/1.1/" - xmlns:cc="http://creativecommons.org/ns#" - xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" - xmlns:svg="http://www.w3.org/2000/svg" - xmlns="http://www.w3.org/2000/svg" - xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - inkscape:version="1.0 (4035a4fb49, 2020-05-01)" - sodipodi:docname="card-bulleted-outline.svg" - id="svg4" - viewBox="0 0 24 24" - height="24" - width="24" - version="1.1"> - <metadata - id="metadata10"> - <rdf:RDF> - <cc:Work - rdf:about=""> - <dc:format>image/svg+xml</dc:format> - <dc:type - rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> - </cc:Work> - </rdf:RDF> - </metadata> - <defs - id="defs8" /> - <sodipodi:namedview - inkscape:current-layer="svg4" - inkscape:window-maximized="0" - inkscape:window-y="0" - inkscape:window-x="0" - inkscape:cy="12" - inkscape:cx="12" - inkscape:zoom="29.791667" - showgrid="false" - id="namedview6" - inkscape:window-height="1312" - inkscape:window-width="1922" - inkscape:pageshadow="2" - inkscape:pageopacity="0" - guidetolerance="10" - gridtolerance="10" - objecttolerance="10" - borderopacity="1" - bordercolor="#666666" - pagecolor="#ffffff" /> - <path - style="fill:#424446;fill-opacity:1" - id="path2" - d="M12,15H10V13H12V15M18,15H14V13H18V15M8,11H6V9H8V11M18,11H10V9H18V11M20,20H4A2,2 0 0,1 2,18V6A2,2 0 0,1 4,4H20A2,2 0 0,1 22,6V18A2,2 0 0,1 20,20M4,6V18H20V6H4Z" /> -</svg> diff --git a/gui2/resources/icons/close-circle-outline.svg b/gui2/resources/icons/close-circle-outline.svg deleted file mode 100644 index dad58cf89bf7d1911fdc1af58fd366940df7aab4..0000000000000000000000000000000000000000 --- a/gui2/resources/icons/close-circle-outline.svg +++ /dev/null @@ -1 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M12,20C7.59,20 4,16.41 4,12C4,7.59 7.59,4 12,4C16.41,4 20,7.59 20,12C20,16.41 16.41,20 12,20M12,2C6.47,2 2,6.47 2,12C2,17.53 6.47,22 12,22C17.53,22 22,17.53 22,12C22,6.47 17.53,2 12,2M14.59,8L12,10.59L9.41,8L8,9.41L10.59,12L8,14.59L9.41,16L12,13.41L14.59,16L16,14.59L13.41,12L16,9.41L14.59,8Z" /></svg> \ No newline at end of file diff --git a/gui2/resources/icons/cog-outline.svg b/gui2/resources/icons/cog-outline.svg deleted file mode 100644 index d7ed72b2d8c38a39c4e88075d13fcacbd916e507..0000000000000000000000000000000000000000 --- a/gui2/resources/icons/cog-outline.svg +++ /dev/null @@ -1 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M12,8A4,4 0 0,1 16,12A4,4 0 0,1 12,16A4,4 0 0,1 8,12A4,4 0 0,1 12,8M12,10A2,2 0 0,0 10,12A2,2 0 0,0 12,14A2,2 0 0,0 14,12A2,2 0 0,0 12,10M10,22C9.75,22 9.54,21.82 9.5,21.58L9.13,18.93C8.5,18.68 7.96,18.34 7.44,17.94L4.95,18.95C4.73,19.03 4.46,18.95 4.34,18.73L2.34,15.27C2.21,15.05 2.27,14.78 2.46,14.63L4.57,12.97L4.5,12L4.57,11L2.46,9.37C2.27,9.22 2.21,8.95 2.34,8.73L4.34,5.27C4.46,5.05 4.73,4.96 4.95,5.05L7.44,6.05C7.96,5.66 8.5,5.32 9.13,5.07L9.5,2.42C9.54,2.18 9.75,2 10,2H14C14.25,2 14.46,2.18 14.5,2.42L14.87,5.07C15.5,5.32 16.04,5.66 16.56,6.05L19.05,5.05C19.27,4.96 19.54,5.05 19.66,5.27L21.66,8.73C21.79,8.95 21.73,9.22 21.54,9.37L19.43,11L19.5,12L19.43,13L21.54,14.63C21.73,14.78 21.79,15.05 21.66,15.27L19.66,18.73C19.54,18.95 19.27,19.04 19.05,18.95L16.56,17.95C16.04,18.34 15.5,18.68 14.87,18.93L14.5,21.58C14.46,21.82 14.25,22 14,22H10M11.25,4L10.88,6.61C9.68,6.86 8.62,7.5 7.85,8.39L5.44,7.35L4.69,8.65L6.8,10.2C6.4,11.37 6.4,12.64 6.8,13.8L4.68,15.36L5.43,16.66L7.86,15.62C8.63,16.5 9.68,17.14 10.87,17.38L11.24,20H12.76L13.13,17.39C14.32,17.14 15.37,16.5 16.14,15.62L18.57,16.66L19.32,15.36L17.2,13.81C17.6,12.64 17.6,11.37 17.2,10.2L19.31,8.65L18.56,7.35L16.15,8.39C15.38,7.5 14.32,6.86 13.12,6.62L12.75,4H11.25Z" /></svg> \ No newline at end of file diff --git a/gui2/resources/icons/dock-left.svg b/gui2/resources/icons/dock-left.svg deleted file mode 100644 index 3b5ffd7a11de05cd66623f6c3aae0582de2c09fd..0000000000000000000000000000000000000000 --- a/gui2/resources/icons/dock-left.svg +++ /dev/null @@ -1 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M20 4H4A2 2 0 0 0 2 6V18A2 2 0 0 0 4 20H20A2 2 0 0 0 22 18V6A2 2 0 0 0 20 4M20 18H9V6H20Z" /></svg> \ No newline at end of file diff --git a/gui2/resources/icons/dock-right.svg b/gui2/resources/icons/dock-right.svg deleted file mode 100644 index 8344eae8a95c410e1cf371630c61ea77049510ff..0000000000000000000000000000000000000000 --- a/gui2/resources/icons/dock-right.svg +++ /dev/null @@ -1 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M20 4H4A2 2 0 0 0 2 6V18A2 2 0 0 0 4 20H20A2 2 0 0 0 22 18V6A2 2 0 0 0 20 4M15 18H4V6H15Z" /></svg> \ No newline at end of file diff --git a/gui2/resources/icons/export.svg b/gui2/resources/icons/export.svg deleted file mode 100644 index cf6f1595fd036b29b4e787ba6c9866126ad8140d..0000000000000000000000000000000000000000 --- a/gui2/resources/icons/export.svg +++ /dev/null @@ -1 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M23,12L19,8V11H10V13H19V16M1,18V6C1,4.89 1.9,4 3,4H15A2,2 0 0,1 17,6V9H15V6H3V18H15V15H17V18A2,2 0 0,1 15,20H3A2,2 0 0,1 1,18Z" /></svg> \ No newline at end of file diff --git a/gui2/resources/icons/import.svg b/gui2/resources/icons/import.svg deleted file mode 100644 index 2cc83b8399ca377af46c256363d9578a65f71e0f..0000000000000000000000000000000000000000 --- a/gui2/resources/icons/import.svg +++ /dev/null @@ -1 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M14,12L10,8V11H2V13H10V16M20,18V6C20,4.89 19.1,4 18,4H6A2,2 0 0,0 4,6V9H6V6H18V18H6V15H4V18A2,2 0 0,0 6,20H18A2,2 0 0,0 20,18Z" /></svg> \ No newline at end of file diff --git a/gui2/resources/icons/layers-outline.svg b/gui2/resources/icons/layers-outline.svg deleted file mode 100644 index 3b376e42461520c3ebc26821387602d2b3a400ca..0000000000000000000000000000000000000000 --- a/gui2/resources/icons/layers-outline.svg +++ /dev/null @@ -1 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M12,18.54L19.37,12.8L21,14.07L12,21.07L3,14.07L4.62,12.81L12,18.54M12,16L3,9L12,2L21,9L12,16M12,4.53L6.26,9L12,13.47L17.74,9L12,4.53Z" /></svg> \ No newline at end of file diff --git a/gui2/resources/icons/layers-triple-outline.svg b/gui2/resources/icons/layers-triple-outline.svg deleted file mode 100644 index d074e884c2b76412c1b6acd9a94c082a334e4d46..0000000000000000000000000000000000000000 --- a/gui2/resources/icons/layers-triple-outline.svg +++ /dev/null @@ -1 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M12 16.54L19.37 10.8L21 12.07L12 19.07L3 12.07L4.62 10.81L12 16.54M12 14L3 7L12 0L21 7L12 14M12 2.53L6.26 7L12 11.47L17.74 7L12 2.53M12 21.47L19.37 15.73L21 17L12 24L3 17L4.62 15.74L12 21.47" /></svg> \ No newline at end of file diff --git a/gui2/resources/icons/play-circle-outline.svg b/gui2/resources/icons/play-circle-outline.svg deleted file mode 100644 index 792051fe4869468cb5d01fcea6fbd6a0edd5cf1d..0000000000000000000000000000000000000000 --- a/gui2/resources/icons/play-circle-outline.svg +++ /dev/null @@ -1 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M12,20C7.59,20 4,16.41 4,12C4,7.59 7.59,4 12,4C16.41,4 20,7.59 20,12C20,16.41 16.41,20 12,20M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M10,16.5L16,12L10,7.5V16.5Z" /></svg> \ No newline at end of file diff --git a/gui2/resources/icons/plus-box-multiple-outline.svg b/gui2/resources/icons/plus-box-multiple-outline.svg deleted file mode 100644 index 7857512bf32bbe50073a0e646fef342f65ef7d57..0000000000000000000000000000000000000000 --- a/gui2/resources/icons/plus-box-multiple-outline.svg +++ /dev/null @@ -1 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M18 11H15V14H13V11H10V9H13V6H15V9H18M20 4V16H8V4H20M20 2H8C6.9 2 6 2.9 6 4V16C6 17.11 6.9 18 8 18H20C21.11 18 22 17.11 22 16V4C22 2.9 21.11 2 20 2M4 6H2V20C2 21.11 2.9 22 4 22H18V20H4V6Z" /></svg> \ No newline at end of file diff --git a/gui2/resources/icons/plus-box-outline.svg b/gui2/resources/icons/plus-box-outline.svg deleted file mode 100644 index b00356cd36d654eaf8cad762fc966ca27e2a4727..0000000000000000000000000000000000000000 --- a/gui2/resources/icons/plus-box-outline.svg +++ /dev/null @@ -1 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M19,19V5H5V19H19M19,3A2,2 0 0,1 21,5V19A2,2 0 0,1 19,21H5A2,2 0 0,1 3,19V5C3,3.89 3.9,3 5,3H19M11,7H13V11H17V13H13V17H11V13H7V11H11V7Z" /></svg> \ No newline at end of file diff --git a/gui2/resources/icons/plus-circle-multiple-outline.svg b/gui2/resources/icons/plus-circle-multiple-outline.svg deleted file mode 100644 index 001d9824254fd72acc9cf5033471b5643c439119..0000000000000000000000000000000000000000 --- a/gui2/resources/icons/plus-circle-multiple-outline.svg +++ /dev/null @@ -1 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M16,8H14V11H11V13H14V16H16V13H19V11H16M2,12C2,9.21 3.64,6.8 6,5.68V3.5C2.5,4.76 0,8.09 0,12C0,15.91 2.5,19.24 6,20.5V18.32C3.64,17.2 2,14.79 2,12M15,3C10.04,3 6,7.04 6,12C6,16.96 10.04,21 15,21C19.96,21 24,16.96 24,12C24,7.04 19.96,3 15,3M15,19C11.14,19 8,15.86 8,12C8,8.14 11.14,5 15,5C18.86,5 22,8.14 22,12C22,15.86 18.86,19 15,19Z" /></svg> \ No newline at end of file diff --git a/gui2/resources/icons/plus-circle-outline.svg b/gui2/resources/icons/plus-circle-outline.svg deleted file mode 100644 index 3fe6bec7ebb59d7577a9683d9a5b704a19df2483..0000000000000000000000000000000000000000 --- a/gui2/resources/icons/plus-circle-outline.svg +++ /dev/null @@ -1 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M12,20C7.59,20 4,16.41 4,12C4,7.59 7.59,4 12,4C16.41,4 20,7.59 20,12C20,16.41 16.41,20 12,20M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M13,7H11V11H7V13H11V17H13V13H17V11H13V7Z" /></svg> \ No newline at end of file diff --git a/gui2/resources/icons/redo.svg b/gui2/resources/icons/redo.svg deleted file mode 100644 index 54af62edc7267f7d2a56bcbd3e2ee84376a971c2..0000000000000000000000000000000000000000 --- a/gui2/resources/icons/redo.svg +++ /dev/null @@ -1 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M18.4,10.6C16.55,9 14.15,8 11.5,8C6.85,8 2.92,11.03 1.54,15.22L3.9,16C4.95,12.81 7.95,10.5 11.5,10.5C13.45,10.5 15.23,11.22 16.62,12.38L13,16H22V7L18.4,10.6Z" /></svg> \ No newline at end of file diff --git a/gui2/resources/icons/set-merge.svg b/gui2/resources/icons/set-merge.svg deleted file mode 100644 index 4869b87086cacf6ef3c9beba53779ed51e450fd5..0000000000000000000000000000000000000000 --- a/gui2/resources/icons/set-merge.svg +++ /dev/null @@ -1 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M2 7V9H7V7H2M12 9V11H9V13H12V15L15 12L12 9M17 9V15H22V9H17M2 11V13H7V11H2M2 15V17H7V15H2Z" /></svg> \ No newline at end of file diff --git a/gui2/resources/icons/undo.svg b/gui2/resources/icons/undo.svg deleted file mode 100644 index 797d4d368041cace5eb10699e2d7f752f33c332b..0000000000000000000000000000000000000000 --- a/gui2/resources/icons/undo.svg +++ /dev/null @@ -1 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M12.5,8C9.85,8 7.45,9 5.6,10.6L2,7V16H11L7.38,12.38C8.77,11.22 10.54,10.5 12.5,10.5C16.04,10.5 19.05,12.81 20.1,16L22.47,15.22C21.08,11.03 17.15,8 12.5,8Z" /></svg> \ No newline at end of file diff --git a/gui2/resources/resources.h b/gui2/resources/resources.h deleted file mode 100644 index 464f01d213ee9e97f3746e7fa4062e3a6c0104b4..0000000000000000000000000000000000000000 --- a/gui2/resources/resources.h +++ /dev/null @@ -1,25 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/resources/resources.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_RESOURCES_RESOURCES_H -#define BORNAGAIN_GUI2_RESOURCES_RESOURCES_H - -#include <QtGlobal> - -inline void InitIconResources() -{ - Q_INIT_RESOURCE(icons); -} - -#endif // BORNAGAIN_GUI2_RESOURCES_RESOURCES_H diff --git a/gui2/settingsview/CMakeLists.txt b/gui2/settingsview/CMakeLists.txt deleted file mode 100644 index 332b321d7a26aff7566adca0f79861cb0c1c8289..0000000000000000000000000000000000000000 --- a/gui2/settingsview/CMakeLists.txt +++ /dev/null @@ -1,4 +0,0 @@ -target_sources(${library_name} PRIVATE - settingsview.cpp - settingsview.h -) diff --git a/gui2/settingsview/settingsview.cpp b/gui2/settingsview/settingsview.cpp deleted file mode 100644 index af103356cb963a5b4b0f6e381f918a7cb90f2a05..0000000000000000000000000000000000000000 --- a/gui2/settingsview/settingsview.cpp +++ /dev/null @@ -1,83 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/settingsview/settingsview.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/settingsview/settingsview.h" -#include "gui2/model/applicationmodels.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/widgets/allitemstreeview.h" -#include "mvvm/widgets/widgetutils.h" -#include <QHBoxLayout> -#include <QListView> -#include <QListWidget> -#include <QStackedWidget> -#include <QTabWidget> -#include <QTreeView> - -namespace gui2 { - -SettingsView::SettingsView(ApplicationModels* models, QWidget* parent) - : QWidget(parent) - , m_listWidget(new QListWidget) - , m_stackedWidget(new QStackedWidget) - , m_tabWidget(new QTabWidget) - , m_models(models) -{ - init_list_selector(); - init_model_settings(); - init_other_settings(); - - auto layout = new QHBoxLayout(this); - layout->addWidget(m_listWidget); - layout->addSpacing(ModelView::Utils::WidthOfLetterM() / 2); - layout->addWidget(m_stackedWidget); - - m_stackedWidget->setCurrentIndex(0); -} - -//! Initialize tabs with model content. -//! Each model will be represented by a single tree (with all items shown) in a tab. - -void SettingsView::init_model_settings() -{ - for (auto model : m_models->application_models()) { - auto view = new ModelView::AllItemsTreeView(model); - view->treeView()->setAlternatingRowColors(true); - m_tabWidget->addTab(view, QString::fromStdString(model->modelType())); - } - m_stackedWidget->addWidget(m_tabWidget); -} - -void SettingsView::init_list_selector() -{ - const int width = ModelView::Utils::WidthOfLetterM() * 10; - m_listWidget->setFixedWidth(width); - m_listWidget->setIconSize( - QSize(ModelView::Utils::WidthOfLetterM() * 1.2, ModelView::Utils::WidthOfLetterM() * 1.2)); - - auto item = new QListWidgetItem(QIcon(":/icons/card-bulleted-outline.svg"), "All models"); - m_listWidget->addItem(item); - - item = new QListWidgetItem(QIcon(":/icons/cog-outline.svg"), "Miscellaneous"); - m_listWidget->addItem(item); - - connect(m_listWidget, &QListWidget::currentRowChanged, - [this](int row) { m_stackedWidget->setCurrentIndex(row); }); -} - -void SettingsView::init_other_settings() -{ - m_stackedWidget->addWidget(new QWidget); -} - -} // namespace gui2 diff --git a/gui2/settingsview/settingsview.h b/gui2/settingsview/settingsview.h deleted file mode 100644 index c54c58c069d5a15c420116a5338639fd7eeea678..0000000000000000000000000000000000000000 --- a/gui2/settingsview/settingsview.h +++ /dev/null @@ -1,53 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/settingsview/settingsview.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_SETTINGSVIEW_SETTINGSVIEW_H -#define BORNAGAIN_GUI2_SETTINGSVIEW_SETTINGSVIEW_H - -#include "darefl_export.h" -#include <QWidget> - -class QTabWidget; -class QStackedWidget; -class QListWidget; - -namespace gui2 { - -class ApplicationModels; - -//! Main settings view, belongs directly to MainWindow. -//! For the moment contains QTabWidget with trees representating all application models. -//! In the future, might be extended to have any type of settings. - -class DAREFLCORE_EXPORT SettingsView : public QWidget { - Q_OBJECT - -public: - SettingsView(ApplicationModels* models, QWidget* parent = nullptr); - -private: - void init_list_selector(); - void init_model_settings(); - void init_other_settings(); - - QListWidget* m_listWidget; //!< selector for specific settings window on the left - QStackedWidget* m_stackedWidget{nullptr}; //!< stack with settings widgets - QTabWidget* m_tabWidget{nullptr}; //!< application model settings - - ApplicationModels* m_models{nullptr}; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_SETTINGSVIEW_SETTINGSVIEW_H diff --git a/gui2/sldeditor/CMakeLists.txt b/gui2/sldeditor/CMakeLists.txt deleted file mode 100644 index dc72eb3b3ff58ec88470aa5b02d4b77078aa7537..0000000000000000000000000000000000000000 --- a/gui2/sldeditor/CMakeLists.txt +++ /dev/null @@ -1,28 +0,0 @@ -target_sources(${library_name} PRIVATE - sldelementmodel.h - sldelementmodel.cpp - layerelementcontroller.h - layerelementcontroller.cpp - layerelementitem.h - layerelementitem.cpp - sldelementcontroller.cpp - sldelementcontroller.h - elementview.h - elementview.cpp - segmentelementview.h - segmentelementview.cpp - handleelementview.h - handleelementview.cpp - roughnesselementview.h - roughnesselementview.cpp - graphicsscene.cpp - graphicsscene.h - sldviewwidget.h - sldviewwidget.cpp - sldeditor.h - sldeditor.cpp - sldeditoractions.h - sldeditoractions.cpp - sldeditortoolbar.h - sldeditortoolbar.cpp -) diff --git a/gui2/sldeditor/elementview.cpp b/gui2/sldeditor/elementview.cpp deleted file mode 100644 index ab0555026e4ce41bbd7bd976e7e6d782e4b9ae12..0000000000000000000000000000000000000000 --- a/gui2/sldeditor/elementview.cpp +++ /dev/null @@ -1,265 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/sldeditor/elementview.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/sldeditor/elementview.h" -#include "gui2/sldeditor/graphicsscene.h" -#include "mvvm/plotting/sceneadapterinterface.h" - -#include <QCursor> -#include <QPainter> -#include <QPainterPath> - -namespace gui2 { - -//! The constructor -ElementView::ElementView() : QGraphicsObject() -{ - setAcceptHoverEvents(true); -} - -ElementView::~ElementView() = default; - -//! Get the conversion axes -ModelView::SceneAdapterInterface* ElementView::sceneAdapter() const -{ - GraphicsScene* scene_item = static_cast<GraphicsScene*>(scene()); - if (!scene_item) - return nullptr; - - return scene_item->sceneAdapter(); -} - -//! Advance method used by the scene adapter -void ElementView::advance(int phase) -{ - if (!phase) - return; - prepareGeometryChange(); - update(); -} - -//! paint override -void ElementView::paint(QPainter* painter, const QStyleOptionGraphicsItem* /*option*/, - QWidget* /*widget*/) -{ - painter->setClipRect(sceneAdapter()->viewportRectangle()); -} - -//! modify the rectangle for display according to the scene adapter -QRectF ElementView::displayRect(const QRectF& real_rect) const -{ - auto adapter = sceneAdapter(); - if (!adapter) - return real_rect; - - auto output = QRectF(real_rect); - - if (m_center_based) { - output = displayRectCenterBased(real_rect); - } else { - output = displayRectEdgeBased(real_rect); - } - - if (m_stretch_left) { - output = stretchRectLeft(output); - } else if (m_stretch_right) { - output = stretchRectRight(output); - } - - return output; -} - -//! Helper function for displayRect based on the center of real_rect -QRectF ElementView::displayRectCenterBased(const QRectF& real_rect) const -{ - auto adapter = sceneAdapter(); - double x = real_rect.x(); - double y = real_rect.y(); - double w = real_rect.width(); - double h = real_rect.height(); - - double center_x = x + w / 2.; - double center_y = y + h / 2.; - - if (m_adapt_x) { - center_x = adapter->toSceneX(-center_x); - } - if (m_adapt_y) { - center_y = adapter->toSceneY(center_y); - } - if (m_adapt_width) { - w = adapter->toSceneX(w) - adapter->toSceneX(0); - } - if (m_adapt_height) { - h = adapter->toSceneY(h) - adapter->toSceneY(0); - } - - x = center_x - w / 2; - y = center_y - h / 2; - - return QRectF(x, y, w, h); -} - -//! Helper function for displayRect based on the edge of real_rect -QRectF ElementView::displayRectEdgeBased(const QRectF& real_rect) const -{ - auto adapter = sceneAdapter(); - double x = real_rect.x(); - double y = real_rect.y(); - double w = real_rect.width(); - double h = real_rect.height(); - - if (m_adapt_x) { - x = adapter->toSceneX(-x); - } - if (m_adapt_y) { - y = adapter->toSceneY(y); - } - if (m_adapt_width) { - w = adapter->toSceneX(w) - adapter->toSceneX(0); - } - if (m_adapt_height) { - h = adapter->toSceneY(h) - adapter->toSceneY(0); - } - - return QRectF(x, y, w, h); -} - -//! Stretch the rectangle to the left limit of the viewport -QRectF ElementView::stretchRectLeft(const QRectF& real_rect) const -{ - double x_i = real_rect.x(); - double y_i = real_rect.y(); - double x_f = real_rect.x() + real_rect.width(); - double y_f = real_rect.y() + real_rect.height(); - - auto viewport_rect = sceneAdapter()->viewportRectangle(); - x_i = viewport_rect.x(); - - return QRectF(x_i, y_i, x_f - x_i, y_f - y_i); -} - -//! Stretch the rectangle to the right limit of the viewport -QRectF ElementView::stretchRectRight(const QRectF& real_rect) const -{ - double x_i = real_rect.x(); - double y_i = real_rect.y(); - double x_f = real_rect.x() + real_rect.width(); - double y_f = real_rect.y() + real_rect.height(); - - auto viewport_rect = sceneAdapter()->viewportRectangle(); - x_f = viewport_rect.x() + viewport_rect.width(); - - return QRectF(x_i, y_i, x_f - x_i, y_f - y_i); -} - -//! modify the path for display according to the scene adapter -QPainterPath ElementView::displayPath(QPainterPath real_path) const -{ - auto adapter = sceneAdapter(); - if (!adapter) - return real_path; - - auto display_path = QPainterPath(real_path); - for (int i = 0; i < display_path.elementCount(); i++) { - QPointF pt = display_path.elementAt(i); - display_path.setElementPositionAt(i, adapter->toSceneX(-pt.x()), adapter->toSceneY(pt.y())); - } - return display_path; -} - -//! modify the rectangle for display according to the scene adapter -QPointF ElementView::scenePos(QPointF pixel_pos) const -{ - auto adapter = sceneAdapter(); - if (!adapter) - return pixel_pos; - - return QPointF(-adapter->fromSceneX(pixel_pos.x()), adapter->fromSceneY(pixel_pos.y())); -} - -//! Adapt the dimensions according to the center -void ElementView::setCenterBased(bool choice) -{ - m_center_based = choice; -} - -//! Adapt the x position -void ElementView::adaptX(bool choice) -{ - m_adapt_x = choice; -} - -//! Adapt the y position -void ElementView::adaptY(bool choice) -{ - m_adapt_y = choice; -} - -//! Adapt the width -void ElementView::adaptW(bool choice) -{ - m_adapt_width = choice; -} - -//! Adapt the height -void ElementView::adaptH(bool choice) -{ - m_adapt_height = choice; -} - -//! Stretch the rectangle to the left limit of the viewport -void ElementView::stretchLeft(bool choice) -{ - m_stretch_left = choice; -} - -//! Stretch the rectangle to the right limit of the viewport -void ElementView::stretchRight(bool choice) -{ - m_stretch_right = choice; -} - -//! The hoover enter event -void ElementView::hoverEnterEvent(QGraphicsSceneHoverEvent* event) -{ - if (flags() & QGraphicsItem::ItemIsMovable) - setCursor(QCursor(Qt::OpenHandCursor)); - QGraphicsItem::hoverEnterEvent(event); -} - -//! The hoover exit event -void ElementView::hoverLeaveEvent(QGraphicsSceneHoverEvent* event) -{ - unsetCursor(); - QGraphicsItem::hoverLeaveEvent(event); -} - -//! The mouse press event -void ElementView::mousePressEvent(QGraphicsSceneMouseEvent* event) -{ - if (flags() & QGraphicsItem::ItemIsMovable) - setCursor(QCursor(Qt::ClosedHandCursor)); - QGraphicsItem::mousePressEvent(event); -} - -//! The mouse release event -void ElementView::mouseReleaseEvent(QGraphicsSceneMouseEvent* event) -{ - if (flags() & QGraphicsItem::ItemIsMovable) - setCursor(QCursor(Qt::OpenHandCursor)); - QGraphicsItem::mouseReleaseEvent(event); -} - -} // namespace gui2 diff --git a/gui2/sldeditor/elementview.h b/gui2/sldeditor/elementview.h deleted file mode 100644 index 4296b5977647a7cac756a5733a40775752679528..0000000000000000000000000000000000000000 --- a/gui2/sldeditor/elementview.h +++ /dev/null @@ -1,74 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/sldeditor/elementview.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_SLDEDITOR_ELEMENTVIEW_H -#define BORNAGAIN_GUI2_SLDEDITOR_ELEMENTVIEW_H - -#include "darefl_export.h" -#include "gui2/sldeditor/graphicsscene.h" - -#include <QGraphicsObject> - -namespace gui2 { - -//! The interface of any QGraphicsViewItem on GraphicsScene to the Sceneadapter -class DAREFLCORE_EXPORT ElementView : public QGraphicsObject { - Q_OBJECT - -public: - ElementView(); - ~ElementView(); - - void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) override; - void advance(int phase) override; - - ModelView::SceneAdapterInterface* sceneAdapter() const; - - void setCenterBased(bool choice); - void adaptX(bool choice); - void adaptY(bool choice); - void adaptW(bool choice); - void adaptH(bool choice); - void stretchLeft(bool choice); - void stretchRight(bool choice); - -protected: - QRectF displayRect(const QRectF& real_rect) const; - QPainterPath displayPath(QPainterPath real_path) const; - QPointF scenePos(QPointF pixel_pos) const; - - void hoverEnterEvent(QGraphicsSceneHoverEvent* event) override; - void hoverLeaveEvent(QGraphicsSceneHoverEvent* event) override; - void mousePressEvent(QGraphicsSceneMouseEvent* event) override; - void mouseReleaseEvent(QGraphicsSceneMouseEvent* event) override; - -private: - QRectF displayRectCenterBased(const QRectF& real_rect) const; - QRectF displayRectEdgeBased(const QRectF& real_rect) const; - QRectF stretchRectLeft(const QRectF& real_rect) const; - QRectF stretchRectRight(const QRectF& real_rect) const; - -private: - bool m_center_based = true; - bool m_adapt_x = true; - bool m_adapt_y = true; - bool m_adapt_width = true; - bool m_adapt_height = true; - bool m_stretch_left = false; - bool m_stretch_right = false; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_SLDEDITOR_ELEMENTVIEW_H diff --git a/gui2/sldeditor/graphicsscene.cpp b/gui2/sldeditor/graphicsscene.cpp deleted file mode 100644 index 18f3f8bfc168495d9a01e263eda86cce8b6134db..0000000000000000000000000000000000000000 --- a/gui2/sldeditor/graphicsscene.cpp +++ /dev/null @@ -1,87 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/sldeditor/graphicsscene.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/sldeditor/graphicsscene.h" - -#include "mvvm/model/modelutils.h" -#include "mvvm/plotting/customplotproxywidget.h" -#include "mvvm/plotting/graphcanvas.h" -#include "mvvm/plotting/sceneadapterinterface.h" -#include "mvvm/standarditems/graphviewportitem.h" - -namespace { -const double scene_origin_x{0.0}; -const double scene_origin_y{0.0}; -const QRectF default_scene_rect{QPointF{scene_origin_x, scene_origin_y}, QSizeF{800, 600}}; -} // namespace - -namespace gui2 { - -//! The contructor -GraphicsScene::GraphicsScene(QObject* parent) : QGraphicsScene(parent) -{ - setItemIndexMethod(QGraphicsScene::NoIndex); - setSceneRect(default_scene_rect); - setContext(); -} - -//! The destructor -GraphicsScene::~GraphicsScene() = default; - -//! Initialise the GraphicsScene with its elements -void GraphicsScene::setContext() -{ - graph_canvas = new ModelView::GraphCanvas; - createPlotProxy(graph_canvas); -} - -//! Set te graph canvas item -void GraphicsScene::setItem(ModelView::GraphViewportItem* viewport_item) -{ - graph_canvas->setItem(viewport_item); -} - -//! Set te graph canvas item -ModelView::GraphCanvas* GraphicsScene::graphCanvas() const -{ - return graph_canvas; -} - -//! Adjust size of scene and color map proxy. -void GraphicsScene::update_size(const QSize& newSize) -{ - if (plot_proxy) { - plot_proxy->resize(newSize); - setSceneRect(scene_origin_x, scene_origin_y, newSize.width(), newSize.height()); - plot_proxy->setPos(0.0, 0.0); - advance(); // notifies all QGraphicsItem that it is time to replot themself using new status - // of scene adapter - } -} - -//! Create the Proxy item -void GraphicsScene::createPlotProxy(ModelView::GraphCanvas* plot_canvas) -{ - scene_adapter = plot_canvas->createSceneAdapter(); - plot_proxy = new ModelView::CustomPlotProxyWidget(plot_canvas); - addItem(plot_proxy); -} - -//! Return the pointer of the scene adapter on request -ModelView::SceneAdapterInterface* GraphicsScene::sceneAdapter() const -{ - return scene_adapter.get(); -} - -} // namespace gui2 diff --git a/gui2/sldeditor/graphicsscene.h b/gui2/sldeditor/graphicsscene.h deleted file mode 100644 index e4c32a6a5c1cd149460bcd0e2859c7656b64e393..0000000000000000000000000000000000000000 --- a/gui2/sldeditor/graphicsscene.h +++ /dev/null @@ -1,56 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/sldeditor/graphicsscene.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_SLDEDITOR_GRAPHICSSCENE_H -#define BORNAGAIN_GUI2_SLDEDITOR_GRAPHICSSCENE_H - -#include "darefl_export.h" -#include <QGraphicsScene> -#include <memory> - -namespace ModelView { -class GraphCanvas; -class SceneAdapterInterface; -class GraphViewportItem; -class CustomPlotProxyWidget; -} // namespace ModelView - -namespace gui2 { - -class RegionOfInterestItem; - -//! Custom graphics scene to show QCustomPlot with additional elements on top. -class DAREFLCORE_EXPORT GraphicsScene : public QGraphicsScene { - Q_OBJECT - -public: - GraphicsScene(QObject* parent = nullptr); - ~GraphicsScene() override; - - void setContext(); - void setItem(ModelView::GraphViewportItem* viewport_item); - ModelView::GraphCanvas* graphCanvas() const; - ModelView::SceneAdapterInterface* sceneAdapter() const; - void update_size(const QSize& newSize); - -private: - void createPlotProxy(ModelView::GraphCanvas* plot_canvas); - ModelView::CustomPlotProxyWidget* plot_proxy{nullptr}; - std::unique_ptr<ModelView::SceneAdapterInterface> scene_adapter; - ModelView::GraphCanvas* graph_canvas{nullptr}; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_SLDEDITOR_GRAPHICSSCENE_H diff --git a/gui2/sldeditor/handleelementview.cpp b/gui2/sldeditor/handleelementview.cpp deleted file mode 100644 index 4593ef4e7acbd2328ea2f44f2796b43ceb342719..0000000000000000000000000000000000000000 --- a/gui2/sldeditor/handleelementview.cpp +++ /dev/null @@ -1,98 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/sldeditor/handleelementview.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/sldeditor/handleelementview.h" -#include "gui2/sldeditor/layerelementcontroller.h" - -#include <QGraphicsSceneMouseEvent> -#include <QPainter> -#include <QStyleOption> - -namespace gui2 { - -//! The constructor -HandleElementView::HandleElementView() - : ElementView() - , m_pos(QPointF(0, 0)) - , m_rectangle(QRectF(0, 0, 0, 0)) - , m_brush(QBrush()) - , m_pen(QPen()) -{ - adaptW(false); - adaptH(false); - setZValue(2); -} - -//! The overriden paint method -void HandleElementView::paint(QPainter* painter, const QStyleOptionGraphicsItem*, QWidget*) -{ - painter->setClipRect(sceneAdapter()->viewportRectangle()); - painter->setPen(m_pen); - painter->setBrush(m_brush); - painter->drawEllipse(displayRect(m_rectangle)); -} - -//! The shape -QPainterPath HandleElementView::shape() const -{ - QPainterPath path; - path.addRect(displayRect(m_rectangle)); - return path; -} - -//! The bounding rectangle of the handle -QRectF HandleElementView::boundingRect() const -{ - return displayRect(m_rectangle); -} - -//! On move update the model -void HandleElementView::mouseMoveEvent(QGraphicsSceneMouseEvent* event) -{ - m_pos = scenePos(event->pos()); - p_controller->handleViewMoved(this); -} - -//! Set the controller to report back the move -void HandleElementView::setLayerElementController(LayerElementController* controller) -{ - p_controller = controller; -} - -//! Set the draw rectangle -void HandleElementView::setRectangle(QRectF rectangle) -{ - prepareGeometryChange(); - m_rectangle = rectangle; -} - -//! Set the brush -void HandleElementView::setBrush(QBrush brush) -{ - m_brush = brush; -} - -//! Set the pen -void HandleElementView::setPen(QPen pen) -{ - m_pen = pen; -} - -//! Get the last position of the item -QPointF HandleElementView::getLastPos() const -{ - return m_pos; -} - -} // namespace gui2 diff --git a/gui2/sldeditor/handleelementview.h b/gui2/sldeditor/handleelementview.h deleted file mode 100644 index 5d7a03a301e386d2639403609680b3c6e4880cd5..0000000000000000000000000000000000000000 --- a/gui2/sldeditor/handleelementview.h +++ /dev/null @@ -1,56 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/sldeditor/handleelementview.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_SLDEDITOR_HANDLEELEMENTVIEW_H -#define BORNAGAIN_GUI2_SLDEDITOR_HANDLEELEMENTVIEW_H - -#include "darefl_export.h" -#include "gui2/sldeditor/elementview.h" - -#include <QBrush> -#include <QPen> -#include <QRectF> - -namespace gui2 { - -class LayerElementController; - -//! The handle QGraphicsViewItem on GraphicsScene -class DAREFLCORE_EXPORT HandleElementView : public ElementView { -public: - HandleElementView(); - QRectF boundingRect() const override; - QPainterPath shape() const override; - void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) override; - - void setLayerElementController(LayerElementController* controller); - void setRectangle(QRectF rectangle); - void setBrush(QBrush brush); - void setPen(QPen pen); - QPointF getLastPos() const; - -public: - void mouseMoveEvent(QGraphicsSceneMouseEvent* event) override; - -protected: - LayerElementController* p_controller; - QPointF m_pos; - QRectF m_rectangle; - QBrush m_brush; - QPen m_pen; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_SLDEDITOR_HANDLEELEMENTVIEW_H diff --git a/gui2/sldeditor/layerelementcontroller.cpp b/gui2/sldeditor/layerelementcontroller.cpp deleted file mode 100644 index 3f8b8670ca21d0f2a412a3a9701020d8dc422695..0000000000000000000000000000000000000000 --- a/gui2/sldeditor/layerelementcontroller.cpp +++ /dev/null @@ -1,912 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/sldeditor/layerelementcontroller.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/sldeditor/layerelementcontroller.h" - -#include "gui2/sldeditor/graphicsscene.h" -#include "gui2/sldeditor/handleelementview.h" -#include "gui2/sldeditor/layerelementitem.h" -#include "gui2/sldeditor/roughnesselementview.h" -#include "gui2/sldeditor/segmentelementview.h" - -#include "mvvm/signals/itemmapper.h" -#include <stdexcept> -#include <string> - -using namespace ModelView; - -namespace gui2 { - -//! Constructor -LayerElementController::LayerElementController(LayerElementItem* layer_view_item) - : QObject(), p_model_item(layer_view_item), m_sample_item_id(" ") -{ -} - -//! Returns the pointer to the LayerElementItem in the model -LayerElementItem* LayerElementController::layerElementItem() const -{ - return p_model_item; -} - -//! Allow the population of the own elements -void LayerElementController::autoPopulate() -{ - setSideSegment(new SegmentElementView()); - setTopSegment(new SegmentElementView()); - setSegmentHandles(new HandleElementView(), new HandleElementView()); - setRoughness(new RoughnessElementView()); - setRoughnessHandles(new HandleElementView(), new HandleElementView()); -} - -//! If loacally created the view elements nees to be locally destroyed -void LayerElementController::deleteViewItems() -{ - if (m_segment_views[0]) { - auto temp_ptr = m_segment_views[0]; - unsetSideSegment(); - delete temp_ptr; - } - if (m_segment_views[1]) { - auto temp_ptr = m_segment_views[1]; - unsetTopSegment(); - delete temp_ptr; - } - if (m_handle_views[0]) { - auto temp_ptr_0 = m_handle_views[0]; - auto temp_ptr_1 = m_handle_views[1]; - unsetSegmentHandles(); - delete temp_ptr_0; - delete temp_ptr_1; - } - if (p_roughness_view) { - auto temp_ptr = p_roughness_view; - unsetRoughness(); - delete temp_ptr; - } - if (m_rough_handles_views[0]) { - auto temp_ptr_0 = m_rough_handles_views[0]; - auto temp_ptr_1 = m_rough_handles_views[1]; - unsetRoughnessHandles(); - delete temp_ptr_0; - delete temp_ptr_1; - } -} - -//! Connect to the set item -void LayerElementController::connectToModel() const -{ - auto on_property_change = [this](ModelView::SessionItem* /*item*/, std::string property_name) { - if (property_name == LayerElementItem::P_X_POS) { - updateSideSegment(); - updateTopSegment(); - updateSegmentHandles(); - updateRoughness(); - if (layerBelow()) - layerBelow()->layerElementItem()->setProperty( - LayerElementItem::P_X_POS, - layerElementItem()->property<double>(LayerElementItem::P_X_POS) - + layerElementItem()->property<double>(LayerElementItem::P_WIDTH)); - } - if (property_name == LayerElementItem::P_HEIGHT) { - emit heightChanged(m_sample_item_id, - layerElementItem()->property<double>(LayerElementItem::P_HEIGHT)); - updateSideSegment(); - updateTopSegment(); - updateSegmentHandles(); - updateRoughness(); - if (layerBelow()) { - layerBelow()->updateSideSegment(); - layerBelow()->updateSegmentHandles(); - layerBelow()->updateRoughness(); - } - } - if (property_name == LayerElementItem::P_WIDTH) { - emit widthChanged(m_sample_item_id, - layerElementItem()->property<double>(LayerElementItem::P_WIDTH)); - updateSideSegment(); - updateTopSegment(); - updateSegmentHandles(); - updateRoughness(); - if (layerBelow()) - layerBelow()->layerElementItem()->setProperty( - LayerElementItem::P_X_POS, - layerElementItem()->property<double>(LayerElementItem::P_X_POS) - + layerElementItem()->property<double>(LayerElementItem::P_WIDTH)); - } - if (property_name == LayerElementItem::P_ROUGHNESS) { - emit roughnessChanged(m_sample_item_id, layerElementItem()->property<double>( - LayerElementItem::P_ROUGHNESS)); - updateRoughness(); - } - - // Side segment update - if (property_name == LayerElementItem::P_SIDE_THICKNESS) { - updateSideSegment(); - } - if (property_name == LayerElementItem::P_SIDE_PEN_WIDTH) { - updateSideSegment(); - } - if (property_name == LayerElementItem::P_SIDE_PEN_COLOR) { - updateSideSegment(); - } - if (property_name == LayerElementItem::P_SIDE_BRUSH_COLOR) { - updateSideSegment(); - } - - // Top segment update - if (property_name == LayerElementItem::P_TOP_THICKNESS) { - updateTopSegment(); - } - if (property_name == LayerElementItem::P_TOP_PEN_WIDTH) { - updateTopSegment(); - } - if (property_name == LayerElementItem::P_TOP_PEN_COLOR) { - updateTopSegment(); - } - if (property_name == LayerElementItem::P_TOP_BRUSH_COLOR) { - updateTopSegment(); - } - - // Segment handle update - if (property_name == LayerElementItem::P_HANDLE_RADIUS) { - updateSegmentHandles(); - } - if (property_name == LayerElementItem::P_HANDLE_BRUSH_COLOR) { - updateSegmentHandles(); - } - if (property_name == LayerElementItem::P_HANDLE_PEN_WIDTH) { - updateSegmentHandles(); - } - if (property_name == LayerElementItem::P_HANDLE_PEN_COLOR) { - updateSegmentHandles(); - } - - // Roughness handles update - if (property_name == LayerElementItem::P_R_HANDLE_RADIUS) { - updateRoughness(); - } - if (property_name == LayerElementItem::P_R_HANDLE_BRUSH_COLOR) { - updateRoughness(); - } - if (property_name == LayerElementItem::P_R_HANDLE_PEN_WIDTH) { - updateRoughness(); - } - if (property_name == LayerElementItem::P_R_HANDLE_PEN_COLOR) { - updateRoughness(); - } - - // Roughness update - if (property_name == LayerElementItem::P_ROUGHNESS_BRUSH_COLOR) { - updateRoughness(); - } - if (property_name == LayerElementItem::P_ROUGHNESS_PEN_WIDTH) { - updateRoughness(); - } - if (property_name == LayerElementItem::P_ROUGHNESS_PEN_COLOR) { - updateRoughness(); - } - }; - - layerElementItem()->mapper()->setOnPropertyChange(on_property_change, this); -} - -//! Disconnect from the set item -void LayerElementController::disconnectFormModel() const -{ - layerElementItem()->mapper()->unsubscribe(this); -} - -//! Set the scene -void LayerElementController::setScene(GraphicsScene* scene) -{ - if (!scene) - return; - - p_scene = scene; - - putSegementsOnScene(); - putSegmentHandlesOnScene(); - putRoughnessOnScene(); - putRoughnessHandlesOnScene(); -} - -//! Return the current set scene -GraphicsScene* LayerElementController::scene() const -{ - return p_scene; -} - -//! Set the scene -void LayerElementController::unsetScene() -{ - if (!scene()) - return; - - removeSegmentsFromScene(); - removeSegmentHandlesFromScene(); - removeRoughnessFromScene(); - removeRoughnessHandlesFromScene(); - p_scene = nullptr; -} - -//! Set the idenfier of the sample item to report -void LayerElementController::setSampleItemId(std::string identifier) -{ - m_sample_item_id = identifier; -} - -//! Return the set sample item identifier -std::string LayerElementController::sampleItemId() const -{ - return m_sample_item_id; -} - -//! Unset the sample item identifier -void LayerElementController::unsetSampleItemId() -{ - m_sample_item_id = " "; -} - -//! Get the scene adapter to convert to axes -SceneAdapterInterface* LayerElementController::sceneAdapter() const -{ - if (!p_scene) - return nullptr; - - return p_scene->sceneAdapter(); -} - -//! Set the layer above the current one in relation -void LayerElementController::setLayerAbove(LayerElementController* layer_view_controller) -{ - p_controller_above = layer_view_controller; - - if (layer_view_controller->layerBelow() != this) - layer_view_controller->setLayerBelow(this); - - double pos = - p_controller_above->layerElementItem()->property<double>(LayerElementItem::P_X_POS) - + p_controller_above->layerElementItem()->property<double>(LayerElementItem::P_WIDTH); - layerElementItem()->setProperty(LayerElementItem::P_X_POS, pos); -} - -//! Set the layer below the current one in relation -void LayerElementController::setLayerBelow(LayerElementController* layer_view_controller) -{ - p_controller_below = layer_view_controller; - - if (layer_view_controller->layerAbove() != this) - layer_view_controller->setLayerAbove(this); -} - -//! Return the layer above the current one in relation -LayerElementController* LayerElementController::layerAbove() const -{ - return p_controller_above; -} - -//! Return the layer below the current one in relation -LayerElementController* LayerElementController::layerBelow() const -{ - return p_controller_below; -} - -//! Unset the layer above the current one in relation -void LayerElementController::unsetLayerAbove(bool silent) -{ - if (!p_controller_above) - return; - - if (silent) - p_controller_above->unsetLayerBelow(false); - - p_controller_above = nullptr; -} - -//! Unset the layer below the current one in relation -void LayerElementController::unsetLayerBelow(bool silent) -{ - if (!p_controller_below) - return; - - if (silent) - p_controller_below->unsetLayerAbove(false); - - p_controller_below = nullptr; -} - -//! Set the side segment elements -void LayerElementController::setSideSegment(SegmentElementView* segment_view) -{ - m_segment_views[0] = segment_view; - m_segment_views[0]->adaptW(false); - m_segment_views[0]->setLayerElementController(this); - updateSideSegment(); - - if (scene()) - scene()->addItem(m_segment_views[0]); -} - -//! Set the top segment elements -void LayerElementController::setTopSegment(SegmentElementView* segment_view) -{ - m_segment_views[1] = segment_view; - m_segment_views[1]->adaptH(false); - m_segment_views[1]->setLayerElementController(this); - updateTopSegment(); - - if (scene()) - scene()->addItem(m_segment_views[1]); -} - -//! Return the side Segment view -SegmentElementView* LayerElementController::sideSegment() const -{ - return m_segment_views[0]; -} - -//! Return the top Segment view -SegmentElementView* LayerElementController::topSegment() const -{ - return m_segment_views[1]; -} - -//! Unset the side segment elements -void LayerElementController::unsetSideSegment() -{ - if (m_segment_views[0] && scene() && m_segment_views[0]->scene() == scene()) - scene()->removeItem(m_segment_views[0]); - - m_segment_views[0] = nullptr; -} - -//! Unset the top segment elements -void LayerElementController::unsetTopSegment() -{ - if (m_segment_views[1] && scene() && m_segment_views[1]->scene() == scene()) - scene()->removeItem(m_segment_views[1]); - - m_segment_views[1] = nullptr; -} - -//! The move logic for the segments -void LayerElementController::segmentViewMoved(SegmentElementView* segment_view) -{ - if (segment_view == sideSegment()) { - sideSegmentMoved(); - } else if (segment_view == topSegment()) { - topSegmentMoved(); - } -} - -//! Update the view of the side segment -void LayerElementController::updateSideSegment() const -{ - if (!m_segment_views[0]) - return; - - auto pen = QPen(); - pen.setColor(layerElementItem()->property<QColor>(LayerElementItem::P_SIDE_PEN_COLOR)); - pen.setWidthF(layerElementItem()->property<double>(LayerElementItem::P_SIDE_PEN_WIDTH)); - m_segment_views.at(0)->setPen(pen); - - auto brush = QBrush(Qt::SolidPattern); - brush.setColor(layerElementItem()->property<QColor>(LayerElementItem::P_SIDE_BRUSH_COLOR)); - m_segment_views.at(0)->setBrush(brush); - - m_segment_views.at(0)->setRectangle(sideSegmentRect()); -} - -//! Update the view of the top segment -void LayerElementController::updateTopSegment() const -{ - if (!m_segment_views[1]) - return; - - auto pen = QPen(); - pen.setColor(layerElementItem()->property<QColor>(LayerElementItem::P_TOP_PEN_COLOR)); - pen.setWidthF(layerElementItem()->property<double>(LayerElementItem::P_TOP_PEN_WIDTH)); - m_segment_views.at(1)->setPen(pen); - - auto brush = QBrush(Qt::SolidPattern); - brush.setColor(layerElementItem()->property<QColor>(LayerElementItem::P_TOP_BRUSH_COLOR)); - m_segment_views.at(1)->setBrush(brush); - - m_segment_views.at(1)->setRectangle(topSegmentRect()); -} - -//! Return the side segment rectangle -QRectF LayerElementController::sideSegmentRect() const -{ - double this_pos = layerElementItem()->property<double>(LayerElementItem::P_X_POS); - double this_height = layerElementItem()->property<double>(LayerElementItem::P_HEIGHT); - double this_thickness = - layerElementItem()->property<double>(LayerElementItem::P_SIDE_THICKNESS); - - double above_height = 0; - if (layerAbove()) { - above_height = - layerAbove()->layerElementItem()->property<double>(LayerElementItem::P_HEIGHT); - } - - if (above_height > this_height) { - return QRectF(this_pos - this_thickness / 2., this_height, this_thickness, - above_height - this_height); - } else { - return QRectF(this_pos - this_thickness / 2., above_height, this_thickness, - this_height - above_height); - } -} - -//! Return the top segment rectangle -QRectF LayerElementController::topSegmentRect() const -{ - double pos = layerElementItem()->property<double>(LayerElementItem::P_X_POS); - double height = layerElementItem()->property<double>(LayerElementItem::P_HEIGHT); - double width = layerElementItem()->property<double>(LayerElementItem::P_WIDTH); - double thickness = layerElementItem()->property<double>(LayerElementItem::P_TOP_THICKNESS); - return QRectF(pos, height - thickness / 2., width, thickness); -} - -//! Put segments on scene -void LayerElementController::putSegementsOnScene() const -{ - if (!scene()) - return; - for (auto segment_view : m_segment_views) { - if (segment_view) - scene()->addItem(segment_view); - } -} - -//! Remove the segments from the scene -void LayerElementController::removeSegmentsFromScene() const -{ - if (!scene()) - return; - for (auto segment_view : m_segment_views) { - if (segment_view && segment_view->scene() == scene()) - scene()->removeItem(segment_view); - } -} - -//! Handle the position variation of the side segment -void LayerElementController::sideSegmentMoved() const -{ - double x = sideSegment()->getLastPos().x(); - if (layerAbove()) { - double w = 0; - auto item = layerAbove()->layerElementItem(); - if (x < item->property<double>(LayerElementItem::P_X_POS)) { - x = item->property<double>(LayerElementItem::P_X_POS) + w; - } else { - w = x - item->property<double>(LayerElementItem::P_X_POS); - } - item->setProperty(LayerElementItem::P_WIDTH, w); - } - layerElementItem()->setProperty(LayerElementItem::P_X_POS, x); -} - -//! Handle the position variation of the top segment -void LayerElementController::topSegmentMoved() const -{ - double y = topSegment()->getLastPos().y(); - if (y < 0) - y = 0; - layerElementItem()->setProperty(LayerElementItem::P_HEIGHT, y); -} - -//! Set the side segment elements -void LayerElementController::setSegmentHandles(HandleElementView* first_handle, - HandleElementView* second_handle) -{ - m_handle_views[0] = first_handle; - m_handle_views[1] = second_handle; - m_handle_views[0]->setLayerElementController(this); - m_handle_views[1]->setLayerElementController(this); - updateSegmentHandles(); - - if (scene()) { - scene()->addItem(m_handle_views[0]); - scene()->addItem(m_handle_views[1]); - } -} - -//! Return the side Segment view -HandleElementView* LayerElementController::firstSegmentHandle() const -{ - return m_handle_views[0]; -} - -//! Return the top Segment view -HandleElementView* LayerElementController::secondSegmentHandle() const -{ - return m_handle_views[1]; -} - -//! Unset the side segment elements -void LayerElementController::unsetSegmentHandles() -{ - if (m_handle_views[0] && scene() && m_handle_views[0]->scene() == scene()) - scene()->removeItem(m_handle_views[0]); - if (m_handle_views[1] && scene() && m_handle_views[1]->scene() == scene()) - scene()->removeItem(m_handle_views[1]); - - m_handle_views[0] = nullptr; - m_handle_views[1] = nullptr; -} - -//! The move logic for the handles associated to the segments -void LayerElementController::handleViewMoved(HandleElementView* handle_view) -{ - if (handle_view == leftRoughnessHandle()) { - leftHandleMoved(); - } else if (handle_view == rightRoughnessHandle()) { - rightHandleMoved(); - } -} - -//! Update the handles of the segment -void LayerElementController::updateSegmentHandles() const -{ - auto pen = QPen(); - pen.setColor(layerElementItem()->property<QColor>(LayerElementItem::P_HANDLE_PEN_COLOR)); - pen.setWidthF(layerElementItem()->property<double>(LayerElementItem::P_HANDLE_PEN_WIDTH)); - - auto brush = QBrush(Qt::SolidPattern); - brush.setColor(layerElementItem()->property<QColor>(LayerElementItem::P_HANDLE_BRUSH_COLOR)); - - if (m_handle_views[0]) { - m_handle_views.at(0)->setPen(pen); - m_handle_views.at(0)->setBrush(brush); - m_handle_views.at(0)->setRectangle(firstSegmentHandleRect()); - } - if (m_handle_views[1]) { - m_handle_views.at(1)->setPen(pen); - m_handle_views.at(1)->setBrush(brush); - m_handle_views.at(1)->setRectangle(secondSegmentHandleRect()); - } -} - -//! Get the first segment handle rectangle -QRectF LayerElementController::firstSegmentHandleRect() const -{ - double pos = layerElementItem()->property<double>(LayerElementItem::P_X_POS); - double radius = layerElementItem()->property<double>(LayerElementItem::P_HANDLE_RADIUS); - - double above_height = 0; - if (layerAbove()) { - above_height = - layerAbove()->layerElementItem()->property<double>(LayerElementItem::P_HEIGHT); - } - - return QRectF(pos - radius, above_height - radius, 2 * radius, 2 * radius); -} - -//! Get the second segment handle rectangle -QRectF LayerElementController::secondSegmentHandleRect() const -{ - double pos = layerElementItem()->property<double>(LayerElementItem::P_X_POS); - double height = layerElementItem()->property<double>(LayerElementItem::P_HEIGHT); - double radius = layerElementItem()->property<double>(LayerElementItem::P_HANDLE_RADIUS); - return QRectF(pos - radius, height - radius, 2 * radius, 2 * radius); -} - -//! Put the segment handles on the secene -void LayerElementController::putSegmentHandlesOnScene() const -{ - if (!scene()) - return; - for (auto handle_view : m_handle_views) { - if (handle_view) - scene()->addItem(handle_view); - } -} - -//! Remove the segment handles on the scene -void LayerElementController::removeSegmentHandlesFromScene() const -{ - if (!scene()) - return; - for (auto handle_view : m_handle_views) { - if (handle_view && handle_view->scene() == scene()) - scene()->removeItem(handle_view); - } -} - -//! Set the roughness element view -void LayerElementController::setRoughness(RoughnessElementView* roughness_view) -{ - p_roughness_view = roughness_view; - updateRoughness(); - - if (scene()) { - scene()->addItem(p_roughness_view); - } -} - -//! Set the roughness handle element views -void LayerElementController::setRoughnessHandles(HandleElementView* first_handle_view, - HandleElementView* second_handle_view) -{ - m_rough_handles_views[0] = first_handle_view; - m_rough_handles_views[1] = second_handle_view; - m_rough_handles_views[0]->setFlag(QGraphicsItem::ItemIsMovable); - m_rough_handles_views[1]->setFlag(QGraphicsItem::ItemIsMovable); - m_rough_handles_views[0]->setLayerElementController(this); - m_rough_handles_views[1]->setLayerElementController(this); - updateRoughness(); - - if (scene()) { - scene()->addItem(m_rough_handles_views[0]); - scene()->addItem(m_rough_handles_views[1]); - } -} - -//! Return the roughness element view -RoughnessElementView* LayerElementController::roughness() const -{ - return p_roughness_view; -} - -//! Return the left roughness handle element view -HandleElementView* LayerElementController::leftRoughnessHandle() const -{ - return m_rough_handles_views[0]; -} - -//! Return the right roughness handle element view -HandleElementView* LayerElementController::rightRoughnessHandle() const -{ - return m_rough_handles_views[1]; -} - -//! Remove the roughness view element pointer -void LayerElementController::unsetRoughness() -{ - if (p_roughness_view && scene() && p_roughness_view->scene() == scene()) - scene()->removeItem(p_roughness_view); - p_roughness_view = nullptr; -} - -//! Remove the handle pointers -void LayerElementController::unsetRoughnessHandles() -{ - if (m_rough_handles_views[0] && scene() && m_rough_handles_views[0]->scene() == scene()) - scene()->removeItem(m_rough_handles_views[0]); - if (m_rough_handles_views[1] && scene() && m_rough_handles_views[1]->scene() == scene()) - scene()->removeItem(m_rough_handles_views[1]); - - m_rough_handles_views[0] = nullptr; - m_rough_handles_views[1] = nullptr; -} - -//! Update the whole roughness drawing -void LayerElementController::updateRoughness() const -{ - // Test the roughness - double roughness = layerElementItem()->property<double>(LayerElementItem::P_ROUGHNESS); - // double width = layerElementItem()->property<double>(LayerElementItem::P_WIDTH); - setRoughnessInLimits(roughness, false); - - // Perform the painting - auto pen = QPen(); - auto brush = QBrush(); - - // Take care of the rounghnessview - pen.setStyle(Qt::PenStyle::DashLine); - pen.setColor(layerElementItem()->property<QColor>(LayerElementItem::P_ROUGHNESS_PEN_COLOR)); - pen.setWidthF(layerElementItem()->property<double>(LayerElementItem::P_ROUGHNESS_PEN_WIDTH)); - brush.setColor(layerElementItem()->property<QColor>(LayerElementItem::P_ROUGHNESS_BRUSH_COLOR)); - if (p_roughness_view) { - p_roughness_view->setPen(pen); - p_roughness_view->setBrush(brush); - p_roughness_view->setLeftPath(leftRoughnessPath()); - p_roughness_view->setRightPath(rightRoughnessPath()); - } - - // Take care of the handles - pen.setStyle(Qt::PenStyle::SolidLine); - pen.setColor(layerElementItem()->property<QColor>(LayerElementItem::P_R_HANDLE_PEN_COLOR)); - pen.setWidthF(layerElementItem()->property<double>(LayerElementItem::P_R_HANDLE_PEN_WIDTH)); - brush.setColor(layerElementItem()->property<QColor>(LayerElementItem::P_R_HANDLE_BRUSH_COLOR)); - brush.setStyle(Qt::SolidPattern); - - if (m_rough_handles_views[0]) { - m_rough_handles_views.at(0)->setPen(pen); - m_rough_handles_views.at(0)->setBrush(brush); - m_rough_handles_views.at(0)->setRectangle(leftRoughnessHandleRect()); - } - if (m_rough_handles_views[1]) { - m_rough_handles_views.at(1)->setPen(pen); - m_rough_handles_views.at(1)->setBrush(brush); - m_rough_handles_views.at(1)->setRectangle(rightRoughnessHandleRect()); - } -} - -//! get the left painter path for the roughness view -QPainterPath LayerElementController::leftRoughnessPath() const -{ - double pos = layerElementItem()->property<double>(LayerElementItem::P_X_POS); - double height = layerElementItem()->property<double>(LayerElementItem::P_HEIGHT); - double roughness = layerElementItem()->property<double>(LayerElementItem::P_ROUGHNESS); - - auto path = QPainterPath(); - - auto layer_above = layerAbove(); - if (!layer_above) { - path.moveTo(pos, 0); - path.lineTo(pos - roughness, 0); - } else { - path.moveTo(pos - roughness, - layer_above->layerElementItem()->property<double>(LayerElementItem::P_HEIGHT)); - } - path.lineTo(pos - roughness, height); - path.lineTo(pos, height); - - return path; -} - -//! get the right painter path for the roughness view -QPainterPath LayerElementController::rightRoughnessPath() const -{ - double pos = layerElementItem()->property<double>(LayerElementItem::P_X_POS); - double height = layerElementItem()->property<double>(LayerElementItem::P_HEIGHT); - double roughness = layerElementItem()->property<double>(LayerElementItem::P_ROUGHNESS); - - auto path = QPainterPath(); - - auto layer_above = layerAbove(); - if (!layer_above) { - path.moveTo(pos, 0); - path.lineTo(pos + roughness, 0); - } else { - path.moveTo(pos, - layer_above->layerElementItem()->property<double>(LayerElementItem::P_HEIGHT)); - path.lineTo(pos + roughness, - layer_above->layerElementItem()->property<double>(LayerElementItem::P_HEIGHT)); - } - path.lineTo(pos + roughness, height); - - return path; -} - -//! get the rectangle for the left roughness handles -QRectF LayerElementController::leftRoughnessHandleRect() const -{ - double pos_x = layerElementItem()->property<double>(LayerElementItem::P_X_POS); - double height = layerElementItem()->property<double>(LayerElementItem::P_HEIGHT); - double radius = layerElementItem()->property<double>(LayerElementItem::P_R_HANDLE_RADIUS); - double roughness = layerElementItem()->property<double>(LayerElementItem::P_ROUGHNESS); - - auto layer_above = layerAbove(); - double lower_height = 0; - if (layer_above) { - lower_height = - layer_above->layerElementItem()->property<double>(LayerElementItem::P_HEIGHT); - } - double pos_y = (lower_height - height) / 2 + height; - - return QRectF(pos_x - roughness - radius, pos_y - radius, 2 * radius, 2 * radius); -} - -//! get the rectangle for the right roughness handles -QRectF LayerElementController::rightRoughnessHandleRect() const -{ - double pos_x = layerElementItem()->property<double>(LayerElementItem::P_X_POS); - double height = layerElementItem()->property<double>(LayerElementItem::P_HEIGHT); - double radius = layerElementItem()->property<double>(LayerElementItem::P_R_HANDLE_RADIUS); - double roughness = layerElementItem()->property<double>(LayerElementItem::P_ROUGHNESS); - - auto layer_above = layerAbove(); - double lower_height = 0; - if (layer_above) { - lower_height = - layer_above->layerElementItem()->property<double>(LayerElementItem::P_HEIGHT); - } - double pos_y = (lower_height - height) / 2 + height; - - return QRectF(pos_x + roughness - radius, pos_y - radius, 2 * radius, 2 * radius); -} - -//! Put the roughnes view on the scene -void LayerElementController::putRoughnessOnScene() const -{ - if (!scene()) - return; - if (p_roughness_view) - scene()->addItem(p_roughness_view); -} - -//! Put the roughness handles on the scene -void LayerElementController::putRoughnessHandlesOnScene() const -{ - if (!scene()) - return; - for (auto handle_roughness_view : m_rough_handles_views) { - if (handle_roughness_view) - scene()->addItem(handle_roughness_view); - } -} - -//! Remove the roughness view item from the scene -void LayerElementController::removeRoughnessFromScene() const -{ - if (!scene()) - return; - if (p_roughness_view && p_roughness_view->scene() == scene()) - scene()->removeItem(p_roughness_view); -} - -//! Remove the roughness handles from the sene -void LayerElementController::removeRoughnessHandlesFromScene() const -{ - if (!scene()) - return; - for (auto handle_roughness_view : m_rough_handles_views) { - if (handle_roughness_view && handle_roughness_view->scene() == scene()) - scene()->removeItem(handle_roughness_view); - } -} - -//! Handle the position variation of the left handle -void LayerElementController::leftHandleMoved() const -{ - double pos = layerElementItem()->property<double>(LayerElementItem::P_X_POS); - double roughness = pos - leftRoughnessHandle()->getLastPos().x(); - setRoughnessInLimits(roughness); -} - -//! Handle the position variation of the right handle -void LayerElementController::rightHandleMoved() const -{ - double pos = layerElementItem()->property<double>(LayerElementItem::P_X_POS); - double roughness = rightRoughnessHandle()->getLastPos().x() - pos; - setRoughnessInLimits(roughness); -} - -//! Handle the position variation of the right handle -void LayerElementController::setRoughnessInLimits(double roughness, bool active) const -{ - if (roughness < 0) { - layerElementItem()->setProperty(LayerElementItem::P_ROUGHNESS, 0.); - return; - } - - double width = layerElementItem()->property<double>(LayerElementItem::P_WIDTH); - if (width == 0) - width = 1e6; - - auto layer_above = layerAbove(); - if (layer_above) { - double second_width = - layer_above->layerElementItem()->property<double>(LayerElementItem::P_WIDTH); - if (second_width == 0) - second_width = 1e6; - - if (second_width < width) - width = second_width; - } - - if (roughness > width / 2.) { - layerElementItem()->setProperty(LayerElementItem::P_ROUGHNESS, width / 2.); - return; - } - - if (active) - layerElementItem()->setProperty(LayerElementItem::P_ROUGHNESS, roughness); -} - -} // namespace gui2 diff --git a/gui2/sldeditor/layerelementcontroller.h b/gui2/sldeditor/layerelementcontroller.h deleted file mode 100644 index 37febdf5ed89368129b4a4d045acf829aa383eba..0000000000000000000000000000000000000000 --- a/gui2/sldeditor/layerelementcontroller.h +++ /dev/null @@ -1,160 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/sldeditor/layerelementcontroller.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_SLDEDITOR_LAYERELEMENTCONTROLLER_H -#define BORNAGAIN_GUI2_SLDEDITOR_LAYERELEMENTCONTROLLER_H - -#include "darefl_export.h" -#include "mvvm/plotting/sceneadapterinterface.h" -#include <QObject> -#include <QPainterPath> -#include <vector> - -namespace gui2 { - -// The mvvm item associated to this layer -class LayerElementItem; -// The graphics scene to put the QGraphicsViewItem on -class GraphicsScene; -// The handle QGraphicsViewItem -class HandleElementView; -// The segment QGraphicsViewItem -class SegmentElementView; -// The roughness QGraphicsViewItem -class RoughnessElementView; - -//! Manages the whole appearance of a layer on the graphicsscene -class DAREFLCORE_EXPORT LayerElementController : public QObject { - Q_OBJECT - -public: - LayerElementController(LayerElementItem* layer_view_item); - LayerElementItem* layerElementItem() const; - void autoPopulate(); - void deleteViewItems(); - void connectToModel() const; - void disconnectFormModel() const; - - // ################################################################################## - // Scene management related - void setScene(GraphicsScene* scene); - GraphicsScene* scene() const; - void unsetScene(); - - // ################################################################################## - // Sample id management related - void setSampleItemId(std::string indentifier); - std::string sampleItemId() const; - void unsetSampleItemId(); - - // ################################################################################## - // Inter layer logic related - void setLayerAbove(LayerElementController* layer_view_controller); - void setLayerBelow(LayerElementController* layer_view_controller); - LayerElementController* layerAbove() const; - LayerElementController* layerBelow() const; - void unsetLayerAbove(bool silent = true); - void unsetLayerBelow(bool silent = true); - - // ################################################################################## - // Segment related public methods - void setSideSegment(SegmentElementView* segment_view); - void setTopSegment(SegmentElementView* segment_view); - SegmentElementView* sideSegment() const; - SegmentElementView* topSegment() const; - void unsetSideSegment(); - void unsetTopSegment(); - void segmentViewMoved(SegmentElementView* segment_view); - - // ################################################################################## - // Handle related public methods - void setSegmentHandles(HandleElementView* first_handle, HandleElementView* secondHandle); - HandleElementView* firstSegmentHandle() const; - HandleElementView* secondSegmentHandle() const; - void unsetSegmentHandles(); - void handleViewMoved(HandleElementView* handle_view); - - // ################################################################################## - // Roughness related - void setRoughness(RoughnessElementView* roughness_view); - void setRoughnessHandles(HandleElementView* first_handle_view, - HandleElementView* second_handle_view); - RoughnessElementView* roughness() const; - HandleElementView* leftRoughnessHandle() const; - HandleElementView* rightRoughnessHandle() const; - void unsetRoughness(); - void unsetRoughnessHandles(); - void updateRoughness() const; - -signals: - void heightChanged(std::string id, double value) const; - void widthChanged(std::string id, double value) const; - void roughnessChanged(std::string id, double value) const; - -private: - ModelView::SceneAdapterInterface* sceneAdapter() const; - -protected: - // ################################################################################## - // Segment related protected methods - void updateSideSegment() const; - void updateTopSegment() const; - QRectF sideSegmentRect() const; - QRectF topSegmentRect() const; - void putSegementsOnScene() const; - void removeSegmentsFromScene() const; - - void sideSegmentMoved() const; - void topSegmentMoved() const; - - // ################################################################################## - // Handle related protected methods - void updateSegmentHandles() const; - QRectF firstSegmentHandleRect() const; - QRectF secondSegmentHandleRect() const; - void putSegmentHandlesOnScene() const; - void removeSegmentHandlesFromScene() const; - - // ################################################################################## - // Roughness related protected methods - QPainterPath leftRoughnessPath() const; - QPainterPath rightRoughnessPath() const; - QRectF leftRoughnessHandleRect() const; - QRectF rightRoughnessHandleRect() const; - void putRoughnessOnScene() const; - void putRoughnessHandlesOnScene() const; - void removeRoughnessFromScene() const; - void removeRoughnessHandlesFromScene() const; - void setRoughnessInLimits(double roughness, bool active = true) const; - - void leftHandleMoved() const; - void rightHandleMoved() const; - -private: - LayerElementItem* p_model_item; - GraphicsScene* p_scene = nullptr; - std::string m_sample_item_id; - - std::vector<SegmentElementView*> m_segment_views = {nullptr, nullptr}; - std::vector<HandleElementView*> m_handle_views = {nullptr, nullptr}; - std::vector<HandleElementView*> m_rough_handles_views = {nullptr, nullptr}; - RoughnessElementView* p_roughness_view = nullptr; - - LayerElementController* p_controller_above = nullptr; - LayerElementController* p_controller_below = nullptr; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_SLDEDITOR_LAYERELEMENTCONTROLLER_H diff --git a/gui2/sldeditor/layerelementitem.cpp b/gui2/sldeditor/layerelementitem.cpp deleted file mode 100644 index 98ff179d33c37b0477e904b426445fa199ce5469..0000000000000000000000000000000000000000 --- a/gui2/sldeditor/layerelementitem.cpp +++ /dev/null @@ -1,57 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/sldeditor/layerelementitem.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/sldeditor/layerelementitem.h" -#include "mvvm/model/externalproperty.h" -#include "mvvm/model/itemcatalogue.h" -#include "mvvm/utils/numericutils.h" -#include "mvvm/utils/reallimits.h" - -namespace gui2 { - -LayerElementItem::LayerElementItem() : ModelView::CompoundItem("LayerElement") -{ - addProperty(P_X_POS, 0.)->setDisplayName("Position"); - addProperty(P_WIDTH, 10.)->setDisplayName("Width"); - addProperty(P_HEIGHT, 10.)->setDisplayName("Height"); - addProperty(P_ROUGHNESS, 5.)->setDisplayName("Roughness"); - - addProperty(P_SIDE_THICKNESS, 5.)->setDisplayName("Side segment thickness"); - addProperty(P_SIDE_BRUSH_COLOR, QColor("black"))->setDisplayName("Side segment color"); - addProperty(P_SIDE_PEN_WIDTH, 2.)->setDisplayName("Side segment pen width"); - addProperty(P_SIDE_PEN_COLOR, QColor("black"))->setDisplayName("Side segment pen color"); - - addProperty(P_TOP_THICKNESS, 5.)->setDisplayName("Top segment thickness"); - addProperty(P_TOP_BRUSH_COLOR, QColor("black"))->setDisplayName("Top segment color"); - addProperty(P_TOP_PEN_WIDTH, 2.)->setDisplayName("Top segment pen width"); - addProperty(P_TOP_PEN_COLOR, QColor("black"))->setDisplayName("Top segment pen color"); - - addProperty(P_HANDLE_RADIUS, 5.)->setDisplayName("Handle radius"); - addProperty(P_HANDLE_BRUSH_COLOR, QColor("black"))->setDisplayName("Handle color"); - addProperty(P_HANDLE_PEN_WIDTH, 2.)->setDisplayName("Handle pen width"); - addProperty(P_HANDLE_PEN_COLOR, QColor("black"))->setDisplayName("Handle pen color"); - - addProperty(P_R_HANDLE_RADIUS, 4.)->setDisplayName("Roughness handle radius"); - addProperty(P_R_HANDLE_BRUSH_COLOR, QColor("black"))->setDisplayName("Roughness handle color"); - addProperty(P_R_HANDLE_PEN_WIDTH, 2.)->setDisplayName("Roughness handle pen width"); - addProperty(P_R_HANDLE_PEN_COLOR, QColor("black")) - ->setDisplayName("Roughness handle pen color"); - - addProperty(P_ROUGHNESS_BRUSH_COLOR, QColor("black"))->setDisplayName("Roughness handle color"); - addProperty(P_ROUGHNESS_PEN_WIDTH, 2.)->setDisplayName("Roughness handle pen width"); - addProperty(P_ROUGHNESS_PEN_COLOR, QColor("black")) - ->setDisplayName("Roughness handle pen color"); -} - -} // namespace gui2 diff --git a/gui2/sldeditor/layerelementitem.h b/gui2/sldeditor/layerelementitem.h deleted file mode 100644 index 60acf311b9e25087a67adfad4459b4b9a0ad45fa..0000000000000000000000000000000000000000 --- a/gui2/sldeditor/layerelementitem.h +++ /dev/null @@ -1,61 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/sldeditor/layerelementitem.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_SLDEDITOR_LAYERELEMENTITEM_H -#define BORNAGAIN_GUI2_SLDEDITOR_LAYERELEMENTITEM_H - -#include "darefl_export.h" -#include "mvvm/model/compounditem.h" -#include "mvvm/model/sessionmodel.h" - -namespace gui2 { - -//! The mvvm session item associated to a layer -class DAREFLCORE_EXPORT LayerElementItem : public ModelView::CompoundItem { -public: - static inline const std::string P_X_POS = "P_X_POS"; - static inline const std::string P_WIDTH = "P_WIDTH"; - static inline const std::string P_HEIGHT = "P_HEIGHT"; - static inline const std::string P_ROUGHNESS = "P_ROUGHNESS"; - - static inline const std::string P_SIDE_THICKNESS = "P_SIDE_THICKNESS"; - static inline const std::string P_SIDE_BRUSH_COLOR = "P_SIDE_BRUSH_COLOR"; - static inline const std::string P_SIDE_PEN_WIDTH = "P_SIDE_PEN_WIDTH"; - static inline const std::string P_SIDE_PEN_COLOR = "P_SIDE_PEN_COLOR"; - - static inline const std::string P_TOP_THICKNESS = "P_TOP_THICKNESS"; - static inline const std::string P_TOP_BRUSH_COLOR = "P_TOP_BRUSH_COLOR"; - static inline const std::string P_TOP_PEN_WIDTH = "P_TOP_PEN_WIDTH"; - static inline const std::string P_TOP_PEN_COLOR = "P_TOP_PEN_COLOR"; - - static inline const std::string P_HANDLE_RADIUS = "P_HANDLE_RADIUS"; - static inline const std::string P_HANDLE_BRUSH_COLOR = "P_HANDLE_BRUSH_COLOR"; - static inline const std::string P_HANDLE_PEN_WIDTH = "P_HANDLE_PEN_WIDTH"; - static inline const std::string P_HANDLE_PEN_COLOR = "P_HANDLE_PEN_COLOR"; - - static inline const std::string P_ROUGHNESS_BRUSH_COLOR = "P_ROUGHNESS_BRUSH_COLOR"; - static inline const std::string P_ROUGHNESS_PEN_WIDTH = "P_ROUGHNESS_PEN_WIDTH"; - static inline const std::string P_ROUGHNESS_PEN_COLOR = "P_ROUGHNESS_PEN_COLOR"; - - static inline const std::string P_R_HANDLE_RADIUS = "P_R_HANDLE_RADIUS"; - static inline const std::string P_R_HANDLE_BRUSH_COLOR = "P_R_HANDLE_BRUSH_COLOR"; - static inline const std::string P_R_HANDLE_PEN_WIDTH = "P_R_HANDLE_PEN_WIDTH"; - static inline const std::string P_R_HANDLE_PEN_COLOR = "P_R_HANDLE_PEN_COLOR"; - - LayerElementItem(); -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_SLDEDITOR_LAYERELEMENTITEM_H diff --git a/gui2/sldeditor/roughnesselementview.cpp b/gui2/sldeditor/roughnesselementview.cpp deleted file mode 100644 index 83fbc3f322e7ca808540afedbef242b8102fd871..0000000000000000000000000000000000000000 --- a/gui2/sldeditor/roughnesselementview.cpp +++ /dev/null @@ -1,88 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/sldeditor/roughnesselementview.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/sldeditor/roughnesselementview.h" -#include "gui2/sldeditor/layerelementcontroller.h" - -#include <QPainter> -#include <QStyleOption> - -namespace gui2 { - -//! The constructor -RoughnessElementView::RoughnessElementView() - : ElementView() - , m_left_path(QPainterPath()) - , m_right_path(QPainterPath()) - , m_brush(QBrush()) - , m_pen(QPen()) -{ - setZValue(0); -} - -//! The overriden paint method -void RoughnessElementView::paint(QPainter* painter, const QStyleOptionGraphicsItem*, QWidget*) -{ - painter->setClipRect(sceneAdapter()->viewportRectangle()); - painter->setPen(m_pen); - painter->setBrush(m_brush); - painter->drawPath(displayPath(m_left_path)); - painter->drawPath(displayPath(m_right_path)); -} - -//! The shape -QPainterPath RoughnessElementView::shape() const -{ - QPainterPath path; - path.addPath(displayPath(m_left_path)); - path.addPath(displayPath(m_right_path)); - return path; -} - -//! The bounding rectangle of the handle -QRectF RoughnessElementView::boundingRect() const -{ - QPainterPath path; - path.addPath(displayPath(m_left_path)); - path.addPath(displayPath(m_right_path)); - return path.boundingRect(); -} - -//! Set the draw path for the left side -void RoughnessElementView::setLeftPath(QPainterPath left_path) -{ - prepareGeometryChange(); - m_left_path = left_path; -} - -//! Set the draw path for the right side -void RoughnessElementView::setRightPath(QPainterPath right_path) -{ - prepareGeometryChange(); - m_right_path = right_path; -} - -//! Set the brush -void RoughnessElementView::setBrush(QBrush brush) -{ - m_brush = brush; -} - -//! Set the pen -void RoughnessElementView::setPen(QPen pen) -{ - m_pen = pen; -} - -} // namespace gui2 diff --git a/gui2/sldeditor/roughnesselementview.h b/gui2/sldeditor/roughnesselementview.h deleted file mode 100644 index 5773450a94f970d3845e272b898d5fafaaeb4575..0000000000000000000000000000000000000000 --- a/gui2/sldeditor/roughnesselementview.h +++ /dev/null @@ -1,49 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/sldeditor/roughnesselementview.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_SLDEDITOR_ROUGHNESSELEMENTVIEW_H -#define BORNAGAIN_GUI2_SLDEDITOR_ROUGHNESSELEMENTVIEW_H - -#include "darefl_export.h" -#include "gui2/sldeditor/elementview.h" - -#include <QBrush> -#include <QPainterPath> -#include <QPen> - -namespace gui2 { - -//! The roughness QGraphicsViewItem -class DAREFLCORE_EXPORT RoughnessElementView : public ElementView { -public: - RoughnessElementView(); - QRectF boundingRect() const override; - QPainterPath shape() const override; - void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) override; - - void setLeftPath(QPainterPath left_path); - void setRightPath(QPainterPath right_path); - void setBrush(QBrush brush); - void setPen(QPen pen); - -protected: - QPainterPath m_left_path; - QPainterPath m_right_path; - QBrush m_brush; - QPen m_pen; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_SLDEDITOR_ROUGHNESSELEMENTVIEW_H diff --git a/gui2/sldeditor/segmentelementview.cpp b/gui2/sldeditor/segmentelementview.cpp deleted file mode 100644 index c9e38de9752be4ce226f2f3472ec31647468354d..0000000000000000000000000000000000000000 --- a/gui2/sldeditor/segmentelementview.cpp +++ /dev/null @@ -1,97 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/sldeditor/segmentelementview.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/sldeditor/segmentelementview.h" -#include "gui2/sldeditor/layerelementcontroller.h" - -#include <QGraphicsSceneMouseEvent> -#include <QPainter> -#include <QStyleOption> - -namespace gui2 { - -//! The constructor -SegmentElementView::SegmentElementView() - : ElementView() - , m_pos(QPointF(0, 0)) - , m_rectangle(QRectF(0, 0, 0, 0)) - , m_brush(QBrush()) - , m_pen(QPen()) -{ - setFlag(QGraphicsItem::ItemIsMovable); - setZValue(1); -} - -//! The overriden paint method -void SegmentElementView::paint(QPainter* painter, const QStyleOptionGraphicsItem*, QWidget*) -{ - painter->setClipRect(sceneAdapter()->viewportRectangle()); - painter->setPen(m_pen); - painter->setBrush(m_brush); - painter->drawRect(displayRect(m_rectangle)); -} - -//! The shape -QPainterPath SegmentElementView::shape() const -{ - QPainterPath path; - path.addRect(displayRect(m_rectangle)); - return path; -} - -//! The bounding rectangle of the handle -QRectF SegmentElementView::boundingRect() const -{ - return displayRect(m_rectangle); -} - -//! On move save the new position and notify the controller -void SegmentElementView::mouseMoveEvent(QGraphicsSceneMouseEvent* event) -{ - m_pos = scenePos(event->pos()); - p_controller->segmentViewMoved(this); -} - -//! Set the controller to report back the move -void SegmentElementView::setLayerElementController(LayerElementController* controller) -{ - p_controller = controller; -} - -//! Set the draw rectangle -void SegmentElementView::setRectangle(QRectF rectangle) -{ - prepareGeometryChange(); - m_rectangle = rectangle; -} - -//! Set the brush -void SegmentElementView::setBrush(QBrush brush) -{ - m_brush = brush; -} - -//! Set the pen -void SegmentElementView::setPen(QPen pen) -{ - m_pen = pen; -} - -//! Get the last position of the item -QPointF SegmentElementView::getLastPos() const -{ - return m_pos; -} - -} // namespace gui2 diff --git a/gui2/sldeditor/segmentelementview.h b/gui2/sldeditor/segmentelementview.h deleted file mode 100644 index 68011748a36b66bf8dd994c921ed143ff21cf708..0000000000000000000000000000000000000000 --- a/gui2/sldeditor/segmentelementview.h +++ /dev/null @@ -1,56 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/sldeditor/segmentelementview.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_SLDEDITOR_SEGMENTELEMENTVIEW_H -#define BORNAGAIN_GUI2_SLDEDITOR_SEGMENTELEMENTVIEW_H - -#include "darefl_export.h" -#include "gui2/sldeditor/elementview.h" - -#include <QBrush> -#include <QPen> -#include <QRectF> - -namespace gui2 { - -class LayerElementController; - -//! The segment QGraphicsViewItem on the Graphicsscene -class DAREFLCORE_EXPORT SegmentElementView : public ElementView { -public: - SegmentElementView(); - QRectF boundingRect() const override; - QPainterPath shape() const override; - void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) override; - - void setLayerElementController(LayerElementController* controller); - void setRectangle(QRectF rectangle); - void setBrush(QBrush brush); - void setPen(QPen pen); - QPointF getLastPos() const; - -public: - void mouseMoveEvent(QGraphicsSceneMouseEvent* event) override; - -protected: - LayerElementController* p_controller; - QPointF m_pos; - QRectF m_rectangle; - QBrush m_brush; - QPen m_pen; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_SLDEDITOR_SEGMENTELEMENTVIEW_H diff --git a/gui2/sldeditor/sldeditor.cpp b/gui2/sldeditor/sldeditor.cpp deleted file mode 100644 index d3a01c2dea50fd71cd90753c8041107e3e30a1ea..0000000000000000000000000000000000000000 --- a/gui2/sldeditor/sldeditor.cpp +++ /dev/null @@ -1,69 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/sldeditor/sldeditor.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/sldeditor/sldeditor.h" -#include "gui2/mainwindow/styleutils.h" -#include "gui2/model/applicationmodels.h" -#include "gui2/sldeditor/graphicsscene.h" -#include "gui2/sldeditor/sldeditoractions.h" -#include "gui2/sldeditor/sldeditortoolbar.h" -#include "gui2/sldeditor/sldviewwidget.h" -#include "mvvm/plotting/graphcanvas.h" -#include <QVBoxLayout> - -namespace gui2 { - -//! The constructor -SLDEditor::SLDEditor(QWidget* parent) - : QWidget(parent) - , m_editorActions(new SLDEditorActions(this)) - , m_viewWidget(new SLDViewWidget(this)) - , m_toolBar(new SLDEditorToolBar(m_editorActions)) -{ - setWindowTitle("SLD editor"); - auto layout = new QVBoxLayout; - layout->addWidget(m_toolBar); - layout->addWidget(m_viewWidget); - setLayout(layout); - layout->setContentsMargins(0, 0, 0, 0); - layout->setSpacing(0); - - connect(dynamic_cast<SLDEditorToolBar*>(m_toolBar), &SLDEditorToolBar::resetViewport, [this]() { - GraphicsScene* scene_item = dynamic_cast<GraphicsScene*>(m_viewWidget->scene()); - if (!scene_item) - return; - scene_item->graphCanvas()->setViewportToContent(); - }); -} - -//! The destructor -SLDEditor::~SLDEditor() = default; - -void SLDEditor::setModels(ApplicationModels* models) -{ - m_viewWidget->setModels(models); - m_editorActions->setModel(models->sldViewModel()); -} - -QSize SLDEditor::sizeHint() const -{ - return GUI::Utils::Style::DockSizeHint(); -} - -QSize SLDEditor::minimumSizeHint() const -{ - return GUI::Utils::Style::DockMinimumSizeHint(); -} - -} // namespace gui2 diff --git a/gui2/sldeditor/sldeditor.h b/gui2/sldeditor/sldeditor.h deleted file mode 100644 index b320a8dc526462b945c6ea46557596141f447918..0000000000000000000000000000000000000000 --- a/gui2/sldeditor/sldeditor.h +++ /dev/null @@ -1,48 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/sldeditor/sldeditor.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_SLDEDITOR_SLDEDITOR_H -#define BORNAGAIN_GUI2_SLDEDITOR_SLDEDITOR_H - -#include "darefl_export.h" -#include <QWidget> - -namespace gui2 { -class SLDEditorActions; -class SLDEditorToolBar; -class SLDViewWidget; -class ApplicationModels; - -//! The SLD editor QWidget -class DAREFLCORE_EXPORT SLDEditor : public QWidget { - Q_OBJECT - -public: - SLDEditor(QWidget* parent = nullptr); - ~SLDEditor(); - - void setModels(ApplicationModels* models); - - QSize sizeHint() const override; - QSize minimumSizeHint() const override; - -private: - SLDEditorActions* m_editorActions{nullptr}; - SLDViewWidget* m_viewWidget{nullptr}; - SLDEditorToolBar* m_toolBar{nullptr}; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_SLDEDITOR_SLDEDITOR_H diff --git a/gui2/sldeditor/sldeditoractions.cpp b/gui2/sldeditor/sldeditoractions.cpp deleted file mode 100644 index 12d43c119117801ac7f7e46bf4e19907f5007a79..0000000000000000000000000000000000000000 --- a/gui2/sldeditor/sldeditoractions.cpp +++ /dev/null @@ -1,42 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/sldeditor/sldeditoractions.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/sldeditor/sldeditoractions.h" -#include "gui2/sldeditor/layerelementitem.h" -#include "gui2/sldeditor/sldelementmodel.h" -#include "mvvm/model/modelutils.h" -#include "mvvm/viewmodel/viewmodel.h" - -using namespace ModelView; - -namespace gui2 { - -struct SLDEditorActions::SLDEditorActionsImpl { - SLDElementModel* sld_element_model{nullptr}; - SLDEditorActionsImpl() {} -}; - -SLDEditorActions::SLDEditorActions(QObject* parent) - : QObject(parent), p_impl(std::make_unique<SLDEditorActionsImpl>()) -{ -} - -void SLDEditorActions::setModel(SLDElementModel* model) -{ - p_impl->sld_element_model = model; -} - -SLDEditorActions::~SLDEditorActions() = default; - -} // namespace gui2 diff --git a/gui2/sldeditor/sldeditoractions.h b/gui2/sldeditor/sldeditoractions.h deleted file mode 100644 index 3d24f9c24fda5f82ded549f7359d99e3d77e7aa7..0000000000000000000000000000000000000000 --- a/gui2/sldeditor/sldeditoractions.h +++ /dev/null @@ -1,45 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/sldeditor/sldeditoractions.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_SLDEDITOR_SLDEDITORACTIONS_H -#define BORNAGAIN_GUI2_SLDEDITOR_SLDEDITORACTIONS_H - -#include "darefl_export.h" -#include <QObject> -#include <memory> - -namespace gui2 { - -class SLDElementModel; - -//! Handles user actions applied to SLDEditor. -//! Belongs to SLDEditor. - -class DAREFLCORE_EXPORT SLDEditorActions : public QObject { - Q_OBJECT - -public: - SLDEditorActions(QObject* parent = nullptr); - ~SLDEditorActions(); - - void setModel(SLDElementModel* model); - -private: - struct SLDEditorActionsImpl; - std::unique_ptr<SLDEditorActionsImpl> p_impl; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_SLDEDITOR_SLDEDITORACTIONS_H diff --git a/gui2/sldeditor/sldeditortoolbar.cpp b/gui2/sldeditor/sldeditortoolbar.cpp deleted file mode 100644 index c32d0d46ab8c10012a37621b5c3fc1705fc7bb90..0000000000000000000000000000000000000000 --- a/gui2/sldeditor/sldeditortoolbar.cpp +++ /dev/null @@ -1,35 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/sldeditor/sldeditortoolbar.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/sldeditor/sldeditortoolbar.h" -#include "gui2/mainwindow/styleutils.h" -#include "gui2/resources/resources.h" -#include "gui2/sldeditor/sldeditoractions.h" -#include <QAction> -#include <QToolButton> - -namespace gui2 { - -SLDEditorToolBar::SLDEditorToolBar(SLDEditorActions*, QWidget* parent) : QToolBar(parent) -{ - GUI::Utils::Style::SetToolBarStyleTextBesides(this); - - auto reset_view = new QToolButton; - reset_view->setToolTip("Set axes to default range."); - reset_view->setIcon(QIcon(":/icons/aspect-ratio.svg")); - addWidget(reset_view); - connect(reset_view, &QToolButton::clicked, [this]() { resetViewport(); }); -} - -} // namespace gui2 diff --git a/gui2/sldeditor/sldeditortoolbar.h b/gui2/sldeditor/sldeditortoolbar.h deleted file mode 100644 index a740a9ac428165438870ef908209728503340d4b..0000000000000000000000000000000000000000 --- a/gui2/sldeditor/sldeditortoolbar.h +++ /dev/null @@ -1,40 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/sldeditor/sldeditortoolbar.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_SLDEDITOR_SLDEDITORTOOLBAR_H -#define BORNAGAIN_GUI2_SLDEDITOR_SLDEDITORTOOLBAR_H - -#include "darefl_export.h" -#include <QToolBar> - -namespace gui2 { - -class SLDEditorActions; - -//! Material editor toolbar. - -class DAREFLCORE_EXPORT SLDEditorToolBar : public QToolBar { - Q_OBJECT - -public: - SLDEditorToolBar(SLDEditorActions* actions, QWidget* parent = nullptr); - ~SLDEditorToolBar() = default; - -signals: - void resetViewport(); -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_SLDEDITOR_SLDEDITORTOOLBAR_H diff --git a/gui2/sldeditor/sldelementcontroller.cpp b/gui2/sldeditor/sldelementcontroller.cpp deleted file mode 100644 index 8e5b70be11d5eadba74b7297cad48447de68a5b8..0000000000000000000000000000000000000000 --- a/gui2/sldeditor/sldelementcontroller.cpp +++ /dev/null @@ -1,309 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/sldeditor/sldelementcontroller.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/sldeditor/sldelementcontroller.h" -#include "gui2/model/materialitems.h" -#include "gui2/model/materialmodel.h" -#include "gui2/model/sampleitems.h" -#include "gui2/model/samplemodel.h" -#include "gui2/sldeditor/graphicsscene.h" -#include "gui2/sldeditor/layerelementcontroller.h" -#include "gui2/sldeditor/layerelementitem.h" -#include "gui2/sldeditor/segmentelementview.h" -#include "gui2/sldeditor/sldelementmodel.h" -#include "mvvm/model/compounditem.h" -#include "mvvm/model/externalproperty.h" -#include "mvvm/model/modelutils.h" -#include "mvvm/signals/modelmapper.h" -#include <iostream> - -using namespace ModelView; - -namespace gui2 { - -//! Contructor -SLDElementController::SLDElementController(MaterialModel* material_model, SampleModel* sample_model, - SLDElementModel* sld_model, GraphicsScene* scene_item) - : p_material_model(material_model) - , p_sample_model(sample_model) - , p_sld_model(sld_model) - , p_scene_item(scene_item) -{ - connectSLDElementModel(); - connectLayerModel(); - connectMaterialModel(); - buildSLD(); -} - -SLDElementController::~SLDElementController() -{ - clearScene(); -} - -//! Connect with signals of MaterialModel -void SLDElementController::connectMaterialModel() -{ - auto on_mat_data_change = [this](SessionItem* item, int) { updateToView(item); }; - p_material_model->mapper()->setOnDataChange(on_mat_data_change, this); - - auto on_mat_model_destroyed = [this](SessionModel*) { p_material_model = nullptr; }; - p_material_model->mapper()->setOnModelDestroyed(on_mat_model_destroyed, this); -} - -// FIXME Consider switching to ModelHasChangedController, or ModelListener. -// See quicksimcontroller.h or materialpropertycontroller.h as an example. - -//! Connect with signals of SampleModel -void SLDElementController::connectLayerModel() -{ - auto on_sam_data_change = [this](SessionItem* item, int) { updateToView(item); }; - p_sample_model->mapper()->setOnDataChange(on_sam_data_change, this); - - auto on_sam_item_inserted = [this](SessionItem*, TagRow) { buildSLD(); }; - p_sample_model->mapper()->setOnItemInserted(on_sam_item_inserted, this); - - auto on_sam_item_removed = [this](SessionItem*, TagRow) { buildSLD(); }; - p_sample_model->mapper()->setOnItemRemoved(on_sam_item_removed, this); - - auto on_sam_model_destroyed = [this](SessionModel*) { p_sample_model = nullptr; }; - p_sample_model->mapper()->setOnModelDestroyed(on_sam_model_destroyed, this); -} - -//! Connect with signals of SLDViewModel -void SLDElementController::connectSLDElementModel() -{ - auto on_sld_model_destroyed = [this](SessionModel*) { p_sld_model = nullptr; }; - p_sld_model->mapper()->setOnModelDestroyed(on_sld_model_destroyed, this); -} - -//! Disconnect with signals of MaterialModel -void SLDElementController::disconnectMaterialModel() const -{ - p_material_model->mapper()->unsubscribe(this); -} - -//! Disconnect with signals of SampleModel -void SLDElementController::disconnectLayerModel() const -{ - p_sample_model->mapper()->unsubscribe(this); -} - -//! Disconnect with signals of SLDViewModel -void SLDElementController::disconnectSLDElementModel() const -{ - p_sld_model->mapper()->unsubscribe(this); -} - -//! Set the scene of the current controller to be passed to the LayerElementControllers -void SLDElementController::setScene(GraphicsScene* scene) -{ - p_scene_item = scene; - buildSLD(); -} - -//! Updates all material properties in LayerItems to get new material colors and labels -void SLDElementController::buildSLD() -{ - if (!p_sld_model) - return; - if (!p_sample_model) - return; - if (!p_material_model) - return; - if (!p_scene_item) - return; - - disconnectSLDElementModel(); - clearScene(); - - if (p_sample_model->rootItem()->childrenCount() == 0) - return; - string_vec identifiers = getIdentifierVector(p_sample_model->rootItem()->children().at(0)); - if (identifiers.size() == 0) - return; - - buildLayerControllers(identifiers); - updateToView(); - connectSLDElementModel(); - connectLayerControllers(); -} - -//! Remove all LayerElementControllers and their items from scene and memory -void SLDElementController::clearScene() -{ - if (!p_scene_item) - return; - if (!p_sld_model) - return; - - for (size_t i = 0; i < m_layer_controllers.size(); ++i) { - m_layer_controllers.at(i)->disconnectFormModel(); - m_layer_controllers.at(i)->unsetScene(); - m_layer_controllers.at(i)->deleteViewItems(); - } - m_layer_controllers.clear(); - p_sld_model->clear(); -} - -//! Get the identifiers of all layeritems in the sample model in order of appearance -SLDElementController::string_vec SLDElementController::getIdentifierVector(SessionItem* item) -{ - string_vec output; - - auto children = item->children(); - for (int i = 0; i < item->childrenCount(); ++i) { - if (dynamic_cast<MultiLayerItem*>(children.at(i))) { - auto child = dynamic_cast<MultiLayerItem*>(children.at(i)); - for (int j = 0; j < child->property<int>(MultiLayerItem::P_NREPETITIONS); ++j) { - auto child_output = getIdentifierVector(child); - output.insert(output.end(), child_output.begin(), child_output.end()); - } - } else if (dynamic_cast<LayerItem*>(children.at(i))) { - auto child = dynamic_cast<LayerItem*>(children.at(i)); - output.push_back(child->identifier()); - } - } - return output; -} - -//! Build and set up the layer controllers -void SLDElementController::buildLayerControllers(string_vec& identifiers) -{ - if (!p_scene_item) - return; - if (!p_sld_model) - return; - - for (auto& identifier : identifiers) { - auto layer_element_item = p_sld_model->addLayer(); - auto layer_element_controller = - std::make_unique<LayerElementController>(layer_element_item); - layer_element_controller->autoPopulate(); - layer_element_controller->setScene(p_scene_item); - layer_element_controller->connectToModel(); - layer_element_controller->setSampleItemId(identifier); - m_layer_controllers.push_back(std::move(layer_element_controller)); - } - - for (size_t i = 0; i < m_layer_controllers.size() - 1; ++i) { - m_layer_controllers.at(i)->setLayerBelow(m_layer_controllers.at(i + 1).get()); - } - - if (m_layer_controllers.size() > 0) { - m_layer_controllers.at(0)->topSegment()->stretchRight(true); - m_layer_controllers.at(0)->topSegment()->setFlag(QGraphicsItem::ItemIsMovable, false); - } - if (m_layer_controllers.size() > 1) { - m_layer_controllers.at(1)->sideSegment()->setFlag(QGraphicsItem::ItemIsMovable, false); - m_layer_controllers.at(m_layer_controllers.size() - 1)->topSegment()->stretchLeft(true); - } -} - -//! Connect the layer controllers -void SLDElementController::connectLayerControllers() -{ - for (const auto& layer_controller : m_layer_controllers) { - QObject::connect(layer_controller.get(), &LayerElementController::heightChanged, this, - &SLDElementController::updateSLDFromView); - QObject::connect(layer_controller.get(), &LayerElementController::widthChanged, this, - &SLDElementController::updateThicknessFromView); - QObject::connect(layer_controller.get(), &LayerElementController::roughnessChanged, this, - &SLDElementController::updateRoughnessFromView); - } -} - -//! Disconnect the layer controllers -void SLDElementController::disconnectLayerControllers() -{ - for (const auto& layer_controller : m_layer_controllers) { - QObject::disconnect(layer_controller.get(), &LayerElementController::heightChanged, this, - &SLDElementController::updateSLDFromView); - QObject::disconnect(layer_controller.get(), &LayerElementController::widthChanged, this, - &SLDElementController::updateThicknessFromView); - QObject::disconnect(layer_controller.get(), &LayerElementController::roughnessChanged, this, - &SLDElementController::updateRoughnessFromView); - } -} - -//! Update the view items with the changes in the material or layer models -void SLDElementController::updateToView(SessionItem* item) -{ - if (item && dynamic_cast<MultiLayerItem*>(item->parent())) { - buildSLD(); - return; - } - - for (const auto& layer_controller : m_layer_controllers) { - auto layer_item = - dynamic_cast<LayerItem*>(p_sample_model->findItem(layer_controller->sampleItemId())); - if (!layer_item) { - buildSLD(); - return; - } - auto roughness_item = layer_item->item<RoughnessItem>(LayerItem::P_ROUGHNESS); - auto material_item = dynamic_cast<SLDMaterialItem*>(p_material_model->findItem( - layer_item->property<ExternalProperty>(LayerItem::P_MATERIAL).identifier())); - - layer_controller->layerElementItem()->setProperty( - LayerElementItem::P_ROUGHNESS, - roughness_item->property<double>(RoughnessItem::P_SIGMA)); - layer_controller->layerElementItem()->setProperty( - LayerElementItem::P_WIDTH, layer_item->property<double>(LayerItem::P_THICKNESS)); - - if (material_item) { - layer_controller->layerElementItem()->setProperty( - LayerElementItem::P_HEIGHT, - material_item->property<double>(SLDMaterialItem::P_SLD_REAL)); - layer_controller->layerElementItem()->setProperty( - LayerElementItem::P_TOP_BRUSH_COLOR, - material_item->property<QColor>(SLDMaterialItem::P_COLOR)); - layer_controller->layerElementItem()->setProperty( - LayerElementItem::P_SIDE_BRUSH_COLOR, - material_item->property<QColor>(SLDMaterialItem::P_COLOR)); - } else { - layer_controller->layerElementItem()->setProperty(LayerElementItem::P_HEIGHT, 1e-6); - layer_controller->layerElementItem()->setProperty(LayerElementItem::P_TOP_BRUSH_COLOR, - QColor("red")); - layer_controller->layerElementItem()->setProperty(LayerElementItem::P_SIDE_BRUSH_COLOR, - QColor("red")); - } - } -} - -//! Update the material and layer models from the view items -void SLDElementController::updateThicknessFromView(std::string identifier, double value) -{ - auto layer_item = dynamic_cast<LayerItem*>(p_sample_model->findItem(identifier)); - layer_item->setProperty(LayerItem::P_THICKNESS, value); -} - -//! Update the material and layer models from the view items -void SLDElementController::updateSLDFromView(std::string identifier, double value) -{ - auto layer_item = dynamic_cast<LayerItem*>(p_sample_model->findItem(identifier)); - auto material_item = dynamic_cast<SLDMaterialItem*>(p_material_model->findItem( - layer_item->property<ExternalProperty>(LayerItem::P_MATERIAL).identifier())); - if (material_item) - material_item->setProperty(SLDMaterialItem::P_SLD_REAL, value); -} - -//! Update the material and layer models from the view items -void SLDElementController::updateRoughnessFromView(std::string identifier, double value) -{ - auto layer_item = dynamic_cast<LayerItem*>(p_sample_model->findItem(identifier)); - auto roughness_item = layer_item->item<RoughnessItem>(LayerItem::P_ROUGHNESS); - roughness_item->setProperty(RoughnessItem::P_SIGMA, value); -} - -} // namespace gui2 diff --git a/gui2/sldeditor/sldelementcontroller.h b/gui2/sldeditor/sldelementcontroller.h deleted file mode 100644 index 38959bb95bd610a40a65b6ba8d500046a69e96d4..0000000000000000000000000000000000000000 --- a/gui2/sldeditor/sldelementcontroller.h +++ /dev/null @@ -1,75 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/sldeditor/sldelementcontroller.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_SLDEDITOR_SLDELEMENTCONTROLLER_H -#define BORNAGAIN_GUI2_SLDEDITOR_SLDELEMENTCONTROLLER_H - -#include "darefl_export.h" -#include "gui2/sldeditor/layerelementcontroller.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/model/sessionmodel.h" -#include <QObject> -#include <vector> - -namespace gui2 { - -class MaterialModel; -class SampleModel; -class SLDElementModel; -class GraphicsScene; - -//! The controller of the sld layer visual representation -class DAREFLCORE_EXPORT SLDElementController : public QObject { - Q_OBJECT - -public: - using string_vec = std::vector<std::string>; - using layer_ctrl_vec = std::vector<std::unique_ptr<LayerElementController>>; - - SLDElementController(MaterialModel* material_model, SampleModel* sample_model, - SLDElementModel* sld_model, GraphicsScene* scene_item); - ~SLDElementController(); - void setScene(GraphicsScene* scene); - -private: - void connectMaterialModel(); - void connectLayerModel(); - void connectSLDElementModel(); - void disconnectMaterialModel() const; - void disconnectLayerModel() const; - void disconnectSLDElementModel() const; - - void buildSLD(); - void clearScene(); - string_vec getIdentifierVector(ModelView::SessionItem* item); - void buildLayerControllers(string_vec& identifiers); - void connectLayerControllers(); - void disconnectLayerControllers(); - - void updateToView(ModelView::SessionItem* item = nullptr); - void updateThicknessFromView(std::string identifier, double value); - void updateSLDFromView(std::string identifier, double value); - void updateRoughnessFromView(std::string identifier, double value); - -private: - MaterialModel* p_material_model; - SampleModel* p_sample_model; - SLDElementModel* p_sld_model; - GraphicsScene* p_scene_item; - layer_ctrl_vec m_layer_controllers; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_SLDEDITOR_SLDELEMENTCONTROLLER_H diff --git a/gui2/sldeditor/sldelementmodel.cpp b/gui2/sldeditor/sldelementmodel.cpp deleted file mode 100644 index f6f4ec6c031569c0379f72d5c598bd3b8410f6c7..0000000000000000000000000000000000000000 --- a/gui2/sldeditor/sldelementmodel.cpp +++ /dev/null @@ -1,49 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/sldeditor/sldelementmodel.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/sldeditor/sldelementmodel.h" -#include "gui2/sldeditor/layerelementitem.h" - -#include "mvvm/model/externalproperty.h" -#include "mvvm/model/itemcatalogue.h" -#include "mvvm/utils/reallimits.h" - -using namespace ModelView; - -namespace gui2 { - -namespace { -std::unique_ptr<ItemCatalogue> CreateItemCatalogue() -{ - auto result = std::make_unique<ModelView::ItemCatalogue>(); - result->registerItem<LayerElementItem>(); - return result; -} - -} // namespace - -//! Contructor -SLDElementModel::SLDElementModel() : SessionModel("ViewItemsModel") -{ - setItemCatalogue(CreateItemCatalogue()); -} - -//! Add a layer item to the model and return its pointer -LayerElementItem* SLDElementModel::addLayer() -{ - auto layer_element_item = insertItem<LayerElementItem>(); - return layer_element_item; -} - -} // namespace gui2 diff --git a/gui2/sldeditor/sldelementmodel.h b/gui2/sldeditor/sldelementmodel.h deleted file mode 100644 index 69b8e647006b32d057da78a083234627d4a87e77..0000000000000000000000000000000000000000 --- a/gui2/sldeditor/sldelementmodel.h +++ /dev/null @@ -1,41 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/sldeditor/sldelementmodel.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_SLDEDITOR_SLDELEMENTMODEL_H -#define BORNAGAIN_GUI2_SLDEDITOR_SLDELEMENTMODEL_H - -#include "darefl_export.h" -#include "mvvm/model/sessionmodel.h" -#include <vector> - -namespace ModelView { -class ExternalProperty; -} - -namespace gui2 { - -class LayerElementItem; - -//! The model of the sld layer visual representation -class DAREFLCORE_EXPORT SLDElementModel : public ModelView::SessionModel { -public: - SLDElementModel(); - - //! Add a layer item - LayerElementItem* addLayer(); -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_SLDEDITOR_SLDELEMENTMODEL_H diff --git a/gui2/sldeditor/sldviewwidget.cpp b/gui2/sldeditor/sldviewwidget.cpp deleted file mode 100644 index 85776e0d869e8932b05252b0dc176306f059b0db..0000000000000000000000000000000000000000 --- a/gui2/sldeditor/sldviewwidget.cpp +++ /dev/null @@ -1,55 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/sldeditor/sldviewwidget.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/sldeditor/sldviewwidget.h" -#include "gui2/model/applicationmodels.h" -#include "gui2/model/jobmodel.h" -#include "gui2/sldeditor/graphicsscene.h" -#include "gui2/sldeditor/sldelementcontroller.h" -#include <QResizeEvent> - -namespace gui2 { - -//! The constructor -SLDViewWidget::SLDViewWidget(QWidget* parent) : QGraphicsView(parent) -{ - GraphicsScene* scene_item = new GraphicsScene(parent = this); - setScene(scene_item); - setRenderHints(QPainter::Antialiasing); - setDragMode(QGraphicsView::ScrollHandDrag); - setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - setContentsMargins(0, 0, 0, 0); -} - -//! The destructor -SLDViewWidget::~SLDViewWidget() = default; - -void SLDViewWidget::setModels(ApplicationModels* models) -{ - m_sld_controller = std::make_unique<SLDElementController>( - models->materialModel(), models->sampleModel(), models->sldViewModel(), nullptr); - m_sld_controller->setScene(dynamic_cast<GraphicsScene*>(scene())); - dynamic_cast<GraphicsScene*>(scene())->setItem(models->jobModel()->sldViewport()); -} - -//! Resize event management -void SLDViewWidget::resizeEvent(QResizeEvent* event) -{ - QWidget::resizeEvent(event); - GraphicsScene* scene_item = static_cast<GraphicsScene*>(scene()); - scene_item->update_size(event->size()); -} - -} // namespace gui2 diff --git a/gui2/sldeditor/sldviewwidget.h b/gui2/sldeditor/sldviewwidget.h deleted file mode 100644 index 9204299e7dc2f44a22717e59669a455fde56fa64..0000000000000000000000000000000000000000 --- a/gui2/sldeditor/sldviewwidget.h +++ /dev/null @@ -1,46 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/sldeditor/sldviewwidget.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_SLDEDITOR_SLDVIEWWIDGET_H -#define BORNAGAIN_GUI2_SLDEDITOR_SLDVIEWWIDGET_H - -#include "darefl_export.h" -#include <QGraphicsView> -#include <memory> - -namespace gui2 { - -class ApplicationModels; -class SLDElementController; - -//! The segment QGraphicsViewItem on the Graphicsscene -class DAREFLCORE_EXPORT SLDViewWidget : public QGraphicsView { - Q_OBJECT - -public: - SLDViewWidget(QWidget* parent = nullptr); - ~SLDViewWidget(); - - void setModels(ApplicationModels* models); - -protected: - void resizeEvent(QResizeEvent* event); - -private: - std::unique_ptr<SLDElementController> m_sld_controller; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_SLDEDITOR_SLDVIEWWIDGET_H diff --git a/gui2/welcomeview/CMakeLists.txt b/gui2/welcomeview/CMakeLists.txt deleted file mode 100644 index 0ba8b05994b5c40f21c374cc165ac3ae4f8f5c6c..0000000000000000000000000000000000000000 --- a/gui2/welcomeview/CMakeLists.txt +++ /dev/null @@ -1,16 +0,0 @@ -target_sources(${library_name} PRIVATE - openprojectwidget.cpp - openprojectwidget.h - projecthandler.cpp - projecthandler.h - projectpanewidget.cpp - projectpanewidget.h - recentprojectsettings.cpp - recentprojectsettings.h - recentprojectwidget.cpp - recentprojectwidget.h - userinteractor.cpp - userinteractor.h - welcomeview.cpp - welcomeview.h -) diff --git a/gui2/welcomeview/openprojectwidget.cpp b/gui2/welcomeview/openprojectwidget.cpp deleted file mode 100644 index 587c9603b9ff36556656e3655f7be661633cb4a4..0000000000000000000000000000000000000000 --- a/gui2/welcomeview/openprojectwidget.cpp +++ /dev/null @@ -1,100 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/welcomeview/openprojectwidget.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/welcomeview/openprojectwidget.h" -#include "BAVersion.h" -#include "gui2/mainwindow/styleutils.h" -#include "mvvm/widgets/widgetutils.h" -#include <QHBoxLayout> -#include <QLabel> -#include <QPushButton> -#include <QVBoxLayout> - -namespace { -int logo_width() -{ - return ModelView::Utils::SizeOfLetterM().height() * 40; -} - -const QString str_open = "Open"; -const QString str_new = "New"; - -} // namespace - -namespace gui2 { - -OpenProjectWidget::OpenProjectWidget(QWidget* parent) : QWidget(parent) -{ - auto layout = new QVBoxLayout(this); - - QPixmap logo(":/icons/F-letter_1000x.png"); - auto label = new QLabel; - label->setPixmap(logo.scaled(logo_width(), logo_width(), Qt::KeepAspectRatio)); - - layout->addSpacing(ModelView::Utils::SizeOfLetterM().height() * 1.5); - layout->addWidget(label, 0, Qt::AlignHCenter); - layout->addSpacing(ModelView::Utils::SizeOfLetterM().height()); - layout->addLayout(createProjectTitleLayout()); - layout->addSpacing(ModelView::Utils::SizeOfLetterM().height()); - layout->addLayout(createLinkedLabelLayout()); - layout->addStretch(); -} - -QSize OpenProjectWidget::sizeHint() const -{ - return GUI::Utils::Style::DockSizeHint(); -} - -QSize OpenProjectWidget::minimumSizeHint() const -{ - return GUI::Utils::Style::DockMinimumSizeHint(); -} - -QBoxLayout* OpenProjectWidget::createProjectTitleLayout() -{ - auto result = new QHBoxLayout; - QString title = - "BornAgain " + QString::fromStdString(BornAgain::GetVersionNumber()) + ", gui2 preview"; - auto label = new QLabel(title); - ModelView::Utils::ScaleLabelFont(label, 1.25); - - result->addWidget(label, 0, Qt::AlignHCenter); - return result; -} - -QBoxLayout* OpenProjectWidget::createLinkedLabelLayout() -{ - auto result = new QHBoxLayout; - - m_newProjectLabel = new QLabel(ModelView::Utils::ClickableText(str_new)); - m_newProjectLabel->setToolTip("Create new project"); - connect(m_newProjectLabel, &QLabel::linkActivated, [this](auto) { createNewProjectRequest(); }); - ModelView::Utils::ScaleLabelFont(m_newProjectLabel, 1.25); - - m_openProjectLabel = new QLabel(ModelView::Utils::ClickableText(str_open)); - m_openProjectLabel->setToolTip("Open existing project"); - connect(m_openProjectLabel, &QLabel::linkActivated, - [this](auto) { openExistingProjectRequest(); }); - ModelView::Utils::ScaleLabelFont(m_openProjectLabel, 1.15); - - result->addStretch(1); - result->addWidget(m_newProjectLabel); - result->addSpacing(ModelView::Utils::WidthOfLetterM()); - result->addWidget(m_openProjectLabel); - result->addStretch(1); - - return result; -} - -} // namespace gui2 diff --git a/gui2/welcomeview/openprojectwidget.h b/gui2/welcomeview/openprojectwidget.h deleted file mode 100644 index 3afbca8701c7a816ee75fb47d06e75adafcf6e36..0000000000000000000000000000000000000000 --- a/gui2/welcomeview/openprojectwidget.h +++ /dev/null @@ -1,54 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/welcomeview/openprojectwidget.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_WELCOMEVIEW_OPENPROJECTWIDGET_H -#define BORNAGAIN_GUI2_WELCOMEVIEW_OPENPROJECTWIDGET_H - -#include "darefl_export.h" -#include <QWidget> -#include <memory> - -class QBoxLayout; -class QPushButton; -class QLabel; - -namespace gui2 { - -//! Widget with logo, name of the program and buttons to create new project or open existing one. -//! Occupies right part of WelcomeView. - -class DAREFLCORE_EXPORT OpenProjectWidget : public QWidget { - Q_OBJECT - -public: - explicit OpenProjectWidget(QWidget* parent = nullptr); - - QSize sizeHint() const override; - QSize minimumSizeHint() const override; - -signals: - void createNewProjectRequest(); - void openExistingProjectRequest(); - -private: - QBoxLayout* createProjectTitleLayout(); - QBoxLayout* createLinkedLabelLayout(); - - QLabel* m_newProjectLabel{nullptr}; - QLabel* m_openProjectLabel{nullptr}; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_WELCOMEVIEW_OPENPROJECTWIDGET_H diff --git a/gui2/welcomeview/projecthandler.cpp b/gui2/welcomeview/projecthandler.cpp deleted file mode 100644 index 45bea510d140bf2702016ebbee4d209f5932e6ed..0000000000000000000000000000000000000000 --- a/gui2/welcomeview/projecthandler.cpp +++ /dev/null @@ -1,125 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/welcomeview/projecthandler.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/welcomeview/projecthandler.h" -#include "gui2/model/applicationmodels.h" -#include "gui2/welcomeview/recentprojectsettings.h" -#include "gui2/welcomeview/recentprojectwidget.h" -#include "gui2/welcomeview/userinteractor.h" -#include "mvvm/factories/projectmanagerfactory.h" -#include "mvvm/project/project_types.h" -#include "mvvm/widgets/widgetutils.h" -#include <QMainWindow> - -using namespace ModelView; - -namespace gui2 { - -ProjectHandler::ProjectHandler(ApplicationModels* models, QWidget* parent) - : QObject(parent) - , m_recentProjectSettings(std::make_unique<RecentProjectSettings>()) - , m_userInteractor(std::make_unique<UserInteractor>(m_recentProjectSettings.get(), parent)) - , m_models(models) -{ - initProjectManager(); - updateRecentProjectNames(); -} - -ProjectHandler::~ProjectHandler() = default; - -//! Update names (name of the current project, recent project name list, notifies the world). - -void ProjectHandler::updateNames() -{ - updateCurrentProjectName(); - updateRecentProjectNames(); -} - -//! Returns 'true' if current project can be closed. -//! Internally will perform check for unsaved data, and proceed via save/discard/cancel dialog. - -bool ProjectHandler::canCloseProject() const -{ - return m_projectManager->closeCurrentProject(); -} - -void ProjectHandler::onCreateNewProject() -{ - if (m_projectManager->createNewProject()) - updateNames(); -} - -void ProjectHandler::onOpenExistingProject(const QString& dirname) -{ - if (m_projectManager->openExistingProject(dirname.toStdString())) - updateNames(); -} - -void ProjectHandler::onSaveCurrentProject() -{ - if (m_projectManager->saveCurrentProject()) - updateNames(); -} - -void ProjectHandler::onSaveProjectAs() -{ - if (m_projectManager->saveProjectAs()) - updateNames(); -} - -void ProjectHandler::clearRecentProjectsList() -{ - m_recentProjectSettings->clearRecentProjectsList(); - updateNames(); -} - -void ProjectHandler::initProjectManager() -{ - auto modified_callback = [this]() { updateCurrentProjectName(); }; - auto models_callback = [this]() { return m_models->persistent_models(); }; - ProjectContext project_context{modified_callback, models_callback}; - - auto select_dir_callback = [this]() { return m_userInteractor->onSelectDirRequest(); }; - auto create_dir_callback = [this]() { return m_userInteractor->onCreateDirRequest(); }; - auto answer_callback = [this]() { return m_userInteractor->onSaveChangesRequest(); }; - UserInteractionContext user_context{select_dir_callback, create_dir_callback, answer_callback}; - - m_projectManager = CreateProjectManager(project_context, user_context); -} - -//! Updates the name of the current project on main window, notifies the world. - -void ProjectHandler::updateCurrentProjectName() -{ - const auto current_project_dir = QString::fromStdString(m_projectManager->currentProjectDir()); - const auto is_modified = m_projectManager->isModified(); - - // set main window title - auto title = ModelView::Utils::ProjectWindowTitle(current_project_dir, is_modified); - if (auto main_window = ModelView::Utils::FindMainWindow(); main_window) - main_window->setWindowTitle(title); - - currentProjectModified(current_project_dir, is_modified); -} - -//! Update recent project list in settings, notifies the world. - -void ProjectHandler::updateRecentProjectNames() -{ - m_recentProjectSettings->addToRecentProjects( - QString::fromStdString(m_projectManager->currentProjectDir())); - recentProjectsListModified(m_recentProjectSettings->recentProjects()); -} - -} // namespace gui2 diff --git a/gui2/welcomeview/projecthandler.h b/gui2/welcomeview/projecthandler.h deleted file mode 100644 index 9c95e24b006dad5c746bb5e00b7d5a72333d8586..0000000000000000000000000000000000000000 --- a/gui2/welcomeview/projecthandler.h +++ /dev/null @@ -1,73 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/welcomeview/projecthandler.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_WELCOMEVIEW_PROJECTHANDLER_H -#define BORNAGAIN_GUI2_WELCOMEVIEW_PROJECTHANDLER_H - -#include "darefl_export.h" -#include <QObject> -#include <memory> -#include <vector> - -class QWidget; - -namespace ModelView { -class ProjectManagerInterface; -} - -namespace gui2 { - -class RecentProjectSettings; -class UserInteractor; -class ApplicationModels; -class RecentProjectWidget; - -//! Main class to coordinate all activity on user's request to create new project, -//! open existing one, or choose one of recent projects on disk. - -class DAREFLCORE_EXPORT ProjectHandler : public QObject { - Q_OBJECT - -public: - explicit ProjectHandler(ApplicationModels* models, QWidget* parent); - ~ProjectHandler() override; - -signals: - void currentProjectModified(const QString& project_dir, bool is_modified); - void recentProjectsListModified(const QStringList& projects); - -public slots: - void updateNames(); - bool canCloseProject() const; - void onCreateNewProject(); - void onOpenExistingProject(const QString& dirname = {}); - void onSaveCurrentProject(); - void onSaveProjectAs(); - - void clearRecentProjectsList(); - -private: - void initProjectManager(); - void updateCurrentProjectName(); - void updateRecentProjectNames(); - - std::unique_ptr<RecentProjectSettings> m_recentProjectSettings; - std::unique_ptr<UserInteractor> m_userInteractor; - std::unique_ptr<ModelView::ProjectManagerInterface> m_projectManager; - ApplicationModels* m_models{nullptr}; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_WELCOMEVIEW_PROJECTHANDLER_H diff --git a/gui2/welcomeview/projectpanewidget.cpp b/gui2/welcomeview/projectpanewidget.cpp deleted file mode 100644 index eab382a7858d6b473fa3f9c189788d7f54730405..0000000000000000000000000000000000000000 --- a/gui2/welcomeview/projectpanewidget.cpp +++ /dev/null @@ -1,105 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/welcomeview/projectpanewidget.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/welcomeview/projectpanewidget.h" -#include "mvvm/widgets/widgetutils.h" -#include <QLabel> -#include <QMouseEvent> -#include <QPainter> -#include <QVBoxLayout> - -namespace { -int widget_height() -{ - return ModelView::Utils::SizeOfLetterM().height() * 3; -} -} // namespace - -namespace gui2 { - -ProjectPaneWidget::ProjectPaneWidget(QWidget* parent) - : QWidget(parent) - , m_currentProjectTitle(new QLabel(" ")) - , m_currentProjectDir(new QLabel(" ")) - , m_widgetColor(QColor(Qt::white)) -{ - setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); - setFixedHeight(widget_height()); - auto layout = new QVBoxLayout(this); - layout->addWidget(m_currentProjectTitle); - layout->addWidget(m_currentProjectDir); -} - -//! Sets current project dir to 'project_dir', adjust title according to 'is_modified'. - -void ProjectPaneWidget::setCurrentProject(const QString& project_dir, bool is_modified) -{ - m_active = true; - m_projectDir = project_dir; - - auto trimmed_project_dir = ModelView::Utils::WithTildeHomePath(project_dir); - auto project_title = ModelView::Utils::ProjectWindowTitle(project_dir, is_modified); - - m_currentProjectDir->setText(trimmed_project_dir); - m_currentProjectDir->setToolTip(m_projectDir); - m_currentProjectTitle->setText(project_title); -} - -//! Clear content of widget and make it inactive. Inactive widget doesnt' send signals when -//! user click on it. - -void ProjectPaneWidget::clear() -{ - setActive(false); - m_projectDir.clear(); - m_currentProjectDir->setText({}); - m_currentProjectDir->setToolTip({}); - m_currentProjectTitle->setText({}); -} - -//! Set 'active' flag to the given value. 'False' means that the widget only shows the project -//! title, but doesn't react on mouse clicks and doesn't change the background on mouse -//! hover events. -void ProjectPaneWidget::setActive(bool value) -{ - m_active = value; - update(); -} - -void ProjectPaneWidget::paintEvent(QPaintEvent*) -{ - QPainter painter(this); - painter.fillRect(0, 0, size().width(), size().height(), m_widgetColor); -} - -void ProjectPaneWidget::enterEvent(QEvent*) -{ - if (m_active) - m_widgetColor = QColor(Qt::lightGray); - update(); -} - -void ProjectPaneWidget::leaveEvent(QEvent*) -{ - m_widgetColor = QColor(Qt::white); - update(); -} - -void ProjectPaneWidget::mousePressEvent(QMouseEvent* event) -{ - if (m_active && event->button() == Qt::LeftButton) - projectSelected(m_projectDir); -} - -} // namespace gui2 diff --git a/gui2/welcomeview/projectpanewidget.h b/gui2/welcomeview/projectpanewidget.h deleted file mode 100644 index cd15c366b3087806af373c43b16025e2db1d55ed..0000000000000000000000000000000000000000 --- a/gui2/welcomeview/projectpanewidget.h +++ /dev/null @@ -1,59 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/welcomeview/projectpanewidget.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_WELCOMEVIEW_PROJECTPANEWIDGET_H -#define BORNAGAIN_GUI2_WELCOMEVIEW_PROJECTPANEWIDGET_H - -#include "darefl_export.h" -#include <QWidget> - -class QLabel; - -namespace gui2 { - -//! Panel with labels to hold project name and project dir. When user clicks on it, -//! sends the request to open corresponding project. Part of RecentProjectsWidget. - -class DAREFLCORE_EXPORT ProjectPaneWidget : public QWidget { - Q_OBJECT - -public: - explicit ProjectPaneWidget(QWidget* parent = nullptr); - - void setCurrentProject(const QString& project_dir, bool is_modified = false); - - void clear(); - - void setActive(bool value); - -signals: - void projectSelected(const QString& project_dir); - -protected: - void paintEvent(QPaintEvent*) override; - void enterEvent(QEvent*) override; - void leaveEvent(QEvent*) override; - void mousePressEvent(QMouseEvent* event) override; - -private: - QLabel* m_currentProjectTitle{nullptr}; - QLabel* m_currentProjectDir{nullptr}; - QColor m_widgetColor; - bool m_active{false}; - QString m_projectDir; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_WELCOMEVIEW_PROJECTPANEWIDGET_H diff --git a/gui2/welcomeview/recentprojectsettings.cpp b/gui2/welcomeview/recentprojectsettings.cpp deleted file mode 100644 index ec3d4f1caa76018243b1c4042aacc5236c3889d0..0000000000000000000000000000000000000000 --- a/gui2/welcomeview/recentprojectsettings.cpp +++ /dev/null @@ -1,114 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/welcomeview/recentprojectsettings.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/welcomeview/recentprojectsettings.h" -#include "mvvm/utils/fileutils.h" -#include <QDir> -#include <QSettings> - -namespace { -const int max_recent_projects = 10; - -const QString group_key = "welcomeview"; -const QString current_workdir_key = "currentworkdir"; -const QString recent_projects_key = "recentprojects"; - -const QString workdir_setting_name() -{ - return group_key + "/" + current_workdir_key; -} - -const QString recent_projects_setting_name() -{ - return group_key + "/" + recent_projects_key; -} - -} // namespace - -namespace gui2 { - -RecentProjectSettings::RecentProjectSettings() -{ - readSettings(); -} - -RecentProjectSettings::~RecentProjectSettings() -{ - writeSettings(); -} - -//! Returns current workdir. -QString RecentProjectSettings::currentWorkdir() const -{ - return m_currentWorkdir; -} - -//! Updates current workdir value from user selection. -//! Workdir will be set as parent director of selected `dirname`. -void RecentProjectSettings::updateWorkdirFromSelection(const QString& dirname) -{ - if (!dirname.isEmpty()) { - auto parent_path = ModelView::Utils::parent_path(dirname.toStdString()); - m_currentWorkdir = QString::fromStdString(parent_path); - } -} - -//! Returns list of recent projects, validates if projects still exists on disk. -QStringList RecentProjectSettings::recentProjects() -{ - QStringList updatedList; - for (const auto& fileName : m_recentProjects) { - if (ModelView::Utils::exists(fileName.toStdString())) - updatedList.append(fileName); - } - m_recentProjects = updatedList; - return m_recentProjects; -} - -//! Adds directory to the list of recent projects. -void RecentProjectSettings::addToRecentProjects(const QString& dirname) -{ - m_recentProjects.removeAll(dirname); - m_recentProjects.prepend(dirname); - while (m_recentProjects.size() > max_recent_projects) - m_recentProjects.removeLast(); -} - -void RecentProjectSettings::clearRecentProjectsList() -{ - m_recentProjects.clear(); -} - -//! Write all settings to file. -void RecentProjectSettings::writeSettings() -{ - QSettings settings; - settings.setValue(workdir_setting_name(), m_currentWorkdir); - settings.setValue(recent_projects_setting_name(), m_recentProjects); -} - -//! Reads all settings from file. -void RecentProjectSettings::readSettings() -{ - QSettings settings; - m_currentWorkdir = QDir::homePath(); - - if (settings.contains(workdir_setting_name())) - m_currentWorkdir = settings.value(workdir_setting_name()).toString(); - - if (settings.contains(recent_projects_setting_name())) - m_recentProjects = settings.value(recent_projects_setting_name()).toStringList(); -} - -} // namespace gui2 diff --git a/gui2/welcomeview/recentprojectsettings.h b/gui2/welcomeview/recentprojectsettings.h deleted file mode 100644 index 4db3f5b14db8ad6f8f5b2b0d76cdc35dfa266496..0000000000000000000000000000000000000000 --- a/gui2/welcomeview/recentprojectsettings.h +++ /dev/null @@ -1,51 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/welcomeview/recentprojectsettings.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_WELCOMEVIEW_RECENTPROJECTSETTINGS_H -#define BORNAGAIN_GUI2_WELCOMEVIEW_RECENTPROJECTSETTINGS_H - -#include "darefl_export.h" -#include <QStringList> - -namespace gui2 { - -//! Collection of settings for RecentProjectWidget. Used to save last directory selected -//! by the user, and list of recent projects. Relies on QSettings machinery. - -class DAREFLCORE_EXPORT RecentProjectSettings { -public: - RecentProjectSettings(); - ~RecentProjectSettings(); - - QString currentWorkdir() const; - - void updateWorkdirFromSelection(const QString& dirname); - - QStringList recentProjects(); - - void addToRecentProjects(const QString& dirname); - - void clearRecentProjectsList(); - -private: - void writeSettings(); - void readSettings(); - - QString m_currentWorkdir; - QStringList m_recentProjects; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_WELCOMEVIEW_RECENTPROJECTSETTINGS_H diff --git a/gui2/welcomeview/recentprojectwidget.cpp b/gui2/welcomeview/recentprojectwidget.cpp deleted file mode 100644 index 4ddfee9b5342172ce01e8dc823aefec43ec06d79..0000000000000000000000000000000000000000 --- a/gui2/welcomeview/recentprojectwidget.cpp +++ /dev/null @@ -1,114 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/welcomeview/recentprojectwidget.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/welcomeview/recentprojectwidget.h" -#include "gui2/mainwindow/styleutils.h" -#include "gui2/welcomeview/projectpanewidget.h" -#include "mvvm/widgets/adjustingscrollarea.h" -#include "mvvm/widgets/widgetutils.h" -#include <QLabel> -#include <QScrollArea> -#include <QVBoxLayout> - -namespace { -const int max_recent_project_count = 10; -const double section_label_scale = 1.25; -} // namespace - -namespace gui2 { - -RecentProjectWidget::RecentProjectWidget(QWidget* parent) - : QWidget(parent), m_currentProjectPane(new ProjectPaneWidget) -{ - auto layout = new QVBoxLayout(this); - layout->setContentsMargins(20, 0, 10, 0); - - layout->addWidget(createRecentProjectScrollArea()); - layout->addStretch(1); -} - -QSize RecentProjectWidget::sizeHint() const -{ - return GUI::Utils::Style::DockSizeHint(); -} - -QSize RecentProjectWidget::minimumSizeHint() const -{ - return GUI::Utils::Style::DockMinimumSizeHint(); -} - -//! Set current project title and label on appropriate widget. -void RecentProjectWidget::setCurrentProject(const QString& project_dir, bool is_modified) -{ - m_currentProjectPane->setCurrentProject(project_dir, is_modified); - m_currentProjectPane->setActive(false); -} - -//! Set name of all recent projects to appropriate widgets. -void RecentProjectWidget::setRecentProjectsList(const QStringList& projects) -{ - int widget_index{0}; - for (auto widget : m_recentProjectPanes) { - if (widget_index < projects.size()) - widget->setCurrentProject(projects.at(widget_index), false); - else - widget->clear(); - - ++widget_index; - } -} - -QBoxLayout* RecentProjectWidget::createCurrentProjectLayout() const -{ - auto result = new QVBoxLayout; - auto label = new QLabel("Current Project"); - ModelView::Utils::ScaleLabelFont(label, section_label_scale); - result->addWidget(label); - result->addWidget(m_currentProjectPane); - return result; -} - -QBoxLayout* RecentProjectWidget::createRecentProjectLayout() -{ - auto result = new QVBoxLayout; - auto label = new QLabel("Recent Projects"); - ModelView::Utils::ScaleLabelFont(label, section_label_scale); - result->addWidget(label); - - for (int i = 0; i < max_recent_project_count; ++i) { - auto widget = new ProjectPaneWidget; - connect(widget, &ProjectPaneWidget::projectSelected, this, - &RecentProjectWidget::projectSelected); - m_recentProjectPanes.push_back(widget); - result->addWidget(widget); - } - return result; -} - -QWidget* RecentProjectWidget::createRecentProjectScrollArea() -{ - auto result = new ModelView::AdjustingScrollArea; - - auto content = new QWidget; - auto layout = new QVBoxLayout; - layout->addLayout(createCurrentProjectLayout()); - layout->addSpacing(ModelView::Utils::SizeOfLetterM().height()); - layout->addLayout(createRecentProjectLayout()); - content->setLayout(layout); - - result->setWidget(content); - return result; -} - -} // namespace gui2 diff --git a/gui2/welcomeview/recentprojectwidget.h b/gui2/welcomeview/recentprojectwidget.h deleted file mode 100644 index d78a6687257a022c861c90667a29f48edcc55a95..0000000000000000000000000000000000000000 --- a/gui2/welcomeview/recentprojectwidget.h +++ /dev/null @@ -1,59 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/welcomeview/recentprojectwidget.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_WELCOMEVIEW_RECENTPROJECTWIDGET_H -#define BORNAGAIN_GUI2_WELCOMEVIEW_RECENTPROJECTWIDGET_H - -#include "darefl_export.h" -#include <QWidget> -#include <memory> -#include <vector> - -class QBoxLayout; - -namespace gui2 { - -class ProjectPaneWidget; - -//! Widget with the name of current project and collection of recent projects. -//! Occupies left part of WelcomeView. - -class DAREFLCORE_EXPORT RecentProjectWidget : public QWidget { - Q_OBJECT - -public: - explicit RecentProjectWidget(QWidget* parent = nullptr); - - QSize sizeHint() const override; - QSize minimumSizeHint() const override; - - void setCurrentProject(const QString& project_dir, bool is_modified); - - void setRecentProjectsList(const QStringList& projects); - -signals: - void projectSelected(const QString& project_dir); - -private: - QBoxLayout* createCurrentProjectLayout() const; - QBoxLayout* createRecentProjectLayout(); - QWidget* createRecentProjectScrollArea(); - - ProjectPaneWidget* m_currentProjectPane; - std::vector<ProjectPaneWidget*> m_recentProjectPanes; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_WELCOMEVIEW_RECENTPROJECTWIDGET_H diff --git a/gui2/welcomeview/userinteractor.cpp b/gui2/welcomeview/userinteractor.cpp deleted file mode 100644 index 868ea56b35da31aa77306de8ca381ac46fc44df8..0000000000000000000000000000000000000000 --- a/gui2/welcomeview/userinteractor.cpp +++ /dev/null @@ -1,116 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/welcomeview/userinteractor.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/welcomeview/userinteractor.h" -#include "gui2/welcomeview/recentprojectsettings.h" -#include "mvvm/project/project_types.h" -#include "mvvm/project/projectutils.h" -#include "mvvm/utils/fileutils.h" -#include <QFileDialog> -#include <QMessageBox> -#include <map> - -using namespace ModelView; - -namespace { -//! Map of standard Qt answers to what ProjectManager expects. -std::map<QMessageBox::StandardButton, SaveChangesAnswer> answer_map() -{ - std::map<QMessageBox::StandardButton, SaveChangesAnswer> result = { - {QMessageBox::Save, SaveChangesAnswer::SAVE}, - {QMessageBox::Discard, SaveChangesAnswer::DISCARD}, - {QMessageBox::Cancel, SaveChangesAnswer::CANCEL}}; - return result; -} -} // namespace - -namespace gui2 { - -UserInteractor::UserInteractor(RecentProjectSettings* settings, QWidget* parent) - : m_settings(settings), m_parent(parent) -{ -} - -//! Returns directory on disk selected by the user via QFileDialog. -//! Checks if selected directory can be the project directory. - -std::string UserInteractor::onSelectDirRequest() -{ - auto dirname = selectDir(); - - if (dirname.empty()) // no valid selection - return {}; - - if (!ModelView::GUI::Project::Utils::IsPossibleProjectDir(dirname)) { - QMessageBox msgBox; - msgBox.setText( - "Selected directory doesn't look like a project directory, choose another one"); - msgBox.exec(); - return {}; - } - - return dirname; -} - -//! Returns new directory on disk created by the user via QFileDialog. - -std::string UserInteractor::onCreateDirRequest() - -{ - auto dirname = selectDir(); - - if (dirname.empty()) // no valid selection - return {}; - - if (!ModelView::Utils::is_empty(dirname)) { - QMessageBox msgBox; - msgBox.setText("The selected directory is not empty, choose another one."); - msgBox.exec(); - return {}; - } - - return dirname; -} - -//! Returns save/cancel/discard changes choice provided by the user. - -SaveChangesAnswer UserInteractor::onSaveChangesRequest() -{ - static auto translate = answer_map(); - - QMessageBox msgBox; - msgBox.setText("The project has been modified."); - msgBox.setInformativeText("Do you want to save your changes?"); - msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); - msgBox.setDefaultButton(QMessageBox::Save); - auto ret = static_cast<QMessageBox::StandardButton>(msgBox.exec()); - return translate[ret]; -} - -//! Summon dialog to select directory on disk. If selection is not empty, -//! save parent directory for later re-use. - -std::string UserInteractor::selectDir() const -{ - QString dirname = QFileDialog::getExistingDirectory( - m_parent, "Select directory", m_settings->currentWorkdir(), - QFileDialog::DontResolveSymlinks | QFileDialog::ShowDirsOnly); - - if (!dirname.isEmpty()) - m_settings->updateWorkdirFromSelection(dirname); - - return dirname.toStdString(); -} - -} // namespace gui2 diff --git a/gui2/welcomeview/userinteractor.h b/gui2/welcomeview/userinteractor.h deleted file mode 100644 index 1f92440bb5cbb6d40258bea391a5c4cd41cc9309..0000000000000000000000000000000000000000 --- a/gui2/welcomeview/userinteractor.h +++ /dev/null @@ -1,53 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/welcomeview/userinteractor.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_WELCOMEVIEW_USERINTERACTOR_H -#define BORNAGAIN_GUI2_WELCOMEVIEW_USERINTERACTOR_H - -#include "darefl_export.h" -#include <string> - -class QWidget; - -namespace ModelView { -enum class SaveChangesAnswer; -} - -namespace gui2 { - -class RecentProjectSettings; - -//! Provide save/discard/cancel and similar dialogs on user request. -//! Intended to work in pair with ProjectManagerDecorator. - -class DAREFLCORE_EXPORT UserInteractor { -public: - UserInteractor(RecentProjectSettings* settings, QWidget* parent); - - std::string onSelectDirRequest(); - - std::string onCreateDirRequest(); - - ModelView::SaveChangesAnswer onSaveChangesRequest(); - -private: - std::string selectDir() const; - - RecentProjectSettings* m_settings{nullptr}; - QWidget* m_parent{nullptr}; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_WELCOMEVIEW_USERINTERACTOR_H diff --git a/gui2/welcomeview/welcomeview.cpp b/gui2/welcomeview/welcomeview.cpp deleted file mode 100644 index 2d55b9a2caccecdb09edf0a7308498e79c5ec9d3..0000000000000000000000000000000000000000 --- a/gui2/welcomeview/welcomeview.cpp +++ /dev/null @@ -1,112 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/welcomeview/welcomeview.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "gui2/welcomeview/welcomeview.h" -#include "gui2/model/applicationmodels.h" -#include "gui2/welcomeview/openprojectwidget.h" -#include "gui2/welcomeview/projecthandler.h" -#include "gui2/welcomeview/recentprojectsettings.h" -#include "gui2/welcomeview/recentprojectwidget.h" -#include "mvvm/project/projectutils.h" -#include "mvvm/widgets/widgetutils.h" -#include <QApplication> -#include <QHBoxLayout> -#include <QMainWindow> - -namespace gui2 { - -WelcomeView::WelcomeView(ApplicationModels* models, QWidget* parent) - : QWidget(parent) - , m_models(models) - , m_projectHandler(new ProjectHandler(models, this)) - , m_recentProjectWidget(new RecentProjectWidget) - , m_openProjectWidget(new OpenProjectWidget) -{ - QPalette palette; - palette.setColor(QPalette::Window, Qt::white); - setAutoFillBackground(true); - setPalette(palette); - - auto layout = new QHBoxLayout(this); - layout->addSpacing(50); - layout->addWidget(m_recentProjectWidget, 38); - layout->addWidget(m_openProjectWidget, 62); - layout->addSpacing(50); - - setup_connections(); -} - -WelcomeView::~WelcomeView() = default; - -//! Returns 'true' if current project can be closed. -//! Internally will perform check for unsaved data, and proceed via save/discard/cancel dialog. - -bool WelcomeView::canCloseProject() const -{ - return m_projectHandler->canCloseProject(); -} - -void WelcomeView::updateNames() -{ - m_projectHandler->updateNames(); -} - -void WelcomeView::onCreateNewProject() -{ - m_projectHandler->onCreateNewProject(); -} - -void WelcomeView::onOpenExistingProject(const QString& dirname) -{ - return m_projectHandler->onOpenExistingProject(dirname); -} - -void WelcomeView::onSaveCurrentProject() -{ - return m_projectHandler->onSaveCurrentProject(); -} - -void WelcomeView::onSaveProjectAs() -{ - return m_projectHandler->onSaveProjectAs(); -} - -void WelcomeView::onClearRecentProjectsList() -{ - m_projectHandler->clearRecentProjectsList(); -} - -void WelcomeView::setup_connections() -{ - // connect buttons of OpenProjectWidget with this slots. - auto open_existing_project = [this]() { onOpenExistingProject(); }; - connect(m_openProjectWidget, &OpenProjectWidget::openExistingProjectRequest, - open_existing_project); - connect(m_openProjectWidget, &OpenProjectWidget::createNewProjectRequest, this, - &WelcomeView::onCreateNewProject); - - // connect RecentProjectWidget panels with this slots. - connect(m_recentProjectWidget, &RecentProjectWidget::projectSelected, this, - &WelcomeView::onOpenExistingProject); - - // connect ProjectHandler with RecentProjectWidget - connect(m_projectHandler, &ProjectHandler::currentProjectModified, m_recentProjectWidget, - &RecentProjectWidget::setCurrentProject); - connect(m_projectHandler, &ProjectHandler::recentProjectsListModified, m_recentProjectWidget, - &RecentProjectWidget::setRecentProjectsList); - connect(m_projectHandler, &ProjectHandler::recentProjectsListModified, this, - &WelcomeView::recentProjectsListModified); -} - -} // namespace gui2 diff --git a/gui2/welcomeview/welcomeview.h b/gui2/welcomeview/welcomeview.h deleted file mode 100644 index 091b715facacdf8a049730647e8a894c193c0440..0000000000000000000000000000000000000000 --- a/gui2/welcomeview/welcomeview.h +++ /dev/null @@ -1,66 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file gui2/welcomeview/welcomeview.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI2_WELCOMEVIEW_WELCOMEVIEW_H -#define BORNAGAIN_GUI2_WELCOMEVIEW_WELCOMEVIEW_H - -#include "darefl_export.h" -#include <QWidget> -#include <memory> - -namespace gui2 { - -class ApplicationModels; -class ProjectHandler; -class RecentProjectWidget; -class OpenProjectWidget; -class RecentProjectSettings; - -//! Welcome view. Main widget on first tab of MainWindow. - -class DAREFLCORE_EXPORT WelcomeView : public QWidget { - Q_OBJECT - -public: - WelcomeView(ApplicationModels* models, QWidget* parent = nullptr); - ~WelcomeView(); - - bool canCloseProject() const; - - void updateNames(); - -signals: - void recentProjectsListModified(const QStringList& projects); - -public slots: - void onCreateNewProject(); - void onOpenExistingProject(const QString& dirname = {}); - void onSaveCurrentProject(); - void onSaveProjectAs(); - void onClearRecentProjectsList(); - -private: - void setup_connections(); - void update_current_project_name(); - void update_recent_project_names(); - - ApplicationModels* m_models{nullptr}; - ProjectHandler* m_projectHandler{nullptr}; - RecentProjectWidget* m_recentProjectWidget{nullptr}; - OpenProjectWidget* m_openProjectWidget{nullptr}; -}; - -} // namespace gui2 - -#endif // BORNAGAIN_GUI2_WELCOMEVIEW_WELCOMEVIEW_H diff --git a/mvvm/CMakeLists.txt b/mvvm/CMakeLists.txt deleted file mode 100644 index f963a972f93ae3780796b837d5178d2b37285c71..0000000000000000000000000000000000000000 --- a/mvvm/CMakeLists.txt +++ /dev/null @@ -1,26 +0,0 @@ -cmake_minimum_required(VERSION 3.14) -project(qt-mvvm VERSION 0.2.0 LANGUAGES CXX) - -set(CMAKE_CXX_STANDARD 17) - -option(MVVM_BUMP_VERSION "Propagate version number" OFF) -option(MVVM_DISCOVER_TESTS "Auto discover tests and add to ctest, otherwise will run at compile time" ON) -option(MVVM_ENABLE_FILESYSTEM "Enable <filesystem> (requires modern compiler), otherwise rely on Qt" ON) -option(MVVM_BUILD_EXAMPLES "Build user examples" ON) - -set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/cmake/modules) -include(configuration) - -set(CMAKE_CXX_VISIBILITY_PRESET hidden) -set(CMAKE_VISIBILITY_INLINES_HIDDEN 1) - -add_subdirectory(model) -add_subdirectory(viewmodel) -add_subdirectory(view) - -add_subdirectory(tests) - -include(installation) - -# Defines new 'clangformat' target. See CodeTools.cmake for details. -# project_clangformat_setup() diff --git a/mvvm/cmake/modules/ClangFormat.cmake b/mvvm/cmake/modules/ClangFormat.cmake deleted file mode 100644 index eb89dcd4018555679704ab4c72b6ee97e031ba8b..0000000000000000000000000000000000000000 --- a/mvvm/cmake/modules/ClangFormat.cmake +++ /dev/null @@ -1,46 +0,0 @@ -# Copyright Tomas Zeman 2019. -# Distributed under the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) - -function(clangformat_setup) - if(NOT CLANGFORMAT_EXECUTABLE) - set(CLANGFORMAT_EXECUTABLE clang-format) - endif() - - if(NOT EXISTS ${CLANGFORMAT_EXECUTABLE}) - find_program(clangformat_executable_tmp ${CLANGFORMAT_EXECUTABLE}) - if(clangformat_executable_tmp) - set(CLANGFORMAT_EXECUTABLE ${clangformat_executable_tmp}) - unset(clangformat_executable_tmp) - else() - message(FATAL_ERROR "ClangFormat: ${CLANGFORMAT_EXECUTABLE} not found! Aborting") - endif() - endif() - - foreach(clangformat_source ${ARGV}) - get_filename_component(clangformat_source ${clangformat_source} ABSOLUTE) - list(APPEND clangformat_sources ${clangformat_source}) - endforeach() - - add_custom_target(${PROJECT_NAME}_clangformat - COMMAND - ${CLANGFORMAT_EXECUTABLE} - -style=file - -i - ${clangformat_sources} - COMMENT - "Formating with ${CLANGFORMAT_EXECUTABLE} ..." - ) - - if(TARGET clangformat) - add_dependencies(clangformat ${PROJECT_NAME}_clangformat) - else() - add_custom_target(clangformat DEPENDS ${PROJECT_NAME}_clangformat) - endif() -endfunction() - -function(target_clangformat_setup target) - get_target_property(target_sources ${target} SOURCES) - clangformat_setup(${target_sources}) -endfunction() diff --git a/mvvm/cmake/modules/CodeTools.cmake b/mvvm/cmake/modules/CodeTools.cmake deleted file mode 100644 index 03234b7b670b23f808a46fab2357266f9d9d1f76..0000000000000000000000000000000000000000 --- a/mvvm/cmake/modules/CodeTools.cmake +++ /dev/null @@ -1,28 +0,0 @@ -# Collection of functions to set-up code beautification and analysis -include(ClangFormat) - -# List of targets for project code beautification. -set(BEAUTIFICATION_TARGETS mvvm_model mvvm_viewmodel mvvm_view testmodel testviewmodel testview) -set(BEAUTIFICATION_EXAMPLES celleditorscore concurrentplotcore dragandmovecore flateditorcore - graphicsproxycore layereditorcore plotcolormapcore plotgraphscore saveloadprojectcore treeviewscore) - -# Defines new target for 'clangformat' to beautify whole project. -# Use 'make clangformat' or 'cmake --build . --target clangformat' to beautify the code. -# Beautification settings are located in .clang-format in project directory. - -function(project_clangformat_setup) - set(all_sources) - foreach(target ${BEAUTIFICATION_TARGETS}) - get_target_property(target_sources ${target} SOURCES) - list(APPEND all_sources ${target_sources}) - endforeach() - # examples needs to add manualy target source dir to all names - foreach(target ${BEAUTIFICATION_EXAMPLES}) - get_target_property(target_sources ${target} SOURCES) - get_target_property(target_source_dir ${target} SOURCE_DIR) - foreach(target ${target_sources}) - list(APPEND all_sources ${target_source_dir}/${target}) - endforeach() - endforeach() - clangformat_setup(${all_sources}) -endfunction() diff --git a/mvvm/cmake/modules/configuration.cmake b/mvvm/cmake/modules/configuration.cmake deleted file mode 100644 index 46e653e10fb0d45b5a4ac9edb6d296719b4989fe..0000000000000000000000000000000000000000 --- a/mvvm/cmake/modules/configuration.cmake +++ /dev/null @@ -1,67 +0,0 @@ -message(STATUS "CMake version ${CMAKE_VERSION}") - -# ----------------------------------------------------------------------------- -# Modules -# ----------------------------------------------------------------------------- - -include(CTest) -include(CodeTools) -include(GenerateExportHeader) -include(GNUInstallDirs) - -# ----------------------------------------------------------------------------- -# Variables -# ----------------------------------------------------------------------------- - -get_filename_component(MVVM_PROJECT_DIR "${CMAKE_CURRENT_LIST_DIR}/../.." ABSOLUTE) - -set(MVVM_SOVERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}) -set(MVVM_BUILDVERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}) -set(MVVM_TESTOUTPUT_DIR ${CMAKE_BINARY_DIR}/test_output_mvvm) - -# ----------------------------------------------------------------------------- -# Directories -# ----------------------------------------------------------------------------- - -set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) - -file(MAKE_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}) -file(MAKE_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) -file(MAKE_DIRECTORY ${MVVM_TESTOUTPUT_DIR}) - -# directory for autogenerated configs -set(MVVM_AUTOGEN_DIR ${CMAKE_BINARY_DIR}/autogen/mvvm) -file(MAKE_DIRECTORY ${MVVM_AUTOGEN_DIR}) - -# ----------------------------------------------------------------------------- -# Dependencies -# ----------------------------------------------------------------------------- - -set(CMAKE_AUTOMOC ON) -set(CMAKE_AUTORCC ON) - -find_package(Qt5 5.12 COMPONENTS Widgets Core Gui PrintSupport REQUIRED) -find_package(Threads) - -get_target_property(Qt5Widgets_location Qt5::Widgets LOCATION_Release) -message(STATUS " Qt5 libraries : ${Qt5Widgets_LIBRARIES} ${Qt5Widgets_location}") -message(STATUS " Qt5 Includes : ${Qt5Widgets_INCLUDE_DIRS}") - -# ----------------------------------------------------------------------------- -# Generating config files -# ----------------------------------------------------------------------------- - -configure_file(${MVVM_PROJECT_DIR}/cmake/scripts/testconfig.h.in ${MVVM_AUTOGEN_DIR}/testconfig.h @ONLY) - -if (MVVM_BUMP_VERSION) - configure_file(${MVVM_PROJECT_DIR}/cmake/scripts/mvvm_version.h.in ${MVVM_PROJECT_DIR}/source/libmvvm_model/mvvm/core/version.h @ONLY) -endif() - -# ----------------------------------------------------------------------------- -# Compile options -# ----------------------------------------------------------------------------- - -add_compile_options($<$<CXX_COMPILER_ID:MSVC>:/MP>) diff --git a/mvvm/cmake/modules/installation.cmake b/mvvm/cmake/modules/installation.cmake deleted file mode 100644 index 4ff10cd6fd4ca62a7f42c40f8d22b4badc69f01d..0000000000000000000000000000000000000000 --- a/mvvm/cmake/modules/installation.cmake +++ /dev/null @@ -1,45 +0,0 @@ -# ----------------------------------------------------------------------------- -# Installation -# Credits to https://pabloariasal.github.io/2018/02/19/its-time-to-do-cmake-right, -# https://gitlab.kitware.com/cmake/community/-/wikis/doc/tutorials/Exporting-and-Importing-Targets -# ----------------------------------------------------------------------------- - -set(INSTALL_CONFIGDIR ${CMAKE_INSTALL_LIBDIR}/cmake/mvvm) - -# exporting targets to a script and installing it -install(EXPORT mvvm-targets FILE MVVMTargets.cmake NAMESPACE MVVM:: DESTINATION ${INSTALL_CONFIGDIR}) - -# ----------------------------------------------------------------------------- -# Exporting -# ----------------------------------------------------------------------------- - -# Add all targets to the build-tree export set -export(TARGETS mvvm_model mvvm_viewmodel mvvm_view NAMESPACE MVVM:: FILE "${PROJECT_BINARY_DIR}/MVVMTargets.cmake") - -# Export the package for use from the build-tree (goes to $HOME/.cmake) -set(CMAKE_EXPORT_PACKAGE_REGISTRY ON) -export(PACKAGE MVVM) - -# ----------------------------------------------------------------------------- -# Creating and installing MVVMConfig.cmake -# ----------------------------------------------------------------------------- - -include(CMakePackageConfigHelpers) - -# to use in the build tree -configure_package_config_file(${MVVM_PROJECT_DIR}/cmake/scripts/MVVMConfig.cmake.in - ${CMAKE_CURRENT_BINARY_DIR}/MVVMConfig.cmake - INSTALL_DESTINATION ${INSTALL_CONFIGDIR} -) - -# to use in install tree -install(FILES ${CMAKE_CURRENT_BINARY_DIR}/MVVMConfig.cmake DESTINATION ${INSTALL_CONFIGDIR}) - -# ----------------------------------------------------------------------------- -# Create and install ConfigVersion.cmake file -# ----------------------------------------------------------------------------- - -write_basic_package_version_file(${CMAKE_CURRENT_BINARY_DIR}/MVVMConfigVersion.cmake VERSION - ${PROJECT_VERSION} COMPATIBILITY AnyNewerVersion) - -install(FILES ${CMAKE_CURRENT_BINARY_DIR}/MVVMConfigVersion.cmake DESTINATION ${INSTALL_CONFIGDIR}) diff --git a/mvvm/cmake/scripts/MVVMConfig.cmake.in b/mvvm/cmake/scripts/MVVMConfig.cmake.in deleted file mode 100644 index f6d2dfc8e5676755b805a45dbd8f40b2afb25700..0000000000000000000000000000000000000000 --- a/mvvm/cmake/scripts/MVVMConfig.cmake.in +++ /dev/null @@ -1,21 +0,0 @@ -# MVVM_INCLUDE_DIRS - include directories for qt-mvvm -# MVVM_LIBRARIES - libraries to link against - -get_filename_component(MVVM_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) - -include(CMakeFindDependencyMacro) -find_dependency(Qt5 5.12 COMPONENTS Widgets REQUIRED) -find_dependency(Threads) - -if(TARGET MVVM::Model OR TARGET MVVM::ViewModel OR TARGET MVVM::View) -else() - message(STATUS "MVVMConfig.cmake including ${MVVM_CMAKE_DIR}/MVVMTargets.cmake") - include("${MVVM_CMAKE_DIR}/MVVMTargets.cmake") -endif() - -set(MVVM_LIBRARIES MVVM::Model MVVM::ViewModel MVVM::View) - -message(STATUS "MVVMConfig.cmake in ${CMAKE_CURRENT_LIST_FILE}") -message(STATUS " MVVM_LIBRARIES ${MVVM_LIBRARIES}") - - diff --git a/mvvm/cmake/scripts/mvvm_version.h.in b/mvvm/cmake/scripts/mvvm_version.h.in deleted file mode 100644 index f8c49492674e00825c55f40ddb9d2fe590a2f22d..0000000000000000000000000000000000000000 --- a/mvvm/cmake/scripts/mvvm_version.h.in +++ /dev/null @@ -1,51 +0,0 @@ -// ************************************************************************** // -// -// Model-view-view-model framework for large GUI applications -// -//! @license GNU General Public License v3 or higher (see COPYING) -//! @authors see AUTHORS -// -// ************************************************************************** // - -#ifndef MVVM_CORE_VERSION_H -#define MVVM_CORE_VERSION_H - -//! @file version.h -//! Automatically generated from mvvm_version.h.in - -#include <string> - -namespace ModelView -{ - -//! Returns major project version. -inline int ProjectVersionMajor() -{ - const int project_version_major = @PROJECT_VERSION_MAJOR@; - return project_version_major; -} - -//! Returns minor project version. -inline int ProjectVersionMinor() -{ - const int project_version_minor = @PROJECT_VERSION_MINOR@; - return project_version_minor; -} - -//! Returns patch project version. -inline int ProjectVersionPatch() -{ - const int project_version_path = @PROJECT_VERSION_PATCH@; - return project_version_path; -} - -//! Returns project version string -inline std::string ProjectVersion() -{ - const std::string project_version = "@PROJECT_VERSION@"; - return project_version; -} - -} // namespace ModelView - -#endif // MVVM_CORE_VERSION_H diff --git a/mvvm/cmake/scripts/testconfig.h.in b/mvvm/cmake/scripts/testconfig.h.in deleted file mode 100644 index ca6899b3f299357124cffc81c9e89a139d0e7f4a..0000000000000000000000000000000000000000 --- a/mvvm/cmake/scripts/testconfig.h.in +++ /dev/null @@ -1,29 +0,0 @@ -// ************************************************************************** // -// -// Model-view-view-model framework for large GUI applications -// -//! @license GNU General Public License v3 or higher (see COPYING) -//! @authors see AUTHORS -// -// ************************************************************************** // - -#ifndef SCRIPTS_TESTCONFIG_H -#define SCRIPTS_TESTCONFIG_H - -#include <string> - -//! Provides build time information for unit tests. -//! Automatically generated by CMake from testconfig.h.in - -namespace TestConfig { - -inline std::string CMakeSourceDir() { return "@CMAKE_SOURCE_DIR@"; } -inline std::string CMakeBinaryDir() { return "@CMAKE_BINARY_DIR@"; } -inline std::string TestOutputDir() { return "@MVVM_TESTOUTPUT_DIR@"; } -inline std::string ProjectSourceDir() { return "@MVVM_PROJECT_DIR@"; } -inline std::string TestData() { return "@MVVM_PROJECT_DIR@/tests/data"; } - -} - -#endif - diff --git a/mvvm/model/CMakeLists.txt b/mvvm/model/CMakeLists.txt deleted file mode 100644 index e738bbcdb53862418d94cc9be56555f7356d08f1..0000000000000000000000000000000000000000 --- a/mvvm/model/CMakeLists.txt +++ /dev/null @@ -1,38 +0,0 @@ -# ----------------------------------------------------------------------------- -# Library: mvvm_model -# ----------------------------------------------------------------------------- -set(library_name mvvm_model) - -add_library(${library_name} SHARED "") -add_subdirectory(mvvm) -add_library(MVVM::Model ALIAS ${library_name}) # alias for build-tree usage - -# -- Generate header for export -- - -set(export_filename ${MVVM_AUTOGEN_DIR}/mvvm/model_export.h) -generate_export_header(${library_name} EXPORT_FILE_NAME ${export_filename}) - -# -- Dependencies -- - -target_link_libraries(${library_name} PUBLIC Qt5::Widgets Threads::Threads) -target_include_directories(${library_name} - PUBLIC - $<INSTALL_INTERFACE:include> - $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}> $<BUILD_INTERFACE:${MVVM_AUTOGEN_DIR}> - ) - -# -- Definitions -- - -target_compile_features(${library_name} PUBLIC cxx_std_17) # clang code model in Qt creator - -if (MVVM_ENABLE_FILESYSTEM) - add_definitions(-DENABLE_FILESYSTEM) -endif() - -# -- Installation -- - -install(TARGETS ${library_name} EXPORT mvvm-targets LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) -set_target_properties(${library_name} PROPERTIES EXPORT_NAME Model SOVERSION ${MVVM_SOVERSION} VERSION ${MVVM_BUILDVERSION}) -install(DIRECTORY mvvm/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/mvvm FILES_MATCHING PATTERN "*.h") -install(FILES ${export_filename} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/mvvm) - diff --git a/mvvm/model/mvvm/CMakeLists.txt b/mvvm/model/mvvm/CMakeLists.txt deleted file mode 100644 index 09107428c2d976b6a4169d70f3322514d1b53506..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -add_subdirectory(commands) -add_subdirectory(core) -add_subdirectory(factories) -add_subdirectory(interfaces) -add_subdirectory(model) -add_subdirectory(project) -add_subdirectory(serialization) -add_subdirectory(signals) -add_subdirectory(standarditems) -add_subdirectory(utils) diff --git a/mvvm/model/mvvm/commands/CMakeLists.txt b/mvvm/model/mvvm/commands/CMakeLists.txt deleted file mode 100644 index 70e73403f5f8680e8ae443ea61b199618ff79bbf..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/commands/CMakeLists.txt +++ /dev/null @@ -1,23 +0,0 @@ -target_sources(${library_name} PRIVATE - abstractitemcommand.cpp - abstractitemcommand.h - commandadapter.cpp - commandadapter.h - commandresult.h - commandservice.cpp - commandservice.h - commandutils.cpp - commandutils.h - copyitemcommand.cpp - copyitemcommand.h - insertnewitemcommand.cpp - insertnewitemcommand.h - moveitemcommand.cpp - moveitemcommand.h - removeitemcommand.cpp - removeitemcommand.h - setvaluecommand.cpp - setvaluecommand.h - undostack.cpp - undostack.h -) diff --git a/mvvm/model/mvvm/commands/abstractitemcommand.cpp b/mvvm/model/mvvm/commands/abstractitemcommand.cpp deleted file mode 100644 index bd3b88ed550f538c14ac1ef081a49b953e9ffb16..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/commands/abstractitemcommand.cpp +++ /dev/null @@ -1,129 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/commands/abstractitemcommand.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/commands/abstractitemcommand.h" -#include "mvvm/model/modelutils.h" -#include "mvvm/model/path.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/model/sessionmodel.h" -#include <stdexcept> - -using namespace ModelView; - -struct AbstractItemCommand::AbstractItemCommandImpl { - enum class Status { initial, after_execute, after_undo }; - bool m_isObsolete{false}; - std::string m_text; - Status m_status{Status::initial}; - SessionModel* m_model{nullptr}; - AbstractItemCommand* m_self{nullptr}; - CommandResult m_result; - AbstractItemCommandImpl(AbstractItemCommand* parent) : m_self(parent) {} - - void set_after_execute() { m_status = Status::after_execute; } - void set_after_undo() { m_status = Status::after_undo; } - bool can_execute() const { return m_status != Status::after_execute; } - bool can_undo() const { return m_status == Status::after_execute && !m_self->isObsolete(); } -}; - -AbstractItemCommand::AbstractItemCommand(SessionItem* receiver) - : p_impl(std::make_unique<AbstractItemCommand::AbstractItemCommandImpl>(this)) -{ - if (!receiver) - throw std::runtime_error("Invalid item."); - - if (!receiver->model()) - throw std::runtime_error("Item doesn't have a model"); - - p_impl->m_model = receiver->model(); -} - -AbstractItemCommand::~AbstractItemCommand() = default; - -//! Execute command. - -void AbstractItemCommand::execute() -{ - if (!p_impl->can_execute()) - throw std::runtime_error("Can't execute the command. Wrong order."); - - execute_command(); - - p_impl->set_after_execute(); -} - -//! Undo command as it was before execution. - -void AbstractItemCommand::undo() -{ - if (!p_impl->can_undo()) - throw std::runtime_error("Can't undo the command. Wrong order."); - - undo_command(); - - p_impl->set_after_undo(); -} - -//! Returns whether the command is obsolete (which means that it shouldn't be kept in the stack). - -bool AbstractItemCommand::isObsolete() const -{ - return p_impl->m_isObsolete; -} - -//! Returns command description. - -std::string AbstractItemCommand::description() const -{ - return p_impl->m_text; -} - -CommandResult AbstractItemCommand::result() const -{ - return p_impl->m_result; -} - -//! Sets command obsolete flag. - -void AbstractItemCommand::setObsolete(bool flag) -{ - p_impl->m_isObsolete = flag; -} - -//! Sets command description. - -void AbstractItemCommand::setDescription(const std::string& text) -{ - p_impl->m_text = text; -} - -Path AbstractItemCommand::pathFromItem(SessionItem* item) const -{ - return Utils::PathFromItem(item); -} - -SessionItem* AbstractItemCommand::itemFromPath(const Path& path) const -{ - return Utils::ItemFromPath(*p_impl->m_model, path); -} - -SessionModel* AbstractItemCommand::model() const -{ - return p_impl->m_model; -} - -void AbstractItemCommand::setResult(const CommandResult& command_result) -{ - p_impl->m_result = command_result; -} diff --git a/mvvm/model/mvvm/commands/abstractitemcommand.h b/mvvm/model/mvvm/commands/abstractitemcommand.h deleted file mode 100644 index 42602e687ad541016adfd14f049ced1985728273..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/commands/abstractitemcommand.h +++ /dev/null @@ -1,67 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/commands/abstractitemcommand.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_COMMANDS_ABSTRACTITEMCOMMAND_H -#define BORNAGAIN_MVVM_MODEL_MVVM_COMMANDS_ABSTRACTITEMCOMMAND_H - -#include "mvvm/commands/commandresult.h" -#include "mvvm/model_export.h" -#include <memory> -#include <string> - -namespace ModelView { - -class SessionItem; -class SessionModel; -class Path; - -//! Abstract command interface to manipulate SessionItem in model context. - -class MVVM_MODEL_EXPORT AbstractItemCommand { -public: - explicit AbstractItemCommand(SessionItem* receiver); - virtual ~AbstractItemCommand(); - - AbstractItemCommand(const AbstractItemCommand& other) = delete; - AbstractItemCommand& operator=(const AbstractItemCommand& other) = delete; - - void execute(); - - void undo(); - - bool isObsolete() const; - - std::string description() const; - - CommandResult result() const; - -protected: - void setObsolete(bool flag); - void setDescription(const std::string& text); - Path pathFromItem(SessionItem* item) const; - SessionItem* itemFromPath(const Path& path) const; - SessionModel* model() const; - void setResult(const CommandResult& command_result); - -private: - virtual void execute_command() = 0; - virtual void undo_command() = 0; - - struct AbstractItemCommandImpl; - std::unique_ptr<AbstractItemCommandImpl> p_impl; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_COMMANDS_ABSTRACTITEMCOMMAND_H diff --git a/mvvm/model/mvvm/commands/commandadapter.cpp b/mvvm/model/mvvm/commands/commandadapter.cpp deleted file mode 100644 index 8dea93805d8269f301a04c37ac1dd80e7bfbbcb7..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/commands/commandadapter.cpp +++ /dev/null @@ -1,37 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/commands/commandadapter.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/commands/commandadapter.h" -#include "mvvm/commands/abstractitemcommand.h" - -using namespace ModelView; - -CommandAdapter::CommandAdapter(std::shared_ptr<AbstractItemCommand> command) - : m_command(std::move(command)) -{ -} - -CommandAdapter::~CommandAdapter() = default; - -void CommandAdapter::undo() -{ - m_command->undo(); -} - -void CommandAdapter::redo() -{ - m_command->execute(); - setObsolete(m_command->isObsolete()); - setText(QString::fromStdString(m_command->description())); -} diff --git a/mvvm/model/mvvm/commands/commandadapter.h b/mvvm/model/mvvm/commands/commandadapter.h deleted file mode 100644 index 972449df66b435f62b9d6d9dff793c4f7564748c..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/commands/commandadapter.h +++ /dev/null @@ -1,42 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/commands/commandadapter.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_COMMANDS_COMMANDADAPTER_H -#define BORNAGAIN_MVVM_MODEL_MVVM_COMMANDS_COMMANDADAPTER_H - -#include "mvvm/model_export.h" -#include <QUndoCommand> -#include <memory> - -namespace ModelView { - -class AbstractItemCommand; - -//! Adapter to execute our commands within Qt undo/redo framework. - -class MVVM_MODEL_EXPORT CommandAdapter : public QUndoCommand { -public: - CommandAdapter(std::shared_ptr<AbstractItemCommand> command); - ~CommandAdapter() override; - - void undo() override; - void redo() override; - -private: - std::shared_ptr<AbstractItemCommand> m_command; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_COMMANDS_COMMANDADAPTER_H diff --git a/mvvm/model/mvvm/commands/commandresult.h b/mvvm/model/mvvm/commands/commandresult.h deleted file mode 100644 index 13dde1c15113a1f02a3675239d71c61877bfbdc2..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/commands/commandresult.h +++ /dev/null @@ -1,29 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/commands/commandresult.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_COMMANDS_COMMANDRESULT_H -#define BORNAGAIN_MVVM_MODEL_MVVM_COMMANDS_COMMANDRESULT_H - -#include <variant> - -namespace ModelView { - -class SessionItem; - -//! Results of command execution. -using CommandResult = std::variant<bool, ModelView::SessionItem*>; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_COMMANDS_COMMANDRESULT_H diff --git a/mvvm/model/mvvm/commands/commandservice.cpp b/mvvm/model/mvvm/commands/commandservice.cpp deleted file mode 100644 index 4e5e43b9f5c54319c08191d27bba58d32f45aec8..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/commands/commandservice.cpp +++ /dev/null @@ -1,110 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/commands/commandservice.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/commands/commandservice.h" -#include "mvvm/commands/copyitemcommand.h" -#include "mvvm/commands/insertnewitemcommand.h" -#include "mvvm/commands/moveitemcommand.h" -#include "mvvm/commands/removeitemcommand.h" -#include "mvvm/commands/setvaluecommand.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/model/sessionmodel.h" -#include <stdexcept> - -using namespace ModelView; - -CommandService::CommandService(SessionModel* model) : m_model(model), m_pause_record(false) {} - -void CommandService::setUndoRedoEnabled(bool value) -{ - if (value) - m_commands = std::make_unique<UndoStack>(); - else - m_commands.reset(); -} - -SessionItem* CommandService::insertNewItem(const item_factory_func_t& func, SessionItem* parent, - const TagRow& tagrow) -{ - if (!parent) - parent = m_model->rootItem(); - - int actual_row = tagrow.row < 0 ? parent->itemCount(tagrow.tag) : tagrow.row; - - return std::get<SessionItem*>( - process_command<InsertNewItemCommand>(func, parent, TagRow{tagrow.tag, actual_row})); -} - -SessionItem* CommandService::copyItem(const SessionItem* item, SessionItem* parent, - const TagRow& tagrow) -{ - if (!item) - return nullptr; - - if (parent->model() != m_model) - throw std::runtime_error( - "CommandService::copyItem() -> Item doesn't belong to given model"); - - int actual_row = tagrow.row < 0 ? parent->itemCount(tagrow.tag) : tagrow.row; - - return std::get<SessionItem*>( - process_command<CopyItemCommand>(item, parent, TagRow{tagrow.tag, actual_row})); -} - -bool CommandService::setData(SessionItem* item, const Variant& value, int role) -{ - if (!item) - return false; - - return std::get<bool>(process_command<SetValueCommand>(item, value, role)); -} - -void CommandService::removeItem(SessionItem* parent, const TagRow& tagrow) -{ - if (parent->model() != m_model) - throw std::runtime_error( - "CommandService::removeRow() -> Item doesn't belong to given model"); - - process_command<RemoveItemCommand>(parent, tagrow); -} - -void CommandService::moveItem(SessionItem* item, SessionItem* new_parent, const TagRow& tagrow) -{ - if (item->model() != m_model) - throw std::runtime_error( - "CommandService::removeRow() -> Item doesn't belong to given model"); - - if (new_parent->model() != m_model) - throw std::runtime_error( - "CommandService::removeRow() -> Parent doesn't belong to given model"); - - int actual_row = tagrow.row < 0 ? new_parent->itemCount(tagrow.tag) : tagrow.row; - - process_command<MoveItemCommand>(item, new_parent, TagRow{tagrow.tag, actual_row}); -} - -UndoStackInterface* CommandService::undoStack() const -{ - return m_commands.get(); -} - -void CommandService::setCommandRecordPause(bool value) -{ - m_pause_record = value; -} - -bool CommandService::provideUndo() const -{ - return m_commands && !m_pause_record; -} diff --git a/mvvm/model/mvvm/commands/commandservice.h b/mvvm/model/mvvm/commands/commandservice.h deleted file mode 100644 index 4cf98c727f7d9962ea345a3059d22068e4cd0c65..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/commands/commandservice.h +++ /dev/null @@ -1,85 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/commands/commandservice.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_COMMANDS_COMMANDSERVICE_H -#define BORNAGAIN_MVVM_MODEL_MVVM_COMMANDS_COMMANDSERVICE_H - -#include "mvvm/commands/commandresult.h" -#include "mvvm/commands/undostack.h" -#include "mvvm/core/variant.h" -#include "mvvm/model/function_types.h" -#include "mvvm/model_export.h" -#include <memory> - -class QUndoCommand; - -namespace ModelView { - -class SessionModel; -class SessionItem; -class TagRow; - -//! Provides undo/redo for all commands of SessionModel. - -class MVVM_MODEL_EXPORT CommandService { -public: - CommandService(SessionModel* model); - - void setUndoRedoEnabled(bool value); - - SessionItem* insertNewItem(const item_factory_func_t& func, SessionItem* parent, - const TagRow& tagrow); - - SessionItem* copyItem(const SessionItem* item, SessionItem* parent, const TagRow& tagrow); - - bool setData(SessionItem* item, const Variant& value, int role); - - void removeItem(SessionItem* parent, const TagRow& tagrow); - - void moveItem(SessionItem* item, SessionItem* new_parent, const TagRow& tagrow); - - UndoStackInterface* undoStack() const; - - void setCommandRecordPause(bool value); - -private: - template <typename C, typename... Args> CommandResult process_command(Args&&... args); - - bool provideUndo() const; - - SessionModel* m_model; - std::unique_ptr<UndoStackInterface> m_commands; - bool m_pause_record; -}; - -//! Creates and processes command of given type using given argument list. - -template <typename C, typename... Args> -CommandResult CommandService::process_command(Args&&... args) -{ - if (provideUndo()) { - // making shared because underlying QUndoStack requires ownership - auto command = std::make_shared<C>(std::forward<Args>(args)...); - m_commands->execute(command); - return command->result(); - } else { - C command(std::forward<Args>(args)...); - command.execute(); - return command.result(); - } -} - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_COMMANDS_COMMANDSERVICE_H diff --git a/mvvm/model/mvvm/commands/commandutils.cpp b/mvvm/model/mvvm/commands/commandutils.cpp deleted file mode 100644 index 36a2568682eea95d2a8a3fc88928c71945991ce3..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/commands/commandutils.cpp +++ /dev/null @@ -1,32 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/commands/commandutils.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/commands/commandutils.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/serialization/jsonitembackupstrategy.h" -#include "mvvm/serialization/jsonitemcopystrategy.h" - -std::unique_ptr<ModelView::ItemBackupStrategy> -ModelView::CreateItemBackupStrategy(const ModelView::SessionModel* model) -{ - assert(model); - return std::make_unique<JsonItemBackupStrategy>(model->factory()); -} - -std::unique_ptr<ModelView::ItemCopyStrategy> -ModelView::CreateItemCopyStrategy(const ModelView::SessionModel* model) -{ - assert(model); - return std::make_unique<JsonItemCopyStrategy>(model->factory()); -} diff --git a/mvvm/model/mvvm/commands/commandutils.h b/mvvm/model/mvvm/commands/commandutils.h deleted file mode 100644 index 7adb35dc46a4c8318590880be5de6a29167e709c..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/commands/commandutils.h +++ /dev/null @@ -1,43 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/commands/commandutils.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_COMMANDS_COMMANDUTILS_H -#define BORNAGAIN_MVVM_MODEL_MVVM_COMMANDS_COMMANDUTILS_H - -//! @file mvvm/model/mvvm/commands/commandutils.h -//! Collection of various utility functions for command service. - -#include "mvvm/interfaces/itembackupstrategy.h" -#include "mvvm/interfaces/itemcopystrategy.h" -#include <memory> - -namespace ModelView { - -class SessionModel; - -//! Creates strategy suitable for item saving/restoring. Restored item will have same identifiers -//! as original. - -MVVM_MODEL_EXPORT std::unique_ptr<ItemBackupStrategy> -CreateItemBackupStrategy(const SessionModel* model); - -//! Returns strategy for item copying. Identifiers of the copy will be different from identifiers -//! of the original. - -MVVM_MODEL_EXPORT std::unique_ptr<ItemCopyStrategy> -CreateItemCopyStrategy(const SessionModel* model); - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_COMMANDS_COMMANDUTILS_H diff --git a/mvvm/model/mvvm/commands/copyitemcommand.cpp b/mvvm/model/mvvm/commands/copyitemcommand.cpp deleted file mode 100644 index 56eef0f9e60ed4965c0faec84a056a1acaa3cd25..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/commands/copyitemcommand.cpp +++ /dev/null @@ -1,81 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/commands/copyitemcommand.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/commands/copyitemcommand.h" -#include "mvvm/commands/commandutils.h" -#include "mvvm/interfaces/itembackupstrategy.h" -#include "mvvm/interfaces/itemcopystrategy.h" -#include "mvvm/model/path.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/model/sessionmodel.h" -#include <sstream> - -using namespace ModelView; - -namespace { -std::string generate_description(const std::string& modelType, const TagRow& tagrow); -} // namespace - -struct CopyItemCommand::CopyItemCommandImpl { - TagRow tagrow; - std::unique_ptr<ItemBackupStrategy> backup_strategy; - Path item_path; - CopyItemCommandImpl(TagRow tagrow) : tagrow(std::move(tagrow)) {} -}; - -CopyItemCommand::CopyItemCommand(const SessionItem* item, SessionItem* parent, TagRow tagrow) - : AbstractItemCommand(parent), p_impl(std::make_unique<CopyItemCommandImpl>(std::move(tagrow))) -{ - setResult(nullptr); - - setDescription(generate_description(item->modelType(), p_impl->tagrow)); - p_impl->backup_strategy = CreateItemBackupStrategy(parent->model()); - p_impl->item_path = pathFromItem(parent); - - auto copy_strategy = CreateItemCopyStrategy(parent->model()); // to modify id's - auto item_copy = copy_strategy->createCopy(item); - - p_impl->backup_strategy->saveItem(item_copy.get()); -} - -CopyItemCommand::~CopyItemCommand() = default; - -void CopyItemCommand::undo_command() -{ - auto parent = itemFromPath(p_impl->item_path); - delete parent->takeItem(p_impl->tagrow); - setResult(nullptr); -} - -void CopyItemCommand::execute_command() -{ - auto parent = itemFromPath(p_impl->item_path); - auto item = p_impl->backup_strategy->restoreItem(); - if (parent->insertItem(item.get(), p_impl->tagrow)) { - auto result = item.release(); - setResult(result); - } else { - setResult(nullptr); - setObsolete(true); - } -} - -namespace { -std::string generate_description(const std::string& modelType, const TagRow& tagrow) -{ - std::ostringstream ostr; - ostr << "Copy item'" << modelType << "' tag:'" << tagrow.tag << "', row:" << tagrow.row; - return ostr.str(); -} -} // namespace diff --git a/mvvm/model/mvvm/commands/copyitemcommand.h b/mvvm/model/mvvm/commands/copyitemcommand.h deleted file mode 100644 index 31bb7ef8f37b47e4d20368439e786d2f3a2982a4..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/commands/copyitemcommand.h +++ /dev/null @@ -1,42 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/commands/copyitemcommand.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_COMMANDS_COPYITEMCOMMAND_H -#define BORNAGAIN_MVVM_MODEL_MVVM_COMMANDS_COPYITEMCOMMAND_H - -#include "mvvm/commands/abstractitemcommand.h" - -namespace ModelView { - -class SessionItem; -class TagRow; - -//! Command to copy an item. - -class MVVM_MODEL_EXPORT CopyItemCommand : public AbstractItemCommand { -public: - CopyItemCommand(const SessionItem* item, SessionItem* parent, TagRow tagrow); - ~CopyItemCommand() override; - -private: - void undo_command() override; - void execute_command() override; - - struct CopyItemCommandImpl; - std::unique_ptr<CopyItemCommandImpl> p_impl; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_COMMANDS_COPYITEMCOMMAND_H diff --git a/mvvm/model/mvvm/commands/insertnewitemcommand.cpp b/mvvm/model/mvvm/commands/insertnewitemcommand.cpp deleted file mode 100644 index 741aca6d9950496e401cb1cc9a534f408640998f..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/commands/insertnewitemcommand.cpp +++ /dev/null @@ -1,83 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/commands/insertnewitemcommand.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/commands/insertnewitemcommand.h" -#include "mvvm/model/path.h" -#include "mvvm/model/sessionitem.h" -#include <sstream> - -using namespace ModelView; - -namespace { -std::string generate_description(const std::string& modelType, const TagRow& tagrow); -} // namespace - -struct InsertNewItemCommand::InsertNewItemCommandImpl { - item_factory_func_t factory_func; - TagRow tagrow; - Path item_path; - std::string initial_identifier; - InsertNewItemCommandImpl(item_factory_func_t func, TagRow tagrow) - : factory_func(std::move(func)), tagrow(std::move(tagrow)) - { - } -}; - -InsertNewItemCommand::InsertNewItemCommand(item_factory_func_t func, SessionItem* parent, - const TagRow& tagrow) - : AbstractItemCommand(parent), p_impl(std::make_unique<InsertNewItemCommandImpl>(func, tagrow)) -{ - setResult(nullptr); - p_impl->item_path = pathFromItem(parent); -} - -InsertNewItemCommand::~InsertNewItemCommand() = default; - -void InsertNewItemCommand::undo_command() -{ - auto parent = itemFromPath(p_impl->item_path); - auto item = parent->takeItem(p_impl->tagrow); - // saving identifier for later redo - if (p_impl->initial_identifier.empty()) - p_impl->initial_identifier = item->identifier(); - delete item; - setResult(nullptr); -} - -void InsertNewItemCommand::execute_command() -{ - auto parent = itemFromPath(p_impl->item_path); - auto child = p_impl->factory_func().release(); - // here we restore original identifier to get exactly same item on consequitive undo/redo - if (!p_impl->initial_identifier.empty()) - child->setData(QVariant::fromValue(p_impl->initial_identifier), ItemDataRole::IDENTIFIER, - /*direct*/ true); - - setDescription(generate_description(child->modelType(), p_impl->tagrow)); - if (parent->insertItem(child, p_impl->tagrow)) { - setResult(child); - } else { - delete child; - setObsolete(true); - } -} - -namespace { -std::string generate_description(const std::string& modelType, const TagRow& tagrow) -{ - std::ostringstream ostr; - ostr << "New item type '" << modelType << "' tag:'" << tagrow.tag << "', row:" << tagrow.row; - return ostr.str(); -} -} // namespace diff --git a/mvvm/model/mvvm/commands/insertnewitemcommand.h b/mvvm/model/mvvm/commands/insertnewitemcommand.h deleted file mode 100644 index 733979d830e1722a526cc88119dfdfe917016332..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/commands/insertnewitemcommand.h +++ /dev/null @@ -1,43 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/commands/insertnewitemcommand.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_COMMANDS_INSERTNEWITEMCOMMAND_H -#define BORNAGAIN_MVVM_MODEL_MVVM_COMMANDS_INSERTNEWITEMCOMMAND_H - -#include "mvvm/commands/abstractitemcommand.h" -#include "mvvm/model/function_types.h" - -namespace ModelView { - -class SessionItem; -class TagRow; - -//! Command for unddo/redo to insert new item. - -class MVVM_MODEL_EXPORT InsertNewItemCommand : public AbstractItemCommand { -public: - InsertNewItemCommand(item_factory_func_t func, SessionItem* parent, const TagRow& tagrow); - ~InsertNewItemCommand() override; - -private: - void undo_command() override; - void execute_command() override; - - struct InsertNewItemCommandImpl; - std::unique_ptr<InsertNewItemCommandImpl> p_impl; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_COMMANDS_INSERTNEWITEMCOMMAND_H diff --git a/mvvm/model/mvvm/commands/moveitemcommand.cpp b/mvvm/model/mvvm/commands/moveitemcommand.cpp deleted file mode 100644 index cb82b6fda6d0d5d583a1e4ce62fdfd1bce81aeb4..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/commands/moveitemcommand.cpp +++ /dev/null @@ -1,128 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/commands/moveitemcommand.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/commands/moveitemcommand.h" -#include "mvvm/model/itemutils.h" -#include "mvvm/model/path.h" -#include "mvvm/model/sessionitem.h" -#include <sstream> -#include <stdexcept> - -using namespace ModelView; - -namespace { -void check_input_data(const SessionItem* item, const SessionItem* parent); -std::string generate_description(const TagRow& tagrow); -} // namespace - -struct MoveItemCommand::MoveItemCommandImpl { - TagRow target_tagrow; - Path target_parent_path; - Path original_parent_path; - TagRow original_tagrow; - MoveItemCommandImpl(TagRow tagrow) : target_tagrow(std::move(tagrow)) - { - if (target_tagrow.row < 0) - throw std::runtime_error("MoveItemCommand() -> Error. Uninitialized target row"); - } -}; - -MoveItemCommand::MoveItemCommand(SessionItem* item, SessionItem* new_parent, TagRow tagrow) - : AbstractItemCommand(new_parent), p_impl(std::make_unique<MoveItemCommandImpl>(tagrow)) -{ - setResult(true); - - check_input_data(item, new_parent); - setDescription(generate_description(p_impl->target_tagrow)); - - p_impl->target_parent_path = pathFromItem(new_parent); - p_impl->original_parent_path = pathFromItem(item->parent()); - p_impl->original_tagrow = item->tagRow(); - - if (Utils::IsSinglePropertyTag(*item->parent(), p_impl->original_tagrow.tag)) - throw std::runtime_error("MoveItemCommand::MoveItemCommand() -> Single property tag."); - - if (Utils::IsSinglePropertyTag(*new_parent, p_impl->target_tagrow.tag)) - throw std::runtime_error("MoveItemCommand::MoveItemCommand() -> Single property tag."); - - if (item->parent() == new_parent) { - if (p_impl->target_tagrow.row >= new_parent->itemCount(p_impl->target_tagrow.tag)) - throw std::runtime_error( - "MoveCommand::MoveCommand() -> move index exceeds number of items in a tag"); - } -} - -MoveItemCommand::~MoveItemCommand() = default; - -void MoveItemCommand::undo_command() -{ - // first find items - auto current_parent = itemFromPath(p_impl->target_parent_path); - auto target_parent = itemFromPath(p_impl->original_parent_path); - - // then make manipulations - auto taken = current_parent->takeItem(p_impl->target_tagrow); - target_parent->insertItem(taken, p_impl->original_tagrow); - - // adjusting new addresses - p_impl->target_parent_path = pathFromItem(current_parent); - p_impl->original_parent_path = pathFromItem(target_parent); -} - -void MoveItemCommand::execute_command() -{ - // first find items - auto original_parent = itemFromPath(p_impl->original_parent_path); - auto target_parent = itemFromPath(p_impl->target_parent_path); - - // then make manipulations - auto taken = original_parent->takeItem(p_impl->original_tagrow); - - if (!taken) - throw std::runtime_error("MoveItemCommand::execute() -> Can't take an item."); - - bool succeeded = target_parent->insertItem(taken, p_impl->target_tagrow); - if (!succeeded) - throw std::runtime_error("MoveItemCommand::execute() -> Can't insert item."); - - // adjusting new addresses - p_impl->target_parent_path = pathFromItem(target_parent); - p_impl->original_parent_path = pathFromItem(original_parent); -} - -namespace { -void check_input_data(const SessionItem* item, const SessionItem* parent) -{ - if (!item || !item->model()) - throw std::runtime_error("MoveItemCommand::MoveItemCommand() -> Invalid input item"); - - if (!parent || !parent->model()) - throw std::runtime_error("MoveItemCommand::MoveItemCommand() -> Invalid parent item"); - - if (item->model() != parent->model()) - throw std::runtime_error( - "MoveItemCommand::MoveItemCommand() -> Items belong to different models"); - - if (!item->parent()) - throw std::runtime_error( - "MoveItemCommand::MoveItemCommand() -> Item doesn't have a parent"); -} - -std::string generate_description(const TagRow& tagrow) -{ - std::ostringstream ostr; - ostr << "Move item to tag '" << tagrow.tag << "', row:" << tagrow.row; - return ostr.str(); -} -} // namespace diff --git a/mvvm/model/mvvm/commands/moveitemcommand.h b/mvvm/model/mvvm/commands/moveitemcommand.h deleted file mode 100644 index 4831f32b6f093b164ae99ab4f9751c57c0a49d78..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/commands/moveitemcommand.h +++ /dev/null @@ -1,43 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/commands/moveitemcommand.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_COMMANDS_MOVEITEMCOMMAND_H -#define BORNAGAIN_MVVM_MODEL_MVVM_COMMANDS_MOVEITEMCOMMAND_H - -#include "mvvm/commands/abstractitemcommand.h" -#include <memory> - -namespace ModelView { - -class SessionItem; -class TagRow; - -//! Command for unddo/redo framework to move item from one parent to another. - -class MVVM_MODEL_EXPORT MoveItemCommand : public AbstractItemCommand { -public: - MoveItemCommand(SessionItem* item, SessionItem* new_parent, TagRow tagrow); - ~MoveItemCommand() override; - -private: - void undo_command() override; - void execute_command() override; - - struct MoveItemCommandImpl; - std::unique_ptr<MoveItemCommandImpl> p_impl; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_COMMANDS_MOVEITEMCOMMAND_H diff --git a/mvvm/model/mvvm/commands/removeitemcommand.cpp b/mvvm/model/mvvm/commands/removeitemcommand.cpp deleted file mode 100644 index 04c0534600fd1d4cd59bef85c5630ed723d35f31..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/commands/removeitemcommand.cpp +++ /dev/null @@ -1,76 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/commands/removeitemcommand.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/commands/removeitemcommand.h" -#include "mvvm/commands/commandutils.h" -#include "mvvm/interfaces/itembackupstrategy.h" -#include "mvvm/model/path.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/model/sessionmodel.h" -#include <sstream> - -using namespace ModelView; - -namespace { -std::string generate_description(const TagRow& tagrow); -} // namespace - -struct RemoveItemCommand::RemoveItemCommandImpl { - TagRow tagrow; - std::unique_ptr<ItemBackupStrategy> backup_strategy; - Path item_path; - RemoveItemCommandImpl(TagRow tagrow) : tagrow(std::move(tagrow)) {} -}; - -RemoveItemCommand::RemoveItemCommand(SessionItem* parent, TagRow tagrow) - : AbstractItemCommand(parent) - , p_impl(std::make_unique<RemoveItemCommandImpl>(std::move(tagrow))) -{ - setResult(false); - - setDescription(generate_description(p_impl->tagrow)); - p_impl->backup_strategy = CreateItemBackupStrategy(parent->model()); - p_impl->item_path = pathFromItem(parent); -} - -RemoveItemCommand::~RemoveItemCommand() = default; - -void RemoveItemCommand::undo_command() -{ - auto parent = itemFromPath(p_impl->item_path); - auto reco_item = p_impl->backup_strategy->restoreItem(); - parent->insertItem(reco_item.release(), p_impl->tagrow); -} - -void RemoveItemCommand::execute_command() -{ - auto parent = itemFromPath(p_impl->item_path); - if (auto child = parent->takeItem(p_impl->tagrow); child) { - p_impl->backup_strategy->saveItem(child); - delete child; - setResult(true); - } else { - setResult(false); - setObsolete(true); - } -} - -namespace { -std::string generate_description(const TagRow& tagrow) -{ - std::ostringstream ostr; - ostr << "Remove item from tag '" << tagrow.tag << "', row " << tagrow.row; - return ostr.str(); -} -} // namespace diff --git a/mvvm/model/mvvm/commands/removeitemcommand.h b/mvvm/model/mvvm/commands/removeitemcommand.h deleted file mode 100644 index f171e8d55d44dfa6d4c5911cd45df18d524fcd3b..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/commands/removeitemcommand.h +++ /dev/null @@ -1,42 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/commands/removeitemcommand.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_COMMANDS_REMOVEITEMCOMMAND_H -#define BORNAGAIN_MVVM_MODEL_MVVM_COMMANDS_REMOVEITEMCOMMAND_H - -#include "mvvm/commands/abstractitemcommand.h" - -namespace ModelView { - -class SessionItem; -class TagRow; - -//! Command for unddo/redo framework to remove item from a model using child's tag and row. - -class MVVM_MODEL_EXPORT RemoveItemCommand : public AbstractItemCommand { -public: - RemoveItemCommand(SessionItem* parent, TagRow tagrow); - ~RemoveItemCommand() override; - -private: - void undo_command() override; - void execute_command() override; - - struct RemoveItemCommandImpl; - std::unique_ptr<RemoveItemCommandImpl> p_impl; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_COMMANDS_REMOVEITEMCOMMAND_H diff --git a/mvvm/model/mvvm/commands/setvaluecommand.cpp b/mvvm/model/mvvm/commands/setvaluecommand.cpp deleted file mode 100644 index 21b9658d211f5ec9c3a0a6e93638ad3ffe0a36d0..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/commands/setvaluecommand.cpp +++ /dev/null @@ -1,76 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/commands/setvaluecommand.cpp -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/commands/setvaluecommand.h" -#include "mvvm/core/variant.h" -#include "mvvm/model/modelutils.h" -#include "mvvm/model/path.h" -#include "mvvm/model/sessionitem.h" -#include <sstream> - -namespace { -std::string generate_description(const std::string& str, int role); -} // namespace - -using namespace ModelView; - -struct SetValueCommand::SetValueCommandImpl { - Variant m_value; //! Value to set as a result of command execution. - int m_role; - Path m_item_path; - SetValueCommandImpl(Variant value, int role) : m_value(std::move(value)), m_role(role) {} -}; - -// ---------------------------------------------------------------------------- - -SetValueCommand::SetValueCommand(SessionItem* item, Variant value, int role) - : AbstractItemCommand(item) - , p_impl(std::make_unique<SetValueCommandImpl>(std::move(value), role)) -{ - setResult(false); - - setDescription(generate_description(p_impl->m_value.toString().toStdString(), role)); - p_impl->m_item_path = pathFromItem(item); -} - -SetValueCommand::~SetValueCommand() = default; - -void SetValueCommand::undo_command() -{ - swap_values(); -} - -void SetValueCommand::execute_command() -{ - swap_values(); -} - -void SetValueCommand::swap_values() -{ - auto item = itemFromPath(p_impl->m_item_path); - auto old = item->data<Variant>(p_impl->m_role); - auto result = item->setData(p_impl->m_value, p_impl->m_role, /*direct*/ true); - setResult(result); - setObsolete(!result); - p_impl->m_value = old; -} - -namespace { -std::string generate_description(const std::string& str, int role) -{ - std::ostringstream ostr; - ostr << "Set value: " << str << ", role:" << role; - return ostr.str(); -} -} // namespace diff --git a/mvvm/model/mvvm/commands/setvaluecommand.h b/mvvm/model/mvvm/commands/setvaluecommand.h deleted file mode 100644 index 86594493f73b6928f82960351efa9df02a26d93d..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/commands/setvaluecommand.h +++ /dev/null @@ -1,43 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/commands/setvaluecommand.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_COMMANDS_SETVALUECOMMAND_H -#define BORNAGAIN_MVVM_MODEL_MVVM_COMMANDS_SETVALUECOMMAND_H - -#include "mvvm/commands/abstractitemcommand.h" -#include "mvvm/core/variant.h" - -namespace ModelView { - -class SessionItem; - -//! Command for unddo/redo framework to set the data of SessionItem. - -class MVVM_MODEL_EXPORT SetValueCommand : public AbstractItemCommand { -public: - SetValueCommand(SessionItem* item, Variant value, int role); - ~SetValueCommand() override; - -private: - void undo_command() override; - void execute_command() override; - void swap_values(); - - struct SetValueCommandImpl; - std::unique_ptr<SetValueCommandImpl> p_impl; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_COMMANDS_SETVALUECOMMAND_H diff --git a/mvvm/model/mvvm/commands/undostack.cpp b/mvvm/model/mvvm/commands/undostack.cpp deleted file mode 100644 index c6b6d274b571b4504a45ec1860ab81ab70bb019c..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/commands/undostack.cpp +++ /dev/null @@ -1,102 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/commands/undostack.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/commands/undostack.h" -#include "mvvm/commands/commandadapter.h" -#include <QUndoStack> - -using namespace ModelView; - -struct UndoStack::UndoStackImpl { - std::unique_ptr<QUndoStack> m_undoStack; - UndoStackImpl() : m_undoStack(std::make_unique<QUndoStack>()) {} - QUndoStack* undoStack() { return m_undoStack.get(); } -}; - -UndoStack::UndoStack() : p_impl(std::make_unique<UndoStackImpl>()) {} - -void UndoStack::execute(std::shared_ptr<AbstractItemCommand> command) -{ - // Wrapping command for Qt. It will be executed by Qt after push. - auto adapter = new CommandAdapter(std::move(command)); - p_impl->undoStack()->push(adapter); -} - -UndoStack::~UndoStack() = default; - -bool UndoStack::isActive() const -{ - return p_impl->undoStack()->isActive(); -} - -bool UndoStack::canUndo() const -{ - return p_impl->undoStack()->canUndo(); -} - -bool UndoStack::canRedo() const -{ - return p_impl->undoStack()->canRedo(); -} - -int UndoStack::index() const -{ - return p_impl->undoStack()->index(); -} - -int UndoStack::count() const -{ - return p_impl->undoStack()->count(); -} - -void UndoStack::undo() -{ - return p_impl->undoStack()->undo(); -} - -void UndoStack::redo() -{ - return p_impl->undoStack()->redo(); -} - -void UndoStack::clear() -{ - return p_impl->undoStack()->clear(); -} - -void UndoStack::setUndoLimit(int limit) -{ - return p_impl->undoStack()->setUndoLimit(limit); -} - -//! Returns underlying QUndoStack if given object can be casted to UndoStack instance. -//! This method is used to "convert" current instance to Qt implementation, and use it with other -//! Qt widgets, if necessary. - -QUndoStack* UndoStack::qtUndoStack(UndoStackInterface* stack_interface) -{ - if (auto stack = dynamic_cast<UndoStack*>(stack_interface); stack) - return stack->p_impl->undoStack(); - return nullptr; -} - -void UndoStack::beginMacro(const std::string& name) -{ - p_impl->undoStack()->beginMacro(QString::fromStdString(name)); -} - -void UndoStack::endMacro() -{ - p_impl->undoStack()->endMacro(); -} diff --git a/mvvm/model/mvvm/commands/undostack.h b/mvvm/model/mvvm/commands/undostack.h deleted file mode 100644 index c3726d715f53046ffc08428dc1ef38f0456f6a1f..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/commands/undostack.h +++ /dev/null @@ -1,60 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/commands/undostack.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_COMMANDS_UNDOSTACK_H -#define BORNAGAIN_MVVM_MODEL_MVVM_COMMANDS_UNDOSTACK_H - -#include "mvvm/interfaces/undostackinterface.h" -#include "mvvm/model_export.h" -#include <memory> - -class QUndoStack; - -namespace ModelView { - -//! Default undo stack implementation. Internally relies on QUndoStack. -//! It serves two goals: a) hides Qt usage b) simplifies future refactoring toward Qt-independent -//! libmvvm_model library. - -class MVVM_MODEL_EXPORT UndoStack : public UndoStackInterface { -public: - UndoStack(); - ~UndoStack() override; - - //! Executes the command, then pushes it in the stack for possible undo. - void execute(std::shared_ptr<AbstractItemCommand> command) override; - - bool isActive() const override; - bool canUndo() const override; - bool canRedo() const override; - int index() const override; - int count() const override; - void undo() override; - void redo() override; - void clear() override; - void setUndoLimit(int limit) override; - - static QUndoStack* qtUndoStack(UndoStackInterface* stack_interface); - - void beginMacro(const std::string& name) override; - void endMacro() override; - -private: - struct UndoStackImpl; - std::unique_ptr<UndoStackImpl> p_impl; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_COMMANDS_UNDOSTACK_H diff --git a/mvvm/model/mvvm/core/CMakeLists.txt b/mvvm/model/mvvm/core/CMakeLists.txt deleted file mode 100644 index 2a745fe708fcd5e1675d9b52a0f74b41bff99f00..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/core/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -target_sources(${library_name} PRIVATE - filesystem.h - types.h - uniqueidgenerator.cpp - uniqueidgenerator.h - variant.h - version.h -) diff --git a/mvvm/model/mvvm/core/filesystem.h b/mvvm/model/mvvm/core/filesystem.h deleted file mode 100644 index 6a690cc75c8086fa919e4005f14c89a9dcf8af50..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/core/filesystem.h +++ /dev/null @@ -1,93 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/core/filesystem.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_CORE_FILESYSTEM_H -#define BORNAGAIN_MVVM_MODEL_MVVM_CORE_FILESYSTEM_H - -//! @file mvvm/model/mvvm/core/filesystem.h of <filesystem> library for older compilers (<gcc8.0) -//! See -//! https://stackoverflow.com/questions/53365538/how-to-determine-whether-to-use-filesystem-or-experimental-filesystem - -// We haven't checked which filesystem to include yet -#ifndef INCLUDE_STD_FILESYSTEM_EXPERIMENTAL - -// Check for feature test macro for <filesystem> -#if defined(__cpp_lib_filesystem) -#define INCLUDE_STD_FILESYSTEM_EXPERIMENTAL 0 - -// Check for feature test macro for <experimental/filesystem> -#elif defined(__cpp_lib_experimental_filesystem) -#define INCLUDE_STD_FILESYSTEM_EXPERIMENTAL 1 - -// We can't check if headers exist... -// Let's assume experimental to be safe -#elif !defined(__has_include) -#define INCLUDE_STD_FILESYSTEM_EXPERIMENTAL 1 - -// Check if the header "<filesystem>" exists -#elif __has_include(<filesystem>) - -// If we're compiling on Visual Studio and are not compiling with C++17, we need to use experimental -#ifdef _MSC_VER - -// Check and include header that defines "_HAS_CXX17" -#if __has_include(<yvals_core.h>) -#include <yvals_core.h> - -// Check for enabled C++17 support -#if defined(_HAS_CXX17) && _HAS_CXX17 -// We're using C++17, so let's use the normal version -#define INCLUDE_STD_FILESYSTEM_EXPERIMENTAL 0 -#endif -#endif - -// If the marco isn't defined yet, that means any of the other VS specific checks failed, so we need -// to use experimental -#ifndef INCLUDE_STD_FILESYSTEM_EXPERIMENTAL -#define INCLUDE_STD_FILESYSTEM_EXPERIMENTAL 1 -#endif - -// Not on Visual Studio. Let's use the normal version -#else // #ifdef _MSC_VER -#define INCLUDE_STD_FILESYSTEM_EXPERIMENTAL 0 -#endif - -// Check if the header "<filesystem>" exists -#elif __has_include(<experimental/filesystem>) -#define INCLUDE_STD_FILESYSTEM_EXPERIMENTAL 1 - -// Fail if neither header is available with a nice error message -#else -#error Could not find system header "<filesystem>" or "<experimental/filesystem>" -#endif - -// We priously determined that we need the exprimental version -#if INCLUDE_STD_FILESYSTEM_EXPERIMENTAL -// Include it -#include <experimental/filesystem> - -// We need the alias from std::experimental::filesystem to std::filesystem -namespace std { -namespace filesystem = experimental::filesystem; -} - -// We have a decent compiler and can use the normal version -#else -// Include it -#include <filesystem> -#endif - -#endif // #ifndef INCLUDE_STD_FILESYSTEM_EXPERIMENTAL - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_CORE_FILESYSTEM_H diff --git a/mvvm/model/mvvm/core/types.h b/mvvm/model/mvvm/core/types.h deleted file mode 100644 index 4fcdf5c89dd546e576ffde73a118c1b8f8285bdb..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/core/types.h +++ /dev/null @@ -1,27 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/core/types.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_CORE_TYPES_H -#define BORNAGAIN_MVVM_MODEL_MVVM_CORE_TYPES_H - -#include <string> - -namespace ModelView { - -using identifier_type = std::string; -using model_type = std::string; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_CORE_TYPES_H diff --git a/mvvm/model/mvvm/core/uniqueidgenerator.cpp b/mvvm/model/mvvm/core/uniqueidgenerator.cpp deleted file mode 100644 index 54ad825c5f6d492f248d00504e797b2b5084b8c2..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/core/uniqueidgenerator.cpp +++ /dev/null @@ -1,23 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/core/uniqueidgenerator.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/core/uniqueidgenerator.h" -#include <QUuid> - -using namespace ModelView; - -identifier_type UniqueIdGenerator::generate() -{ - return QUuid::createUuid().toString().toStdString(); -} diff --git a/mvvm/model/mvvm/core/uniqueidgenerator.h b/mvvm/model/mvvm/core/uniqueidgenerator.h deleted file mode 100644 index 38a3256415a7e16511cc48e1b10b988a3bde2124..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/core/uniqueidgenerator.h +++ /dev/null @@ -1,40 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/core/uniqueidgenerator.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_CORE_UNIQUEIDGENERATOR_H -#define BORNAGAIN_MVVM_MODEL_MVVM_CORE_UNIQUEIDGENERATOR_H - -#include "mvvm/core/types.h" -#include "mvvm/model_export.h" - -namespace ModelView { - -/*! -@class UniqueIdGenerator -@brief Provides generation of unique SessionItem itentifier. - -In the future might be turned to singleton to keep track of all generated identifier -and make sure, that SessionItem identifiers loaded from disk, are different from those -generated during dynamic session. For the moment though, we rely on zero-probability of -such event. -*/ - -class MVVM_MODEL_EXPORT UniqueIdGenerator { -public: - static identifier_type generate(); -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_CORE_UNIQUEIDGENERATOR_H diff --git a/mvvm/model/mvvm/core/variant.h b/mvvm/model/mvvm/core/variant.h deleted file mode 100644 index ac0c2e35cd504964a3930521cc5751a22f9f7903..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/core/variant.h +++ /dev/null @@ -1,25 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/core/variant.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_CORE_VARIANT_H -#define BORNAGAIN_MVVM_MODEL_MVVM_CORE_VARIANT_H - -//! @file mvvm/model/mvvm/core/variant.h -//! Defines variant type (intermediate step toward migration from QVariant to std::variant). - -#include <QVariant> - -using Variant = QVariant; - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_CORE_VARIANT_H diff --git a/mvvm/model/mvvm/core/version.h b/mvvm/model/mvvm/core/version.h deleted file mode 100644 index 758d96a7066b2b58350de1a8d1d2a99ab8ceefc1..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/core/version.h +++ /dev/null @@ -1,55 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/core/version.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_CORE_VERSION_H -#define BORNAGAIN_MVVM_MODEL_MVVM_CORE_VERSION_H - -//! @file mvvm/model/mvvm/core/version.h -//! Automatically generated from mvvm_version.h.in - -#include <string> - -namespace ModelView { - -//! Returns major project version. -inline int ProjectVersionMajor() -{ - const int project_version_major = 0; - return project_version_major; -} - -//! Returns minor project version. -inline int ProjectVersionMinor() -{ - const int project_version_minor = 2; - return project_version_minor; -} - -//! Returns patch project version. -inline int ProjectVersionPatch() -{ - const int project_version_path = 0; - return project_version_path; -} - -//! Returns project version string -inline std::string ProjectVersion() -{ - const std::string project_version = "0.2.0"; - return project_version; -} - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_CORE_VERSION_H diff --git a/mvvm/model/mvvm/factories/CMakeLists.txt b/mvvm/model/mvvm/factories/CMakeLists.txt deleted file mode 100644 index 1730bd52b10726aaba517733a9c138fe04e3d163..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/factories/CMakeLists.txt +++ /dev/null @@ -1,12 +0,0 @@ -target_sources(${library_name} PRIVATE - itemcataloguefactory.cpp - itemcataloguefactory.h - itemconverterfactory.cpp - itemconverterfactory.h - modelconverterfactory.cpp - modelconverterfactory.h - modeldocumentfactory.cpp - modeldocumentfactory.h - projectmanagerfactory.cpp - projectmanagerfactory.h -) diff --git a/mvvm/model/mvvm/factories/itemcataloguefactory.cpp b/mvvm/model/mvvm/factories/itemcataloguefactory.cpp deleted file mode 100644 index 84f6bc95c0f1b361e996fa74571af14dbfa91ce2..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/factories/itemcataloguefactory.cpp +++ /dev/null @@ -1,41 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/factories/itemcataloguefactory.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/factories/itemcataloguefactory.h" -#include "mvvm/standarditems/standarditemincludes.h" - -using namespace ModelView; - -std::unique_ptr<ItemCatalogue> ModelView::CreateStandardItemCatalogue() -{ - auto result = std::make_unique<ItemCatalogue>(); - result->registerItem<ColorMapItem>(); - result->registerItem<ColorMapViewportItem>(); - result->registerItem<CompoundItem>(); - result->registerItem<ContainerItem>(); - result->registerItem<Data1DItem>(); - result->registerItem<Data2DItem>(); - result->registerItem<FixedBinAxisItem>(); - result->registerItem<GraphItem>(); - result->registerItem<GraphViewportItem>(); - result->registerItem<LinkedItem>(); - result->registerItem<PenItem>(); - result->registerItem<PointwiseAxisItem>(); - result->registerItem<PropertyItem>(); - result->registerItem<SessionItem>(); - result->registerItem<TextItem>(); - result->registerItem<VectorItem>(); - result->registerItem<ViewportAxisItem>(); - return result; -} diff --git a/mvvm/model/mvvm/factories/itemcataloguefactory.h b/mvvm/model/mvvm/factories/itemcataloguefactory.h deleted file mode 100644 index cfa0aeed1a33761486c9bdd51d1aa3798c8833b1..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/factories/itemcataloguefactory.h +++ /dev/null @@ -1,27 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/factories/itemcataloguefactory.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_FACTORIES_ITEMCATALOGUEFACTORY_H -#define BORNAGAIN_MVVM_MODEL_MVVM_FACTORIES_ITEMCATALOGUEFACTORY_H - -#include "mvvm/model/itemcatalogue.h" - -namespace ModelView { - -//! Creates a catalog of items supported by SessionModel out-of-the-box. -MVVM_MODEL_EXPORT std::unique_ptr<ItemCatalogue> CreateStandardItemCatalogue(); - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_FACTORIES_ITEMCATALOGUEFACTORY_H diff --git a/mvvm/model/mvvm/factories/itemconverterfactory.cpp b/mvvm/model/mvvm/factories/itemconverterfactory.cpp deleted file mode 100644 index 75145240197584b03cde10430ef9b197fe322935..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/factories/itemconverterfactory.cpp +++ /dev/null @@ -1,59 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/factories/itemconverterfactory.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/factories/itemconverterfactory.h" -#include "mvvm/serialization/jsonitem_types.h" -#include "mvvm/serialization/jsonitemconverter.h" - -namespace ModelView { - -//! Creates JSON item converter intended for item cloning. -//! Saves full deep copy of item to JSON. When restoring from JSON, reconstruct everything, -//! including item's unique ID. Used for backup. - -std::unique_ptr<JsonItemConverterInterface> -CreateItemCloneConverter(const ItemFactoryInterface* item_factory) -{ - ConverterContext context{item_factory, ConverterMode::clone}; - return std::make_unique<JsonItemConverter>(context); -} - -//! Creates JSON item converter intended for item copying. -//! Saves full deep copy of item to JSON. When restoring from JSON, will regenerate item's ID -//! to make it unique. Used for copying of item together with its children. - -std::unique_ptr<JsonItemConverterInterface> -CreateItemCopyConverter(const ItemFactoryInterface* item_factory) -{ - ConverterContext context{item_factory, ConverterMode::copy}; - return std::make_unique<JsonItemConverter>(context); -} - -//! Creates JSON item converter intended for saving on disk. -//! When saving on disk: -//! + Only selected data roles of items are saved (i.e. DATA, IDENTIFIER) -//! + All tags with its content are saved as usual -//! When loading from disk: -//! + Only selected roles are taken from JSON (i.e. DATA, IDENTIFIER), other roles (e.g. TOOLTIPS) -//! are taken from memory. -//! + Property tags are updated, universal tags reconstructed. - -std::unique_ptr<JsonItemConverterInterface> -CreateItemProjectConverter(const ItemFactoryInterface* item_factory) -{ - ConverterContext context{item_factory, ConverterMode::project}; - return std::make_unique<JsonItemConverter>(context); -} - -} // namespace ModelView diff --git a/mvvm/model/mvvm/factories/itemconverterfactory.h b/mvvm/model/mvvm/factories/itemconverterfactory.h deleted file mode 100644 index 57ee5c899da867bea5c8d8d64268b51f2423f927..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/factories/itemconverterfactory.h +++ /dev/null @@ -1,45 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/factories/itemconverterfactory.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_FACTORIES_ITEMCONVERTERFACTORY_H -#define BORNAGAIN_MVVM_MODEL_MVVM_FACTORIES_ITEMCONVERTERFACTORY_H - -//! @file mvvm/model/mvvm/factories/itemconverterfactory.h -//! Collection of factory functions to create SessionItem converters to/from serialized content. - -#include "mvvm/serialization/jsonitemconverterinterface.h" -#include <memory> - -namespace ModelView { - -class ItemFactoryInterface; - -//! Creates JSON item converter intended for item cloning. - -MVVM_MODEL_EXPORT std::unique_ptr<JsonItemConverterInterface> -CreateItemCloneConverter(const ItemFactoryInterface* item_factory); - -//! Creates JSON item converter intended for item copying. - -MVVM_MODEL_EXPORT std::unique_ptr<JsonItemConverterInterface> -CreateItemCopyConverter(const ItemFactoryInterface* item_factory); - -//! Creates JSON item converter intended for saving on disk. - -MVVM_MODEL_EXPORT std::unique_ptr<JsonItemConverterInterface> -CreateItemProjectConverter(const ItemFactoryInterface* item_factory); - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_FACTORIES_ITEMCONVERTERFACTORY_H diff --git a/mvvm/model/mvvm/factories/modelconverterfactory.cpp b/mvvm/model/mvvm/factories/modelconverterfactory.cpp deleted file mode 100644 index d8558fa09017db56cb6eedc9c4d84e52dfca26e4..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/factories/modelconverterfactory.cpp +++ /dev/null @@ -1,45 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/factories/modelconverterfactory.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/factories/modelconverterfactory.h" -#include "mvvm/factories/itemconverterfactory.h" -#include "mvvm/serialization/jsonitem_types.h" -#include "mvvm/serialization/jsonmodelconverter.h" - -//! Creates a JSON model converter intended for model cloning. -//! Saves a full deep copy of model in JSON. When restoring, reconstruct full copy. -//! This will lead to item ID's which are identical to original. - -std::unique_ptr<ModelView::JsonModelConverterInterface> ModelView::CreateModelCloneConverter() -{ - return std::make_unique<JsonModelConverter>(ConverterMode::clone); -} - -//! Creates a JSON model converter intended for model copying. -//! Saves a full deep copy of model in JSON. When restoring, reconstruct full copy and regenerate -//! item's ID to make them unique. - -std::unique_ptr<ModelView::JsonModelConverterInterface> ModelView::CreateModelCopyConverter() -{ - return std::make_unique<JsonModelConverter>(ConverterMode::copy); -} - -//! Creates a JSON model converter intended for save/load of the project on disk. -//! When saving to disk, only certain data is saved. When loading from disk, items -//! in memory is gently updated from JSON content. - -std::unique_ptr<ModelView::JsonModelConverterInterface> ModelView::CreateModelProjectConverter() -{ - return std::make_unique<JsonModelConverter>(ConverterMode::project); -} diff --git a/mvvm/model/mvvm/factories/modelconverterfactory.h b/mvvm/model/mvvm/factories/modelconverterfactory.h deleted file mode 100644 index 8f92735937d6f822fc96e5dee945b188060225d7..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/factories/modelconverterfactory.h +++ /dev/null @@ -1,37 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/factories/modelconverterfactory.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_FACTORIES_MODELCONVERTERFACTORY_H -#define BORNAGAIN_MVVM_MODEL_MVVM_FACTORIES_MODELCONVERTERFACTORY_H - -//! @file mvvm/model/mvvm/factories/modelconverterfactory.h -//! Collection of factory functions to create SessionModel converters to/from serialized content. - -#include "mvvm/serialization/jsonmodelconverterinterface.h" -#include <memory> - -namespace ModelView { - -//! Creates a JSON model converter intended for model cloning. -MVVM_MODEL_EXPORT std::unique_ptr<JsonModelConverterInterface> CreateModelCloneConverter(); - -//! Creates a JSON model converter intended for model copying. -MVVM_MODEL_EXPORT std::unique_ptr<JsonModelConverterInterface> CreateModelCopyConverter(); - -//! Creates a JSON model converter intended for save/load of the project on disk. -MVVM_MODEL_EXPORT std::unique_ptr<JsonModelConverterInterface> CreateModelProjectConverter(); - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_FACTORIES_MODELCONVERTERFACTORY_H diff --git a/mvvm/model/mvvm/factories/modeldocumentfactory.cpp b/mvvm/model/mvvm/factories/modeldocumentfactory.cpp deleted file mode 100644 index 9d6a2a1bff0852c26b7e45eda992547dbe322dd9..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/factories/modeldocumentfactory.cpp +++ /dev/null @@ -1,25 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/factories/modeldocumentfactory.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/factories/modeldocumentfactory.h" -#include "mvvm/serialization/jsondocument.h" - -namespace ModelView { - -std::unique_ptr<ModelDocumentInterface> CreateJsonDocument(const std::vector<SessionModel*>& models) -{ - return std::make_unique<JsonDocument>(models); -} - -} // namespace ModelView diff --git a/mvvm/model/mvvm/factories/modeldocumentfactory.h b/mvvm/model/mvvm/factories/modeldocumentfactory.h deleted file mode 100644 index 5a4a261d3fd1bb0a88a31054a7ab006b23734cab..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/factories/modeldocumentfactory.h +++ /dev/null @@ -1,32 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/factories/modeldocumentfactory.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_FACTORIES_MODELDOCUMENTFACTORY_H -#define BORNAGAIN_MVVM_MODEL_MVVM_FACTORIES_MODELDOCUMENTFACTORY_H - -#include "mvvm/interfaces/modeldocumentinterface.h" -#include <memory> -#include <vector> - -namespace ModelView { - -class SessionModel; - -//! Creates JsonDocument to save and load models. -MVVM_MODEL_EXPORT std::unique_ptr<ModelDocumentInterface> -CreateJsonDocument(const std::vector<SessionModel*>& models); - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_FACTORIES_MODELDOCUMENTFACTORY_H diff --git a/mvvm/model/mvvm/factories/projectmanagerfactory.cpp b/mvvm/model/mvvm/factories/projectmanagerfactory.cpp deleted file mode 100644 index dd579eb4c1d746550454ffc83577f4c822c6833b..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/factories/projectmanagerfactory.cpp +++ /dev/null @@ -1,27 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/factories/projectmanagerfactory.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/factories/projectmanagerfactory.h" -#include "mvvm/project/project_types.h" -#include "mvvm/project/projectmanagerdecorator.h" - -namespace ModelView { -std::unique_ptr<ProjectManagerInterface> -CreateProjectManager(const ProjectContext& project_context, - const UserInteractionContext& user_context) -{ - return std::make_unique<ProjectManagerDecorator>(project_context, user_context); -} - -} // namespace ModelView diff --git a/mvvm/model/mvvm/factories/projectmanagerfactory.h b/mvvm/model/mvvm/factories/projectmanagerfactory.h deleted file mode 100644 index 177dbe6b5ea9fd4f2c041c926d3966baed9960dd..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/factories/projectmanagerfactory.h +++ /dev/null @@ -1,33 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/factories/projectmanagerfactory.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_FACTORIES_PROJECTMANAGERFACTORY_H -#define BORNAGAIN_MVVM_MODEL_MVVM_FACTORIES_PROJECTMANAGERFACTORY_H - -#include "mvvm/interfaces/projectmanagerinterface.h" -#include <memory> - -namespace ModelView { - -struct ProjectContext; -struct UserInteractionContext; - -//! Creates default ProjectManager to save and load models. -MVVM_MODEL_EXPORT std::unique_ptr<ProjectManagerInterface> -CreateProjectManager(const ProjectContext& project_context, - const UserInteractionContext& user_context); - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_FACTORIES_PROJECTMANAGERFACTORY_H diff --git a/mvvm/model/mvvm/interfaces/CMakeLists.txt b/mvvm/model/mvvm/interfaces/CMakeLists.txt deleted file mode 100644 index 569e88432a0c2063c5662772d00800ba6fb12f09..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/interfaces/CMakeLists.txt +++ /dev/null @@ -1,12 +0,0 @@ -target_sources(${library_name} PRIVATE - applicationmodelsinterface.h - itembackupstrategy.h - itemcopystrategy.h - itemfactoryinterface.h - itemlistenerinterface.h - modeldocumentinterface.h - modellistenerinterface.h - projectinterface.h - projectmanagerinterface.h - undostackinterface.h -) diff --git a/mvvm/model/mvvm/interfaces/applicationmodelsinterface.h b/mvvm/model/mvvm/interfaces/applicationmodelsinterface.h deleted file mode 100644 index eceaf9efe2882a733843c07f629bb58bf711ed76..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/interfaces/applicationmodelsinterface.h +++ /dev/null @@ -1,36 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/interfaces/applicationmodelsinterface.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_INTERFACES_APPLICATIONMODELSINTERFACE_H -#define BORNAGAIN_MVVM_MODEL_MVVM_INTERFACES_APPLICATIONMODELSINTERFACE_H - -#include "mvvm/model_export.h" -#include <vector> - -namespace ModelView { - -class SessionModel; - -//! Interface to access application's model list for further manipulation. -//! Used in the context of save/load projects. - -class MVVM_MODEL_EXPORT ApplicationModelsInterface { -public: - //! Returns vector of models intended for saving on disk. - virtual std::vector<SessionModel*> persistent_models() const = 0; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_INTERFACES_APPLICATIONMODELSINTERFACE_H diff --git a/mvvm/model/mvvm/interfaces/itembackupstrategy.h b/mvvm/model/mvvm/interfaces/itembackupstrategy.h deleted file mode 100644 index 770c96b82f1a2fd45b69c195795352a2d70709e8..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/interfaces/itembackupstrategy.h +++ /dev/null @@ -1,40 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/interfaces/itembackupstrategy.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_INTERFACES_ITEMBACKUPSTRATEGY_H -#define BORNAGAIN_MVVM_MODEL_MVVM_INTERFACES_ITEMBACKUPSTRATEGY_H - -#include "mvvm/model_export.h" -#include <memory> - -namespace ModelView { - -class SessionItem; - -//! Interface to backup items for later restore. - -class MVVM_MODEL_EXPORT ItemBackupStrategy { -public: - virtual ~ItemBackupStrategy() = default; - - //! Restore item from saved content. - virtual std::unique_ptr<SessionItem> restoreItem() const = 0; - - //! Save item's content. - virtual void saveItem(const SessionItem*) = 0; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_INTERFACES_ITEMBACKUPSTRATEGY_H diff --git a/mvvm/model/mvvm/interfaces/itemcopystrategy.h b/mvvm/model/mvvm/interfaces/itemcopystrategy.h deleted file mode 100644 index 46831af35f0ae8cbc56beb29024053ef6a0072cb..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/interfaces/itemcopystrategy.h +++ /dev/null @@ -1,37 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/interfaces/itemcopystrategy.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_INTERFACES_ITEMCOPYSTRATEGY_H -#define BORNAGAIN_MVVM_MODEL_MVVM_INTERFACES_ITEMCOPYSTRATEGY_H - -#include "mvvm/model_export.h" -#include <memory> - -namespace ModelView { - -class SessionItem; - -//! Interface for deep item copying. - -class MVVM_MODEL_EXPORT ItemCopyStrategy { -public: - virtual ~ItemCopyStrategy() = default; - - //! Creates item copy by deep copying all children. SessionItem identifiers will be regenerated. - virtual std::unique_ptr<SessionItem> createCopy(const SessionItem* item) const = 0; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_INTERFACES_ITEMCOPYSTRATEGY_H diff --git a/mvvm/model/mvvm/interfaces/itemfactoryinterface.h b/mvvm/model/mvvm/interfaces/itemfactoryinterface.h deleted file mode 100644 index 9c7612bd528469cad4dd59fba12870b6eca0e579..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/interfaces/itemfactoryinterface.h +++ /dev/null @@ -1,41 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/interfaces/itemfactoryinterface.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_INTERFACES_ITEMFACTORYINTERFACE_H -#define BORNAGAIN_MVVM_MODEL_MVVM_INTERFACES_ITEMFACTORYINTERFACE_H - -#include "mvvm/core/types.h" -#include "mvvm/model/function_types.h" -#include "mvvm/model_export.h" -#include <memory> - -namespace ModelView { - -class SessionItem; - -//! Interface class for all factories capable of producing SessionItem's. - -class MVVM_MODEL_EXPORT ItemFactoryInterface { -public: - virtual ~ItemFactoryInterface() = default; - - virtual void registerItem(const std::string& modelType, item_factory_func_t func, - const std::string& label) = 0; - - virtual std::unique_ptr<SessionItem> createItem(const model_type& modelType) const = 0; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_INTERFACES_ITEMFACTORYINTERFACE_H diff --git a/mvvm/model/mvvm/interfaces/itemlistenerinterface.h b/mvvm/model/mvvm/interfaces/itemlistenerinterface.h deleted file mode 100644 index d50bbc4b6d205ed55b8068484d365c57a26ad505..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/interfaces/itemlistenerinterface.h +++ /dev/null @@ -1,74 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/interfaces/itemlistenerinterface.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_INTERFACES_ITEMLISTENERINTERFACE_H -#define BORNAGAIN_MVVM_MODEL_MVVM_INTERFACES_ITEMLISTENERINTERFACE_H - -#include "mvvm/signals/callback_types.h" - -namespace ModelView { - -//! Interface to subscribe to various events happening with specific SessionItem. - -class MVVM_MODEL_EXPORT ItemListenerInterface { -public: - virtual ~ItemListenerInterface() = default; - - virtual void setOnItemDestroy(Callbacks::item_t f, Callbacks::slot_t owner) = 0; - - //! Sets callback to be notified on item's data change. - //! Callback will be called with (SessionItem*, data_role). - - virtual void setOnDataChange(Callbacks::item_int_t f, Callbacks::slot_t owner) = 0; - - //! Sets callback to be notified on item's property change. - //! Callback will be called with (compound_item, property_name). - - virtual void setOnPropertyChange(Callbacks::item_str_t f, Callbacks::slot_t owner) = 0; - - //! Sets callback to be notified on item's children property change. - //! Callback will be called with (compound_item, property_name). For MultiLayer containing the - //! layer with "thickness" property, the signal will be triggered on thickness change using - //! (layeritem*, "thickness") as callback parameters. - - virtual void setOnChildPropertyChange(Callbacks::item_str_t f, Callbacks::slot_t owner) = 0; - - //! Sets callback to be notified on child insertion. - //! Callback will be called with (compound_item, tag, row). For MultiLayer containing the - //! T_LAYERS tag, the signal will be triggered on layer insertion with - //! (multilayer*, {T_LAYER, row}) as callback parameters. - - virtual void setOnItemInserted(Callbacks::item_tagrow_t f, Callbacks::slot_t owner) = 0; - - //! Sets callback to be notified on child removal. - //! Callback will be called with (compound_item, tag, row). For MultiLayer containing the - //! T_LAYERS tag, the signal will be triggered on layer removal with - //! (multilayer*, {T_LAYER, oldrow}) as callback parameters. - - virtual void setOnItemRemoved(Callbacks::item_tagrow_t f, Callbacks::slot_t owner) = 0; - - //! Sets callback to be notified when row is about to be removed. - //! Callback will be called with (compound_item, tagrow). For MultiLayer containing the - //! T_LAYERS tag, the signal will be triggered on layer deletion with - //! (multilayer*, {T_LAYER, row}) as callback parameters. - - virtual void setOnAboutToRemoveItem(Callbacks::item_tagrow_t f, Callbacks::slot_t owner) = 0; - - //! Removes given client from all subscriptions. - virtual void unsubscribe(Callbacks::slot_t client) = 0; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_INTERFACES_ITEMLISTENERINTERFACE_H diff --git a/mvvm/model/mvvm/interfaces/modeldocumentinterface.h b/mvvm/model/mvvm/interfaces/modeldocumentinterface.h deleted file mode 100644 index 86b93caf130262576943e64c4928beda8dbdb988..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/interfaces/modeldocumentinterface.h +++ /dev/null @@ -1,35 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/interfaces/modeldocumentinterface.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_INTERFACES_MODELDOCUMENTINTERFACE_H -#define BORNAGAIN_MVVM_MODEL_MVVM_INTERFACES_MODELDOCUMENTINTERFACE_H - -#include "mvvm/model_export.h" -#include <string> - -namespace ModelView { - -//! Pure virtual interface to save and restore session models to/from disk. - -class MVVM_MODEL_EXPORT ModelDocumentInterface { -public: - virtual ~ModelDocumentInterface() = default; - - virtual void save(const std::string& file_name) const = 0; - virtual void load(const std::string& file_name) = 0; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_INTERFACES_MODELDOCUMENTINTERFACE_H diff --git a/mvvm/model/mvvm/interfaces/modellistenerinterface.h b/mvvm/model/mvvm/interfaces/modellistenerinterface.h deleted file mode 100644 index 580a6f957710a92e6453ab6379c5fee274c6651e..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/interfaces/modellistenerinterface.h +++ /dev/null @@ -1,60 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/interfaces/modellistenerinterface.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_INTERFACES_MODELLISTENERINTERFACE_H -#define BORNAGAIN_MVVM_MODEL_MVVM_INTERFACES_MODELLISTENERINTERFACE_H - -#include "mvvm/signals/callback_types.h" - -namespace ModelView { - -//! Interface to subscribe to various signals generated by SessionModel. - -class MVVM_MODEL_EXPORT ModelListenerInterface { -public: - virtual ~ModelListenerInterface() = default; - - //! Sets callback to be notified on item's data change. The callback will be called - //! with (SessionItem*, data_role). - virtual void setOnDataChange(Callbacks::item_int_t f, Callbacks::slot_t client) = 0; - - //! Sets callback to be notified on item insert. The callback will be called with - //! (SessionItem* parent, tagrow), where 'tagrow' denotes inserted child position. - virtual void setOnItemInserted(Callbacks::item_tagrow_t f, Callbacks::slot_t client) = 0; - - //! Sets callback to be notified on item remove. The callback will be called with - //! (SessionItem* parent, tagrow), where 'tagrow' denotes child position before the removal. - virtual void setOnItemRemoved(Callbacks::item_tagrow_t f, Callbacks::slot_t client) = 0; - - //! Sets callback to be notified when the item is about to be removed. The callback will be - //! called with (SessionItem* parent, tagrow), where 'tagrow' denotes child position being - //! removed. - virtual void setOnAboutToRemoveItem(Callbacks::item_tagrow_t f, Callbacks::slot_t client) = 0; - - //! Sets the callback for notifications on model destruction. - virtual void setOnModelDestroyed(Callbacks::model_t f, Callbacks::slot_t client) = 0; - - //! Sets the callback to be notified just before the reset of the root item. - virtual void setOnModelAboutToBeReset(Callbacks::model_t f, Callbacks::slot_t client) = 0; - - //! Sets the callback to be notified right after the root item recreation. - virtual void setOnModelReset(Callbacks::model_t f, Callbacks::slot_t client) = 0; - - //! Removes given client from all subscriptions. - virtual void unsubscribe(Callbacks::slot_t client) = 0; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_INTERFACES_MODELLISTENERINTERFACE_H diff --git a/mvvm/model/mvvm/interfaces/projectinterface.h b/mvvm/model/mvvm/interfaces/projectinterface.h deleted file mode 100644 index dd06efbd4024684f81a058ba47e0fb310a2de722..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/interfaces/projectinterface.h +++ /dev/null @@ -1,37 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/interfaces/projectinterface.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_INTERFACES_PROJECTINTERFACE_H -#define BORNAGAIN_MVVM_MODEL_MVVM_INTERFACES_PROJECTINTERFACE_H - -#include "mvvm/model_export.h" -#include <string> - -namespace ModelView { - -//! Interface to manipulate projects on disk. -//! Project represents content of all application models in a folder on disk. - -class MVVM_MODEL_EXPORT ProjectInterface { -public: - virtual ~ProjectInterface() = default; - virtual std::string projectDir() const = 0; - virtual bool save(const std::string& dirname) const = 0; - virtual bool load(const std::string& dirname) = 0; - virtual bool isModified() const = 0; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_INTERFACES_PROJECTINTERFACE_H diff --git a/mvvm/model/mvvm/interfaces/projectmanagerinterface.h b/mvvm/model/mvvm/interfaces/projectmanagerinterface.h deleted file mode 100644 index 187458ac3d144cd0bcc1174817c26a6d4a24e47d..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/interfaces/projectmanagerinterface.h +++ /dev/null @@ -1,48 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/interfaces/projectmanagerinterface.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_INTERFACES_PROJECTMANAGERINTERFACE_H -#define BORNAGAIN_MVVM_MODEL_MVVM_INTERFACES_PROJECTMANAGERINTERFACE_H - -#include "mvvm/model_export.h" -#include <string> - -namespace ModelView { - -//! Interface class for ProjectManager family. - -//! Responsible for handling new/save/save-as/close Project logic, where the Project represents -//! a collection of serialized application models in the project directory. - -class MVVM_MODEL_EXPORT ProjectManagerInterface { -public: - virtual ~ProjectManagerInterface() = default; - virtual bool createNewProject(const std::string& dirname = {}) = 0; - - virtual bool saveCurrentProject() = 0; - - virtual bool saveProjectAs(const std::string& dirname = {}) = 0; - - virtual bool openExistingProject(const std::string& dirname = {}) = 0; - - virtual std::string currentProjectDir() const = 0; - - virtual bool isModified() const = 0; - - virtual bool closeCurrentProject() const = 0; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_INTERFACES_PROJECTMANAGERINTERFACE_H diff --git a/mvvm/model/mvvm/interfaces/undostackinterface.h b/mvvm/model/mvvm/interfaces/undostackinterface.h deleted file mode 100644 index 802d01d4afc82c7d1fa87915272c9914aae813f0..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/interfaces/undostackinterface.h +++ /dev/null @@ -1,56 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/interfaces/undostackinterface.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_INTERFACES_UNDOSTACKINTERFACE_H -#define BORNAGAIN_MVVM_MODEL_MVVM_INTERFACES_UNDOSTACKINTERFACE_H - -#include <memory> -#include <string> - -class QUndoCommand; - -namespace ModelView { - -class AbstractItemCommand; - -//! Interface class for undo/redo stack. - -class UndoStackInterface { -public: - virtual ~UndoStackInterface() = default; - - //! Executes the command, then pushes it in the stack for possible undo. - //! Current design relies on shared pointer. This is done - //! a) to retrieve result of the command from another place - //! b) to adapt the command for QUndoStack - //! c) to bypass QUndoStack behavior which wants to have an ownership - virtual void execute(std::shared_ptr<AbstractItemCommand> command) = 0; - - virtual bool isActive() const = 0; - virtual bool canUndo() const = 0; - virtual bool canRedo() const = 0; - virtual int index() const = 0; - virtual int count() const = 0; - virtual void undo() = 0; - virtual void redo() = 0; - virtual void clear() = 0; - virtual void setUndoLimit(int limit) = 0; - - virtual void beginMacro(const std::string& name) = 0; - virtual void endMacro() = 0; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_INTERFACES_UNDOSTACKINTERFACE_H diff --git a/mvvm/model/mvvm/model/CMakeLists.txt b/mvvm/model/mvvm/model/CMakeLists.txt deleted file mode 100644 index 0356baaaec18fd2898719aa4b92f513fad27ff24..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/model/CMakeLists.txt +++ /dev/null @@ -1,49 +0,0 @@ -target_sources(${library_name} PRIVATE - comboproperty.cpp - comboproperty.h - comparators.cpp - comparators.h - compounditem.cpp - compounditem.h - customvariants.cpp - customvariants.h - datarole.cpp - datarole.h - externalproperty.cpp - externalproperty.h - function_types.h - groupitem.cpp - groupitem.h - itemcatalogue.cpp - itemcatalogue.h - itemfactory.cpp - itemfactory.h - itemmanager.cpp - itemmanager.h - itempool.cpp - itempool.h - itemutils.cpp - itemutils.h - modelutils.cpp - modelutils.h - mvvm_types.h - path.cpp - path.h - propertyitem.cpp - propertyitem.h - sessionitem.cpp - sessionitem.h - sessionitemcontainer.cpp - sessionitemcontainer.h - sessionitemdata.cpp - sessionitemdata.h - sessionitemtags.cpp - sessionitemtags.h - sessionmodel.cpp - sessionmodel.h - taginfo.cpp - taginfo.h - tagrow.cpp - tagrow.h - variant_constants.h -) diff --git a/mvvm/model/mvvm/model/comboproperty.cpp b/mvvm/model/mvvm/model/comboproperty.cpp deleted file mode 100644 index 33ee40a0e8208f553753a410dee3e28797a11d07..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/model/comboproperty.cpp +++ /dev/null @@ -1,257 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/model/comboproperty.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/model/comboproperty.h" -#include "mvvm/utils/containerutils.h" -#include <sstream> -#include <stdexcept> - -namespace { -const std::string value_separator = ";"; -const std::string selection_separator = ","; -const std::string multiple_label = "Multiple"; -const std::string none_label = "None"; - -template <typename C, typename T> std::string toString(const C& container, const T& delim) -{ - std::stringstream result; - for (auto it = container.begin(); it != container.end(); ++it) { - result << *it; - if (std::distance(it, container.end()) != 1) - result << delim; - } - return result.str(); -} - -std::vector<std::string> tokenize(const std::string& str, const std::string& delimeter) -{ - std::vector<std::string> result; - size_t start = str.find_first_not_of(delimeter); - size_t end = start; - - while (start != std::string::npos) { - // Find next occurence of delimiter - end = str.find(delimeter, start); - // Push back the token found into vector - result.push_back(str.substr(start, end - start)); - // Skip all occurences of the delimiter to find new start - start = str.find_first_not_of(delimeter, end); - } - return result; -} -} // namespace - -using namespace ModelView; - -ComboProperty::ComboProperty() = default; - -ComboProperty::ComboProperty(std::vector<std::string> values) : m_values(std::move(values)) {} - -ComboProperty ComboProperty::createFrom(const std::vector<std::string>& values, - const std::string& current_value) -{ - ComboProperty result(values); - - if (!current_value.empty()) - result.setValue(current_value); - else - result.setCurrentIndex(0); - - return result; -} - -std::string ComboProperty::value() const -{ - return currentIndex() < 0 ? "" : m_values.at(static_cast<size_t>(currentIndex())); -} - -void ComboProperty::setValue(const std::string& name) -{ - if (!Utils::Contains(m_values, name)) - throw std::runtime_error("ComboProperty::setValue() -> Error. Combo doesn't contain " - "value " - + name); - setCurrentIndex(Utils::IndexOfItem(m_values, name)); -} - -std::vector<std::string> ComboProperty::values() const -{ - return m_values; -} - -//! Sets new list of values. Current value will be preserved, if exists in a new list. - -void ComboProperty::setValues(const std::vector<std::string>& values) -{ - if (values.empty()) - return; - - auto current = value(); - m_values = values; - setCurrentIndex(Utils::Contains(m_values, current) ? Utils::IndexOfItem(m_values, current) : 0); -} - -//! returns list of tool tips for all values -std::vector<std::string> ComboProperty::toolTips() const -{ - return m_tooltips; -} - -void ComboProperty::setToolTips(const std::vector<std::string>& tooltips) -{ - m_tooltips = tooltips; -} - -int ComboProperty::currentIndex() const -{ - return m_selected_indices.empty() ? -1 : m_selected_indices.at(0); -} - -void ComboProperty::setCurrentIndex(int index) -{ - if (index < 0 || index >= static_cast<int>(m_values.size())) - throw std::runtime_error("ComboProperty::setCurrentIndex(int index) -> Error. " - "Invalid index"); - m_selected_indices.clear(); - m_selected_indices.push_back(index); -} - -ComboProperty& ComboProperty::operator<<(const std::string& str) -{ - m_values.push_back(str); - if (currentIndex() == -1) - setCurrentIndex(0); - return *this; -} - -ComboProperty& ComboProperty::operator<<(const std::vector<std::string>& str) -{ - m_values.insert(m_values.end(), str.begin(), str.end()); - if (currentIndex() == -1) - setCurrentIndex(0); - return *this; -} - -bool ComboProperty::operator==(const ComboProperty& other) const -{ - if (m_selected_indices != other.m_selected_indices) - return false; - if (m_values != other.m_values) - return false; - return true; -} - -bool ComboProperty::operator!=(const ComboProperty& other) const -{ - return !(*this == other); -} - -bool ComboProperty::operator<(const ComboProperty& other) const -{ - return m_selected_indices < other.m_selected_indices && m_values < other.m_values; -} - -//! Returns a single string containing values delimited with ';'. - -std::string ComboProperty::stringOfValues() const -{ - return toString(m_values, value_separator); -} - -//! Sets values from the string containing delimeter ';'. - -void ComboProperty::setStringOfValues(const std::string& values) -{ - auto current = value(); - m_values = tokenize(values, value_separator); - setCurrentIndex(Utils::Contains(m_values, current) ? Utils::IndexOfItem(m_values, current) : 0); -} - -//! Returns vector of selected indices. - -std::vector<int> ComboProperty::selectedIndices() const -{ - return m_selected_indices; -} - -//! Returns list of string with selected values; - -std::vector<std::string> ComboProperty::selectedValues() const -{ - std::vector<std::string> result; - for (auto index : m_selected_indices) - result.push_back(m_values.at(static_cast<size_t>(index))); - return result; -} - -//! Sets given index selection flag. -//! If false, index will be excluded from selection. - -void ComboProperty::setSelected(int index, bool value) -{ - if (index < 0 || index >= static_cast<int>(m_values.size())) - return; - - auto pos = find(m_selected_indices.begin(), m_selected_indices.end(), index); - if (value) { - if (pos == m_selected_indices.end()) - m_selected_indices.push_back(index); - } else { - if (pos != m_selected_indices.end()) - m_selected_indices.erase(pos); - } - std::sort(m_selected_indices.begin(), m_selected_indices.end()); -} - -void ComboProperty::setSelected(const std::string& name, bool value) -{ - setSelected(Utils::IndexOfItem(m_values, name), value); -} - -//! Return string with coma separated list of selected indices. - -std::string ComboProperty::stringOfSelections() const -{ - std::vector<std::string> text; - for (auto index : m_selected_indices) - text.push_back(std::to_string(index)); - return toString(text, selection_separator); -} - -//! Sets selected indices from string. - -void ComboProperty::setStringOfSelections(const std::string& values) -{ - m_selected_indices.clear(); - if (values.empty()) - return; - - for (const auto& str : tokenize(values, selection_separator)) { - int num = std::stoi(str); - setSelected(num, true); - } -} - -//! Returns the label to show. - -std::string ComboProperty::label() const -{ - if (m_selected_indices.size() > 1) { - return multiple_label; - } else if (m_selected_indices.size() == 1) { - return value(); - } else { - return none_label; - } -} diff --git a/mvvm/model/mvvm/model/comboproperty.h b/mvvm/model/mvvm/model/comboproperty.h deleted file mode 100644 index 39d309ce84816cdb5e689025f5e75150ce736ae6..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/model/comboproperty.h +++ /dev/null @@ -1,78 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/model/comboproperty.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_MODEL_COMBOPROPERTY_H -#define BORNAGAIN_MVVM_MODEL_MVVM_MODEL_COMBOPROPERTY_H - -#include "mvvm/core/variant.h" -#include "mvvm/model_export.h" -#include <string> -#include <vector> - -namespace ModelView { - -//! Custom property to define list of string values with multiple selections. - -class MVVM_MODEL_EXPORT ComboProperty { -public: - ComboProperty(); - - static ComboProperty createFrom(const std::vector<std::string>& values, - const std::string& current_value = {}); - - std::string value() const; - void setValue(const std::string& name); - - std::vector<std::string> values() const; - void setValues(const std::vector<std::string>& values); - - std::vector<std::string> toolTips() const; - void setToolTips(const std::vector<std::string>& tooltips); - - int currentIndex() const; - void setCurrentIndex(int index); - - ComboProperty& operator<<(const std::string& str); - ComboProperty& operator<<(const std::vector<std::string>& str); - bool operator==(const ComboProperty& other) const; - bool operator!=(const ComboProperty& other) const; - bool operator<(const ComboProperty& other) const; - - std::string stringOfValues() const; - void setStringOfValues(const std::string& values); - - std::vector<int> selectedIndices() const; - std::vector<std::string> selectedValues() const; - - void setSelected(int index, bool value = true); - void setSelected(const std::string& name, bool value = true); - - std::string stringOfSelections() const; - void setStringOfSelections(const std::string& values); - - std::string label() const; - -private: - ComboProperty(std::vector<std::string> values); - - std::vector<std::string> m_values; - std::vector<std::string> m_tooltips; - std::vector<int> m_selected_indices; -}; - -} // namespace ModelView - -Q_DECLARE_METATYPE(ModelView::ComboProperty) - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_MODEL_COMBOPROPERTY_H diff --git a/mvvm/model/mvvm/model/comparators.cpp b/mvvm/model/mvvm/model/comparators.cpp deleted file mode 100644 index acbeefad7dc58c291c29341aa92c5edf323a8188..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/model/comparators.cpp +++ /dev/null @@ -1,41 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/model/comparators.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/model/comparators.h" -#include "mvvm/model/comboproperty.h" -#include "mvvm/model/customvariants.h" -#include "mvvm/model/externalproperty.h" -#include "mvvm/utils/reallimits.h" -#include <QMetaType> - -using namespace ModelView; - -bool Comparators::m_is_registered = false; - -void Comparators::registerComparators() -{ - if (!m_is_registered) { - QMetaType::registerComparators<std::string>(); - QMetaType::registerComparators<std::vector<double>>(); - QMetaType::registerComparators<ComboProperty>(); - QMetaType::registerComparators<ExternalProperty>(); - QMetaType::registerComparators<RealLimits>(); - m_is_registered = true; - } -} - -bool Comparators::registered() -{ - return m_is_registered; -} diff --git a/mvvm/model/mvvm/model/comparators.h b/mvvm/model/mvvm/model/comparators.h deleted file mode 100644 index e67a89b055c006fe8a91017a5e861f8646fc6e55..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/model/comparators.h +++ /dev/null @@ -1,35 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/model/comparators.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_MODEL_COMPARATORS_H -#define BORNAGAIN_MVVM_MODEL_MVVM_MODEL_COMPARATORS_H - -#include "mvvm/model_export.h" - -namespace ModelView { - -//! Helper class to register variant comparators. - -class MVVM_MODEL_EXPORT Comparators { -public: - static void registerComparators(); - static bool registered(); - -private: - static bool m_is_registered; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_MODEL_COMPARATORS_H diff --git a/mvvm/model/mvvm/model/compounditem.cpp b/mvvm/model/mvvm/model/compounditem.cpp deleted file mode 100644 index c7b5161688515cc881a4571857c850fdef1d014f..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/model/compounditem.cpp +++ /dev/null @@ -1,37 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/model/compounditem.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/model/compounditem.h" -#include "mvvm/model/itemutils.h" - -using namespace ModelView; - -namespace { -bool has_custom_display_name(const SessionItem* item) -{ - return item->SessionItem::displayName() != item->modelType(); -} -} // namespace - -CompoundItem::CompoundItem(const std::string& modelType) : SessionItem(modelType) {} - -std::string CompoundItem::displayName() const -{ - if (has_custom_display_name(this)) - return SessionItem::displayName(); - - int copy_number = Utils::CopyNumber(this); - return copy_number != -1 ? SessionItem::displayName() + std::to_string(copy_number) - : SessionItem::displayName(); -} diff --git a/mvvm/model/mvvm/model/compounditem.h b/mvvm/model/mvvm/model/compounditem.h deleted file mode 100644 index 25a09ff28f2407e0c8b1bf08eb5b31e14af0bcaf..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/model/compounditem.h +++ /dev/null @@ -1,74 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/model/compounditem.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_MODEL_COMPOUNDITEM_H -#define BORNAGAIN_MVVM_MODEL_MVVM_MODEL_COMPOUNDITEM_H - -#include "mvvm/model/customvariants.h" -#include "mvvm/model/propertyitem.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/model/taginfo.h" -#include "mvvm/utils/reallimits.h" - -namespace ModelView { - -//! Complex item holding mixed SessionItem types (single properties and other CompountItems). - -class MVVM_MODEL_EXPORT CompoundItem : public SessionItem { -public: - CompoundItem(const std::string& modelType = GUI::Constants::CompoundItemType); - - //! Adds property item of given type. - template <typename T = PropertyItem> T* addProperty(const std::string& name); - - template <typename V> PropertyItem* addProperty(const std::string& name, const V& value); - - //! Register char property. Special case to turn it into std::string. - PropertyItem* addProperty(const std::string& name, const char* value); - - std::string displayName() const override; -}; - -template <typename T> T* CompoundItem::addProperty(const std::string& name) -{ - T* property = new T; - registerTag(TagInfo::propertyTag(name, property->modelType())); - property->setDisplayName(name); - insertItem(property, {name, 0}); - return property; -} - -inline PropertyItem* CompoundItem::addProperty(const std::string& name, const char* value) -{ - return addProperty(name, std::string(value)); -} - -template <typename V> -PropertyItem* CompoundItem::addProperty(const std::string& name, const V& value) -{ - auto property = new PropertyItem; - registerTag(TagInfo::propertyTag(name, property->modelType())); - property->setDisplayName(name); - property->setData(value); - - if constexpr (std::is_floating_point_v<V>) - property->setData(RealLimits::limitless(), ItemDataRole::LIMITS); - - insertItem(property, {name, 0}); - return property; -} - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_MODEL_COMPOUNDITEM_H diff --git a/mvvm/model/mvvm/model/customvariants.cpp b/mvvm/model/mvvm/model/customvariants.cpp deleted file mode 100644 index e218be97430915834a7a6e14c4e9f5dc46375a02..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/model/customvariants.cpp +++ /dev/null @@ -1,135 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/model/customvariants.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/model/customvariants.h" -#include "mvvm/model/comboproperty.h" -#include "mvvm/model/externalproperty.h" -#include "mvvm/model/variant_constants.h" - -namespace { -const QString qstring_name = "QString"; -} - -using namespace ModelView; - -std::string Utils::VariantName(const Variant& variant) -{ - return variant.isValid() ? variant.typeName() : GUI::Constants::invalid_type_name; -} - -int Utils::VariantType(const Variant& variant) -{ - auto result = static_cast<int>(variant.type()); - if (result == Variant::UserType) - result = variant.userType(); - return result; -} - -bool Utils::CompatibleVariantTypes(const Variant& oldValue, const Variant& newValue) -{ - // Invalid variant can be rewritten by any variant. - // Valid Variant can be replaced by invalid variant. - // In other cases types of variants should coincide to be compatible. - - if (!oldValue.isValid() || !newValue.isValid()) - return true; - - return Utils::VariantType(oldValue) == Utils::VariantType(newValue); -} - -bool Utils::IsTheSame(const Variant& var1, const Variant& var2) -{ - // variants of different type are always reported as not the same - if (VariantType(var1) != VariantType(var2)) - return false; - - // variants of same type are compared by value - return var1 == var2; -} - -Variant Utils::toQtVariant(const Variant& custom) -{ - if (!custom.isValid()) - return custom; - - // converts variant based on std::string to variant based on QString - if (custom.typeName() == GUI::Constants::string_type_name) { - return Variant(QString::fromStdString(custom.value<std::string>())); - } else if (IsDoubleVectorVariant(custom)) { - QString str = - QString("vector of %1 elements").arg(custom.value<std::vector<double>>().size()); - return Variant(str); - } - - // in other cases returns unchanged variant - return custom; -} - -Variant Utils::toCustomVariant(const Variant& standard) -{ - if (!standard.isValid()) - return standard; - - // converts variant based on std::string to variant based on QString - if (standard.typeName() == qstring_name) - return Variant::fromValue(standard.toString().toStdString()); - - // in other cases returns unchanged variant - return standard; -} - -bool Utils::IsBoolVariant(const Variant& variant) -{ - return variant.type() == Variant::Bool; -} - -bool Utils::IsIntVariant(const Variant& variant) -{ - return variant.type() == Variant::Int; -} - -bool Utils::IsDoubleVariant(const Variant& variant) -{ - return variant.type() == Variant::Double; -} - -bool Utils::IsComboVariant(const Variant& variant) -{ - return variant.canConvert<ComboProperty>(); -} - -bool Utils::IsStdStringVariant(const Variant& variant) -{ - return variant.canConvert<std::string>(); -} - -bool Utils::IsDoubleVectorVariant(const Variant& variant) -{ - return variant.typeName() == GUI::Constants::vector_double_type_name; -} - -bool Utils::IsColorVariant(const Variant& variant) -{ - return variant.type() == Variant::Color; -} - -bool Utils::IsExtPropertyVariant(const Variant& variant) -{ - return variant.canConvert<ExternalProperty>(); -} - -bool Utils::IsRealLimitsVariant(const Variant& variant) -{ - return variant.canConvert<RealLimits>(); -} diff --git a/mvvm/model/mvvm/model/customvariants.h b/mvvm/model/mvvm/model/customvariants.h deleted file mode 100644 index 5b53cc908b7463bd3f0cf64cba4d9a2ff646e87a..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/model/customvariants.h +++ /dev/null @@ -1,81 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/model/customvariants.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_MODEL_CUSTOMVARIANTS_H -#define BORNAGAIN_MVVM_MODEL_MVVM_MODEL_CUSTOMVARIANTS_H - -//! @file mvvm/model/mvvm/model/customvariants.h -//! Registrations and translations for custom variants. - -#include "mvvm/core/variant.h" -#include "mvvm/model_export.h" -#include "mvvm/utils/reallimits.h" -#include <QMetaType> -#include <string> -#include <vector> - -namespace ModelView::Utils { - -//! Returns name of variant. -MVVM_MODEL_EXPORT std::string VariantName(const Variant& variant); - -//! Returns type of variant (additionally checks for user type). -MVVM_MODEL_EXPORT int VariantType(const Variant& variant); - -//! Returns true if variants has compatible types. -MVVM_MODEL_EXPORT bool CompatibleVariantTypes(const Variant& oldValue, const Variant& newValue); - -//! Returns true if given variants have same type and value. -MVVM_MODEL_EXPORT bool IsTheSame(const Variant& var1, const Variant& var2); - -//! Converts custom variant to standard variant which Qt views will understand. -MVVM_MODEL_EXPORT Variant toQtVariant(const Variant& custom); - -//! Converts Qt variant to custom variant on board of SessionItem. -MVVM_MODEL_EXPORT Variant toCustomVariant(const Variant& standard); - -//! Returns true in the case of double value based variant. -MVVM_MODEL_EXPORT bool IsBoolVariant(const Variant& variant); - -//! Returns true in the case of double value based variant. -MVVM_MODEL_EXPORT bool IsIntVariant(const Variant& variant); - -//! Returns true in the case of double value based variant. -MVVM_MODEL_EXPORT bool IsDoubleVariant(const Variant& variant); - -//! Returns true in the case of double value based variant. -MVVM_MODEL_EXPORT bool IsComboVariant(const Variant& variant); - -//! Returns true in the case of double value based variant. -MVVM_MODEL_EXPORT bool IsStdStringVariant(const Variant& variant); - -//! Returns true in the case of variant based on std::vector<double>. -MVVM_MODEL_EXPORT bool IsDoubleVectorVariant(const Variant& variant); - -//! Returns true in the case of QColor based variant. -MVVM_MODEL_EXPORT bool IsColorVariant(const Variant& variant); - -//! Returns true in the case of ExternalProperty based variant. -MVVM_MODEL_EXPORT bool IsExtPropertyVariant(const Variant& variant); - -//! Returns true in the case of RealLimits based variant. -MVVM_MODEL_EXPORT bool IsRealLimitsVariant(const Variant& variant); - -} // namespace ModelView::Utils - -Q_DECLARE_METATYPE(std::string) -Q_DECLARE_METATYPE(std::vector<double>) -Q_DECLARE_METATYPE(ModelView::RealLimits) - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_MODEL_CUSTOMVARIANTS_H diff --git a/mvvm/model/mvvm/model/datarole.cpp b/mvvm/model/mvvm/model/datarole.cpp deleted file mode 100644 index 6e3b7785b82fbb224899cc28d7527438efb77c08..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/model/datarole.cpp +++ /dev/null @@ -1,25 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/model/datarole.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/model/datarole.h" -#include "mvvm/model/customvariants.h" - -using namespace ModelView; - -DataRole::DataRole(Variant data, int role) : m_data(std::move(data)), m_role(role) {} - -bool DataRole::operator==(const DataRole& other) const -{ - return m_role == other.m_role && Utils::IsTheSame(m_data, other.m_data); -} diff --git a/mvvm/model/mvvm/model/datarole.h b/mvvm/model/mvvm/model/datarole.h deleted file mode 100644 index c0c01f616674a4125da9bd7d9ecdb4e839503b0c..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/model/datarole.h +++ /dev/null @@ -1,35 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/model/datarole.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_MODEL_DATAROLE_H -#define BORNAGAIN_MVVM_MODEL_MVVM_MODEL_DATAROLE_H - -#include "mvvm/core/variant.h" -#include "mvvm/model_export.h" - -namespace ModelView { - -//! Represents pair of data,role for SessionItemData. - -class MVVM_MODEL_EXPORT DataRole { -public: - DataRole(Variant data = Variant(), int role = -1); - Variant m_data; - int m_role; - bool operator==(const DataRole& other) const; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_MODEL_DATAROLE_H diff --git a/mvvm/model/mvvm/model/externalproperty.cpp b/mvvm/model/mvvm/model/externalproperty.cpp deleted file mode 100644 index b8e6d0d5956ea2519e283645d8011f1e56cbbe25..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/model/externalproperty.cpp +++ /dev/null @@ -1,65 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/model/externalproperty.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/model/externalproperty.h" - -using namespace ModelView; - -ExternalProperty::ExternalProperty() = default; - -ExternalProperty::ExternalProperty(std::string text, QColor color, std::string id) - : m_text(std::move(text)), m_color(std::move(color)), m_identifier(std::move(id)) -{ -} - -ExternalProperty ExternalProperty::undefined() -{ - return ExternalProperty("Undefined", QColor(Qt::red)); -} - -std::string ExternalProperty::text() const -{ - return m_text; -} - -QColor ExternalProperty::color() const -{ - return m_color; -} - -std::string ExternalProperty::identifier() const -{ - return m_identifier; -} - -bool ExternalProperty::isValid() const -{ - return !(m_identifier.empty() && m_text.empty() && !m_color.isValid()); -} - -bool ExternalProperty::operator==(const ExternalProperty& other) const -{ - return m_identifier == other.m_identifier && m_text == other.m_text && m_color == other.m_color; -} - -bool ExternalProperty::operator!=(const ExternalProperty& other) const -{ - return !(*this == other); -} - -bool ExternalProperty::operator<(const ExternalProperty& other) const -{ - return m_identifier < other.m_identifier && m_text < other.m_text - && m_color.name() < other.m_color.name(); -} diff --git a/mvvm/model/mvvm/model/externalproperty.h b/mvvm/model/mvvm/model/externalproperty.h deleted file mode 100644 index 79643d0562bb995e7b782d703a7c0a514cd5250b..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/model/externalproperty.h +++ /dev/null @@ -1,57 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/model/externalproperty.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_MODEL_EXTERNALPROPERTY_H -#define BORNAGAIN_MVVM_MODEL_MVVM_MODEL_EXTERNALPROPERTY_H - -#include "mvvm/core/variant.h" -#include "mvvm/model_export.h" -#include <QColor> -#include <string> - -namespace ModelView { - -//! Property to carry text, color and identifier. -//! Can be used to link items with each other. - -class MVVM_MODEL_EXPORT ExternalProperty { -public: - ExternalProperty(); - ExternalProperty(std::string text, QColor color, std::string id = {}); - - static ExternalProperty undefined(); - - std::string text() const; - - QColor color() const; - - std::string identifier() const; - - bool isValid() const; - - bool operator==(const ExternalProperty& other) const; - bool operator!=(const ExternalProperty& other) const; - bool operator<(const ExternalProperty& other) const; - -private: - std::string m_text; - QColor m_color; - std::string m_identifier; -}; - -} // namespace ModelView - -Q_DECLARE_METATYPE(ModelView::ExternalProperty) - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_MODEL_EXTERNALPROPERTY_H diff --git a/mvvm/model/mvvm/model/function_types.h b/mvvm/model/mvvm/model/function_types.h deleted file mode 100644 index c515a5e9a5045e41f56183acbd6f91e5a423c09c..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/model/function_types.h +++ /dev/null @@ -1,36 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/model/function_types.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_MODEL_FUNCTION_TYPES_H -#define BORNAGAIN_MVVM_MODEL_MVVM_MODEL_FUNCTION_TYPES_H - -#include <functional> -#include <memory> - -namespace ModelView { - -class SessionItem; - -//! Definition for item factory funciton. -using item_factory_func_t = std::function<std::unique_ptr<SessionItem>()>; - -//! Creates factory function for item of specific type. -template <typename T> item_factory_func_t ItemFactoryFunction() -{ - return []() { return std::make_unique<T>(); }; -} - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_MODEL_FUNCTION_TYPES_H diff --git a/mvvm/model/mvvm/model/groupitem.cpp b/mvvm/model/mvvm/model/groupitem.cpp deleted file mode 100644 index dd1d0ceec0d7da8130af4b5cac91e948382ac36a..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/model/groupitem.cpp +++ /dev/null @@ -1,92 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/model/groupitem.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/model/groupitem.h" -#include "mvvm/model/comboproperty.h" -#include "mvvm/model/taginfo.h" -#include "mvvm/utils/containerutils.h" -#include <stdexcept> - -using namespace ModelView; - -GroupItem::~GroupItem() = default; - -GroupItem::GroupItem(model_type modelType) - : SessionItem(std::move(modelType)) - , m_catalogue(std::make_unique<ItemCatalogue>()) - , m_default_selected_index(0) -{ - registerTag(TagInfo::universalTag(T_GROUP_ITEMS), /*set_as_default*/ true); - setData(ComboProperty()); -} - -int GroupItem::currentIndex() const -{ - return data<ComboProperty>().currentIndex(); -} - -//! Returns currently selected item. - -const SessionItem* GroupItem::currentItem() const -{ - return is_valid_index() ? getItem("", currentIndex()) : nullptr; -} - -SessionItem* GroupItem::currentItem() -{ - return const_cast<SessionItem*>(static_cast<const GroupItem*>(this)->currentItem()); -} - -std::string GroupItem::currentType() const -{ - return is_valid_index() ? m_catalogue->modelTypes()[static_cast<size_t>(currentIndex())] : ""; -} - -//! Sets item corresponding to given model type. - -void GroupItem::setCurrentType(const std::string& model_type) -{ - auto model_types = m_catalogue->modelTypes(); - int index = Utils::IndexOfItem(model_types, model_type); - if (index == -1) - throw std::runtime_error("GroupItem::setCurrentType() -> Model type '" + model_type - + "' doesn't belong to the group"); - - setCurrentIndex(index); -} - -void GroupItem::setCurrentIndex(int index) -{ - auto combo = data<ComboProperty>(); - combo.setCurrentIndex(index); - setData(combo, ItemDataRole::DATA); -} - -bool GroupItem::is_valid_index() const -{ - return currentIndex() != -1; -} - -//! Inits group item by creating all registered items and constructing combo property -//! for switching between items. - -void GroupItem::init_group() -{ - ComboProperty combo; - combo.setValues(m_catalogue->labels()); - combo.setCurrentIndex(m_default_selected_index); - setData(combo, ItemDataRole::DATA); - for (const auto& x : m_catalogue->modelTypes()) - insertItem(m_catalogue->create(x).release(), TagRow::append(T_GROUP_ITEMS)); -} diff --git a/mvvm/model/mvvm/model/groupitem.h b/mvvm/model/mvvm/model/groupitem.h deleted file mode 100644 index 06209964cfbfdbcb8533996161f53aa2f9e0f6f3..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/model/groupitem.h +++ /dev/null @@ -1,61 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/model/groupitem.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_MODEL_GROUPITEM_H -#define BORNAGAIN_MVVM_MODEL_MVVM_MODEL_GROUPITEM_H - -#include "mvvm/model/itemcatalogue.h" -#include "mvvm/model/sessionitem.h" -#include <memory> - -namespace ModelView { - -//! Group item holds collection of predefined items. - -class MVVM_MODEL_EXPORT GroupItem : public SessionItem { -public: - static inline const std::string T_GROUP_ITEMS = "T_GROUP_ITEMS"; - - GroupItem(model_type modelType = GUI::Constants::GroupItemType); - ~GroupItem() override; - - int currentIndex() const; - - const SessionItem* currentItem() const; - SessionItem* currentItem(); - - std::string currentType() const; - void setCurrentType(const std::string& model_type); - -protected: - void setCurrentIndex(int index); - bool is_valid_index() const; - template <typename T> void registerItem(const std::string& text, bool make_selected = false); - // FIXME how to make sure that init_group() was called in constructor? - // Shell we delegate this call to CompoundItem::addProperty ? - void init_group(); - std::unique_ptr<ItemCatalogue> m_catalogue; - int m_default_selected_index; -}; - -template <typename T> void GroupItem::registerItem(const std::string& text, bool make_selected) -{ - m_catalogue->registerItem<T>(text); - if (make_selected) - m_default_selected_index = m_catalogue->itemCount() - 1; -} - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_MODEL_GROUPITEM_H diff --git a/mvvm/model/mvvm/model/itemcatalogue.cpp b/mvvm/model/mvvm/model/itemcatalogue.cpp deleted file mode 100644 index d1844fa24a1828334c90f3a8e74cace2fccc1430..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/model/itemcatalogue.cpp +++ /dev/null @@ -1,101 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/model/itemcatalogue.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/model/itemcatalogue.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/utils/ifactory.h" -#include <stdexcept> - -using namespace ModelView; - -struct ItemCatalogue::ItemCatalogueImpl { - IFactory<std::string, SessionItem> factory; - struct TypeAndLabel { - std::string item_type; - std::string item_label; - }; - - std::vector<TypeAndLabel> m_info; -}; - -ItemCatalogue::ItemCatalogue() : p_impl(std::make_unique<ItemCatalogueImpl>()) {} - -ItemCatalogue::ItemCatalogue(const ItemCatalogue& other) -{ - p_impl = std::make_unique<ItemCatalogueImpl>(*other.p_impl); -} - -ItemCatalogue& ItemCatalogue::operator=(const ItemCatalogue& other) -{ - if (this != &other) { - ItemCatalogue tmp(other); - std::swap(this->p_impl, tmp.p_impl); - } - return *this; -} - -void ItemCatalogue::registerItem(const std::string& modelType, item_factory_func_t func, - const std::string& label) -{ - p_impl->factory.add(modelType, func); - p_impl->m_info.push_back({modelType, label}); -} - -ItemCatalogue::~ItemCatalogue() = default; - -bool ItemCatalogue::contains(const std::string& modelType) const -{ - return p_impl->factory.contains(modelType); -} - -std::unique_ptr<SessionItem> ItemCatalogue::create(const std::string& modelType) const -{ - return p_impl->factory.create(modelType); -} - -std::vector<std::string> ItemCatalogue::modelTypes() const -{ - std::vector<std::string> result; - for (const auto& x : p_impl->m_info) - result.push_back(x.item_type); - return result; -} - -std::vector<std::string> ItemCatalogue::labels() const -{ - std::vector<std::string> result; - for (const auto& x : p_impl->m_info) - result.push_back(x.item_label); - return result; -} - -int ItemCatalogue::itemCount() const -{ - return static_cast<int>(p_impl->factory.size()); -} - -//! Adds content of other catalogue to this. - -void ItemCatalogue::merge(const ItemCatalogue& other) -{ - size_t index(0); - for (auto it : other.p_impl->factory) { - if (contains(it.first)) - throw std::runtime_error( - "ItemCatalogue::add() -> Catalogue contains duplicated records"); - - registerItem(it.first, it.second, other.p_impl->m_info[index].item_label); - ++index; - } -} diff --git a/mvvm/model/mvvm/model/itemcatalogue.h b/mvvm/model/mvvm/model/itemcatalogue.h deleted file mode 100644 index 04586ae64f642dbe74a138c30636968fb747ddcc..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/model/itemcatalogue.h +++ /dev/null @@ -1,67 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/model/itemcatalogue.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_MODEL_ITEMCATALOGUE_H -#define BORNAGAIN_MVVM_MODEL_MVVM_MODEL_ITEMCATALOGUE_H - -#include "mvvm/model/function_types.h" -#include "mvvm/model_export.h" -#include <string> -#include <vector> - -namespace ModelView { - -class SessionItem; - -//! Catalogue for item constructions. Contains collection of factory functions associated with -//! item's modelType and optional label. - -class MVVM_MODEL_EXPORT ItemCatalogue { -public: - ItemCatalogue(); - ~ItemCatalogue(); - - ItemCatalogue(const ItemCatalogue& other); - ItemCatalogue& operator=(const ItemCatalogue& other); - - template <typename T> void registerItem(const std::string& label = {}); - - void registerItem(const std::string& modelType, item_factory_func_t func, - const std::string& label); - - bool contains(const std::string& modelType) const; - - std::unique_ptr<SessionItem> create(const std::string& modelType) const; - - std::vector<std::string> modelTypes() const; - - std::vector<std::string> labels() const; - - int itemCount() const; - - void merge(const ItemCatalogue& other); - -private: - struct ItemCatalogueImpl; - std::unique_ptr<ItemCatalogueImpl> p_impl; -}; - -template <typename T> void ItemCatalogue::registerItem(const std::string& label) -{ - registerItem(T().modelType(), ItemFactoryFunction<T>(), label); -} - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_MODEL_ITEMCATALOGUE_H diff --git a/mvvm/model/mvvm/model/itemfactory.cpp b/mvvm/model/mvvm/model/itemfactory.cpp deleted file mode 100644 index aaea3fc62e57e850c2f45d920e3bf7b3b748dc93..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/model/itemfactory.cpp +++ /dev/null @@ -1,37 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/model/itemfactory.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/model/itemfactory.h" -#include "mvvm/model/itemcatalogue.h" -#include "mvvm/model/sessionitem.h" - -using namespace ModelView; - -GUI::Model::ItemFactory::ItemFactory(std::unique_ptr<ItemCatalogue> catalogue) - : m_catalogue(std::move(catalogue)) -{ -} - -void GUI::Model::ItemFactory::registerItem(const std::string& modelType, item_factory_func_t func, - const std::string& label) -{ - m_catalogue->registerItem(modelType, func, label); -} - -GUI::Model::ItemFactory::~ItemFactory() = default; - -std::unique_ptr<SessionItem> GUI::Model::ItemFactory::createItem(const model_type& modelType) const -{ - return m_catalogue->create(modelType); -} diff --git a/mvvm/model/mvvm/model/itemfactory.h b/mvvm/model/mvvm/model/itemfactory.h deleted file mode 100644 index 47192e5f26b5607fa53f323d2dce4ab90c3e9640..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/model/itemfactory.h +++ /dev/null @@ -1,44 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/model/itemfactory.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_MODEL_ITEMFACTORY_H -#define BORNAGAIN_MVVM_MODEL_MVVM_MODEL_ITEMFACTORY_H - -#include "mvvm/interfaces/itemfactoryinterface.h" -#include "mvvm/model_export.h" -#include <memory> - -namespace ModelView { - -class ItemCatalogue; - -//! Default SessionItem factory. - -class MVVM_MODEL_EXPORT ItemFactory : public ItemFactoryInterface { -public: - ItemFactory(std::unique_ptr<ItemCatalogue> catalogue); - ~ItemFactory() override; - - void registerItem(const std::string& modelType, item_factory_func_t func, - const std::string& label) override; - - std::unique_ptr<SessionItem> createItem(const model_type& modelType) const override; - -protected: - std::unique_ptr<ItemCatalogue> m_catalogue; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_MODEL_ITEMFACTORY_H diff --git a/mvvm/model/mvvm/model/itemmanager.cpp b/mvvm/model/mvvm/model/itemmanager.cpp deleted file mode 100644 index b4752256cdb6e0816e23baab12f587513912d196..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/model/itemmanager.cpp +++ /dev/null @@ -1,94 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/model/itemmanager.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/model/itemmanager.h" -#include "mvvm/factories/itemcataloguefactory.h" -#include "mvvm/model/itemfactory.h" -#include "mvvm/model/itempool.h" -#include "mvvm/model/sessionitem.h" - -namespace { -std::unique_ptr<ModelView::ItemFactory> DefaultItemFactory() -{ - return std::make_unique<ModelView::ItemFactory>(ModelView::CreateStandardItemCatalogue()); -} -} // namespace - -using namespace ModelView; - -ItemManager::ItemManager() : m_item_factory(DefaultItemFactory()) {} - -void ItemManager::setItemFactory(std::unique_ptr<ItemFactoryInterface> factory) -{ - m_item_factory = std::move(factory); -} - -void ItemManager::setItemPool(std::shared_ptr<ItemPool> pool) -{ - m_item_pool = std::move(pool); -} - -ItemManager::~ItemManager() = default; - -std::unique_ptr<SessionItem> ItemManager::createItem(const model_type& modelType) const -{ - return m_item_factory->createItem(modelType); -} - -std::unique_ptr<SessionItem> ItemManager::createRootItem() const -{ - return std::make_unique<SessionItem>(); -} - -SessionItem* ItemManager::findItem(const identifier_type& id) const -{ - return m_item_pool ? m_item_pool->item_for_key(id) : nullptr; -} - -identifier_type ItemManager::findIdentifier(const SessionItem* item) const -{ - return m_item_pool ? m_item_pool->key_for_item(item) : identifier_type(); -} - -const ItemPool* ItemManager::itemPool() const -{ - return m_item_pool.get(); -} - -ItemPool* ItemManager::itemPool() -{ - return m_item_pool.get(); -} - -void ItemManager::registerInPool(SessionItem* item) -{ - if (m_item_pool) - m_item_pool->register_item(item, item->identifier()); -} - -void ItemManager::unregisterFromPool(SessionItem* item) -{ - if (m_item_pool) - m_item_pool->unregister_item(item); -} - -const ItemFactoryInterface* ItemManager::factory() const -{ - return m_item_factory.get(); -} - -ItemFactoryInterface* ItemManager::factory() -{ - return const_cast<ItemFactoryInterface*>(static_cast<const ItemManager*>(this)->factory()); -} diff --git a/mvvm/model/mvvm/model/itemmanager.h b/mvvm/model/mvvm/model/itemmanager.h deleted file mode 100644 index 617c983b9f20351f418bcec8d477b263ed784d9e..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/model/itemmanager.h +++ /dev/null @@ -1,63 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/model/itemmanager.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_MODEL_ITEMMANAGER_H -#define BORNAGAIN_MVVM_MODEL_MVVM_MODEL_ITEMMANAGER_H - -#include "mvvm/model/mvvm_types.h" -#include "mvvm/model_export.h" -#include <memory> - -namespace ModelView { - -class SessionItem; -class ItemPool; -class ItemFactoryInterface; - -//! Manages item creation/registration for SessionModel. - -class MVVM_MODEL_EXPORT ItemManager { -public: - ItemManager(); - ~ItemManager(); - - void setItemFactory(std::unique_ptr<ItemFactoryInterface> factory); - void setItemPool(std::shared_ptr<ItemPool> pool); - - std::unique_ptr<SessionItem> createItem(const model_type& modelType = {}) const; - - std::unique_ptr<SessionItem> createRootItem() const; - - SessionItem* findItem(const identifier_type& id) const; - - identifier_type findIdentifier(const SessionItem* item) const; - - const ItemPool* itemPool() const; - ItemPool* itemPool(); - - void registerInPool(SessionItem* item); - void unregisterFromPool(SessionItem* item); - - const ItemFactoryInterface* factory() const; - - ItemFactoryInterface* factory(); - -private: - std::shared_ptr<ItemPool> m_item_pool; - std::unique_ptr<ItemFactoryInterface> m_item_factory; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_MODEL_ITEMMANAGER_H diff --git a/mvvm/model/mvvm/model/itempool.cpp b/mvvm/model/mvvm/model/itempool.cpp deleted file mode 100644 index cc0b33eb1bac9fcc382f6934926044d9ea9ae27d..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/model/itempool.cpp +++ /dev/null @@ -1,79 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/model/itempool.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/model/itempool.h" -#include "mvvm/core/uniqueidgenerator.h" -#include <stdexcept> - -using namespace ModelView; - -size_t ItemPool::size() const -{ - if (m_key_to_item.size() != m_item_to_key.size()) - throw std::runtime_error("Error in ItemPool: array size mismatch"); - return m_key_to_item.size(); -} - -identifier_type ItemPool::register_item(SessionItem* item, identifier_type key) - -{ - if (m_item_to_key.find(item) != m_item_to_key.end()) - throw std::runtime_error("ItemPool::register_item() -> Attempt to register already " - "registered item."); - - if (key.empty()) { - key = UniqueIdGenerator::generate(); - while (m_key_to_item.find(key) != m_key_to_item.end()) - key = UniqueIdGenerator::generate(); // preventing improbable duplicates - } else { - if (m_key_to_item.find(key) != m_key_to_item.end()) - throw std::runtime_error(" ItemPool::register_item() -> Attempt to reuse existing key"); - } - - m_key_to_item.insert(std::make_pair(key, item)); - m_item_to_key.insert(std::make_pair(item, key)); - - return key; -} - -void ItemPool::unregister_item(SessionItem* item) -{ - auto it = m_item_to_key.find(item); - if (it == m_item_to_key.end()) - throw std::runtime_error("ItemPool::deregister_item() -> Attempt to deregister " - "non existing item."); - auto key = it->second; - m_item_to_key.erase(it); - - auto it2 = m_key_to_item.find(key); - m_key_to_item.erase(it2); -} - -identifier_type ItemPool::key_for_item(const SessionItem* item) const -{ - const auto it = m_item_to_key.find(item); - if (it != m_item_to_key.end()) - return it->second; - - return {}; -} - -SessionItem* ItemPool::item_for_key(const identifier_type& key) const -{ - auto it = m_key_to_item.find(key); - if (it != m_key_to_item.end()) - return it->second; - - return nullptr; -} diff --git a/mvvm/model/mvvm/model/itempool.h b/mvvm/model/mvvm/model/itempool.h deleted file mode 100644 index 68be36663a268e1fbc8615fe2bacbe5e1ecb7201..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/model/itempool.h +++ /dev/null @@ -1,53 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/model/itempool.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_MODEL_ITEMPOOL_H -#define BORNAGAIN_MVVM_MODEL_MVVM_MODEL_ITEMPOOL_H - -#include "mvvm/model/mvvm_types.h" -#include "mvvm/model_export.h" -#include <map> - -namespace ModelView { - -class SessionItem; - -//! Provides registration of SessionItem pointers and their unique identifiers -//! in global memory pool. - -class MVVM_MODEL_EXPORT ItemPool { -public: - ItemPool() = default; - ItemPool(const ItemPool&) = delete; - ItemPool(ItemPool&&) = delete; - ItemPool& operator=(const ItemPool&) = delete; - ItemPool& operator=(ItemPool&&) = delete; - - size_t size() const; - - identifier_type register_item(SessionItem* item, identifier_type key = {}); - void unregister_item(SessionItem* item); - - identifier_type key_for_item(const SessionItem* item) const; - - SessionItem* item_for_key(const identifier_type& key) const; - -private: - std::map<identifier_type, SessionItem*> m_key_to_item; - std::map<const SessionItem*, identifier_type> m_item_to_key; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_MODEL_ITEMPOOL_H diff --git a/mvvm/model/mvvm/model/itemutils.cpp b/mvvm/model/mvvm/model/itemutils.cpp deleted file mode 100644 index a3374b327a4f011c25cc0f2e276f60d4e60e6b0f..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/model/itemutils.cpp +++ /dev/null @@ -1,177 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/model/itemutils.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/model/itemutils.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/model/sessionitemcontainer.h" -#include "mvvm/model/sessionitemtags.h" -#include "mvvm/utils/containerutils.h" -#include <iterator> - -using namespace ModelView; - -void Utils::iterate(SessionItem* item, const std::function<void(SessionItem*)>& fun) -{ - if (item) - fun(item); - else - return; - - for (auto child : item->children()) - iterate(child, fun); -} - -void Utils::iterate_if(const SessionItem* item, const std::function<bool(const SessionItem*)>& fun) -{ - bool proceed_with_children(true); - - if (item) - proceed_with_children = fun(item); - - if (!item || !proceed_with_children) - return; - - for (auto child : item->children()) - iterate_if(child, fun); -} - -int Utils::CopyNumber(const SessionItem* item) -{ - int result(-1); - - if (!item) - return result; - - int count(0); - auto model_type = item->modelType(); - if (auto parent = item->parent()) { - for (auto child : parent->children()) { - if (child == item) - result = count; - if (child->modelType() == model_type) - ++count; - } - } - - return count > 1 ? result : -1; -} - -SessionItem* Utils::ChildAt(const SessionItem* parent, int index) -{ - if (!parent) - return nullptr; - - auto container = parent->children(); - return index >= 0 && static_cast<size_t>(index) < container.size() - ? container[static_cast<size_t>(index)] - : nullptr; -} - -int Utils::IndexOfChild(const SessionItem* parent, const SessionItem* child) -{ - return Utils::IndexOfItem(parent->children(), child); -} - -bool Utils::HasTag(const SessionItem& item, const std::string& tag) -{ - return item.itemTags()->isTag(tag); -} - -bool Utils::IsSinglePropertyTag(const SessionItem& item, const std::string& tag) -{ - return item.itemTags()->isSinglePropertyTag(tag); -} - -std::vector<std::string> Utils::RegisteredTags(const SessionItem& item) -{ - std::vector<std::string> result; - for (const auto container : *item.itemTags()) - result.push_back(container->name()); - return result; -} - -std::vector<std::string> Utils::RegisteredUniversalTags(const SessionItem& item) -{ - std::vector<std::string> result; - for (const auto& tag : RegisteredTags(item)) - if (!IsSinglePropertyTag(item, tag)) - result.push_back(tag); - return result; -} - -std::vector<SessionItem*> Utils::TopLevelItems(const SessionItem& item) -{ - std::vector<SessionItem*> result; - for (auto child : item.children()) - if (!IsSinglePropertyTag(item, item.tagRowOfItem(child).tag)) - result.push_back(child); - return result; -} - -std::vector<SessionItem*> Utils::SinglePropertyItems(const SessionItem& item) -{ - std::vector<SessionItem*> result; - for (auto child : item.children()) - if (IsSinglePropertyTag(item, item.tagRowOfItem(child).tag)) - result.push_back(child); - return result; -} - -SessionItem* Utils::FindNextSibling(SessionItem* item) -{ - auto parent = item ? item->parent() : nullptr; - if (!parent) - return nullptr; - auto tagrow = item->tagRow(); - return parent->getItem(tagrow.tag, tagrow.row + 1); -} - -SessionItem* Utils::FindPreviousSibling(SessionItem* item) -{ - auto parent = item ? item->parent() : nullptr; - if (!parent) - return nullptr; - auto tagrow = parent->tagRowOfItem(item); - return parent->getItem(tagrow.tag, tagrow.row - 1); -} - -SessionItem* Utils::FindNextItemToSelect(SessionItem* item) -{ - auto next = FindNextSibling(item); - auto closest = next ? next : FindPreviousSibling(item); - return closest ? closest : item->parent(); -} - -bool Utils::IsItemAncestor(const SessionItem* item, const SessionItem* candidate) -{ - if (!item || !candidate) - return false; - const SessionItem* parent = item->parent(); - while (parent) { - if (parent == candidate) - return true; - else - parent = parent->parent(); - } - return false; -} - -std::vector<SessionItem*> Utils::UniqueItems(const std::vector<SessionItem*>& items) -{ - auto filtered = Utils::UniqueWithOrder(items); - std::vector<SessionItem*> result; - std::copy_if(filtered.begin(), filtered.end(), std::back_inserter(result), - [](auto x) { return x != nullptr; }); - return result; -} diff --git a/mvvm/model/mvvm/model/itemutils.h b/mvvm/model/mvvm/model/itemutils.h deleted file mode 100644 index 49174449d8b2f0a2495be2e45b99295c8e1754de..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/model/itemutils.h +++ /dev/null @@ -1,104 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/model/itemutils.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_MODEL_ITEMUTILS_H -#define BORNAGAIN_MVVM_MODEL_MVVM_MODEL_ITEMUTILS_H - -#include "mvvm/model_export.h" -#include <functional> -#include <string> -#include <vector> - -namespace ModelView { - -class SessionItem; - -namespace Utils { - -//! Iterates through item and all its children. -MVVM_MODEL_EXPORT void iterate(SessionItem* item, const std::function<void(SessionItem*)>& fun); - -//! Iterates through all model indices and calls user function. -//! If function returns false for given index, iteration will not go down to children. -MVVM_MODEL_EXPORT void iterate_if(const SessionItem* item, - const std::function<bool(const SessionItem*)>& fun); - -//! Returns copy number of given item in it's parent hierarchy. Takes into account only items with -//! same modelType. -MVVM_MODEL_EXPORT int CopyNumber(const SessionItem* item); - -//! Returns child at given index of parent. No tags are involved, index is considered -//! as global index in the combined array of all children. -MVVM_MODEL_EXPORT SessionItem* ChildAt(const SessionItem* parent, int index); - -//! Returns index in children array corresponding to given child. No tags are involved, -//! index is considered as global index in the combined array of all children. -MVVM_MODEL_EXPORT int IndexOfChild(const SessionItem* parent, const SessionItem* child); - -//! Returns true if given item has registered tag. -MVVM_MODEL_EXPORT bool HasTag(const SessionItem& item, const std::string& tag); - -//! Returns true if given item has registered `tag`, and it belongs to single property. -MVVM_MODEL_EXPORT bool IsSinglePropertyTag(const SessionItem& item, const std::string& tag); - -//! Returns vector of strings containing all registered tags of the given item. -MVVM_MODEL_EXPORT std::vector<std::string> RegisteredTags(const SessionItem& item); - -//! Returns vector of strings containing all registered universal tags of the given item. -//! A universal tag is a tag that is usually empty after item construction and serves for later -//! children's insertion. -MVVM_MODEL_EXPORT std::vector<std::string> RegisteredUniversalTags(const SessionItem& item); - -//! Returns vector of children representing top level items. -MVVM_MODEL_EXPORT std::vector<SessionItem*> TopLevelItems(const SessionItem& item); - -//! Returns vector of children representing property items. - -MVVM_MODEL_EXPORT std::vector<SessionItem*> SinglePropertyItems(const SessionItem& item); - -//! Returns next sibling with same tag. - -MVVM_MODEL_EXPORT SessionItem* FindNextSibling(SessionItem* item); - -//! Returns previous sibling with same tag. - -MVVM_MODEL_EXPORT SessionItem* FindPreviousSibling(SessionItem* item); - -//! Finds next item to select -//! Method is used in the context of next item selection after given item was deleted. - -MVVM_MODEL_EXPORT SessionItem* FindNextItemToSelect(SessionItem* item); - -//! Returns true if 'candidate' is one of ancestor of given item. -MVVM_MODEL_EXPORT bool IsItemAncestor(const SessionItem* item, const SessionItem* candidate); - -//! Returns vector with duplicates and 'nullptr' filtered out. -MVVM_MODEL_EXPORT std::vector<SessionItem*> UniqueItems(const std::vector<SessionItem*>& items); - -//! Returns vector of items casted to given type. -template <typename T> std::vector<T*> CastedItems(const std::vector<SessionItem*>& items) -{ - std::vector<T*> result; - for (auto item : items) - if (auto casted_item = dynamic_cast<T*>(item); casted_item) - result.push_back(casted_item); - - return result; -} - -} // namespace Utils - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_MODEL_ITEMUTILS_H diff --git a/mvvm/model/mvvm/model/modelutils.cpp b/mvvm/model/mvvm/model/modelutils.cpp deleted file mode 100644 index 0ad046e3e446a1a875b747f7e47cb8f3d05fb5b0..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/model/modelutils.cpp +++ /dev/null @@ -1,107 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/model/modelutils.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/model/modelutils.h" -#include "mvvm/interfaces/undostackinterface.h" -#include "mvvm/model/path.h" -#include <QJsonObject> - -using namespace ModelView; - -Path Utils::PathFromItem(const SessionItem* item) -{ - if (!item || !item->model()) - return {}; - - Path result; - const SessionItem* current(item); - while (current && current->parent()) { - result.prepend(Utils::IndexOfChild(current->parent(), current)); - current = current->parent(); - } - return result; -} - -SessionItem* Utils::ItemFromPath(const SessionModel& model, const Path& path) -{ - SessionItem* result(model.rootItem()); - for (const auto& x : path) { - result = Utils::ChildAt(result, x); - if (!result) - break; - } - return result; -} - -void Utils::PopulateEmptyModel(const JsonModelConverterInterface* converter, - const SessionModel& source, SessionModel& target) -{ - QJsonObject object = converter->to_json(source); - converter->from_json(object, target); -} - -void Utils::DeleteItemFromModel(SessionItem* item) -{ - auto model = item->model(); - if (!model) - return; - - model->removeItem(item->parent(), item->tagRow()); -} - -void Utils::MoveUp(SessionItem* item) -{ - auto tagrow = item->tagRow(); - if (tagrow.row == 0) - return; // item already at the top - item->model()->moveItem(item, item->parent(), tagrow.prev()); -} - -void Utils::MoveDown(SessionItem* item) -{ - auto tagrow = item->tagRow(); - if (tagrow.row == item->parent()->itemCount(tagrow.tag) - 1) - return; // item already at the buttom - item->model()->moveItem(item, item->parent(), tagrow.next()); -} - -void Utils::Undo(SessionModel& model) -{ - if (auto stack = model.undoStack(); stack) - stack->undo(); -} - -void Utils::Redo(SessionModel& model) -{ - if (auto stack = model.undoStack(); stack) - stack->redo(); -} - -void Utils::BeginMacros(const SessionItem* item, const std::string& macro_name) -{ - if (!item->model()) - return; - - if (auto stack = item->model()->undoStack(); stack) - stack->beginMacro(macro_name); -} - -void Utils::EndMacros(const SessionItem* item) -{ - if (!item->model()) - return; - - if (auto stack = item->model()->undoStack(); stack) - stack->endMacro(); -} diff --git a/mvvm/model/mvvm/model/modelutils.h b/mvvm/model/mvvm/model/modelutils.h deleted file mode 100644 index e36b20f57e708a4135318e8f423e0d2982ecb0cc..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/model/modelutils.h +++ /dev/null @@ -1,124 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/model/modelutils.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_MODEL_MODELUTILS_H -#define BORNAGAIN_MVVM_MODEL_MVVM_MODEL_MODELUTILS_H - -#include "mvvm/factories/modelconverterfactory.h" -#include "mvvm/model/itemutils.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/model_export.h" -#include <memory> -#include <vector> - -namespace ModelView { - -class Path; - -namespace Utils { - -//! Returns all top level items of given type. - -template <typename T = SessionItem> std::vector<T*> TopItems(const SessionModel* model) -{ - std::vector<T*> result; - for (auto child : model->rootItem()->children()) { - if (auto item = dynamic_cast<T*>(child); item) - result.push_back(item); - } - - return result; -} - -//! Returns top level item of given type. - -template <typename T = SessionItem> T* TopItem(const SessionModel* model) -{ - auto items = TopItems<T>(model); - return items.empty() ? nullptr : items.front(); -} - -//! Returns all items in a tree of given type. - -template <typename T = SessionItem> std::vector<T*> FindItems(const SessionModel* model) -{ - std::vector<T*> result; - - auto func = [&result](SessionItem* item) { - if (auto concrete = dynamic_cast<T*>(item); concrete) - result.push_back(concrete); - }; - - iterate(model->rootItem(), func); - - return result; -} - -//! Constructs path to find given item. Item must belong to a model. -MVVM_MODEL_EXPORT Path PathFromItem(const SessionItem* item); - -//! Returns item found in the model following given Path. -MVVM_MODEL_EXPORT SessionItem* ItemFromPath(const SessionModel& moodel, const Path& path); - -//! Populate empty model with content of target model using provided converter. -//! Serves as auxiliary function for model copying and cloning. -MVVM_MODEL_EXPORT void PopulateEmptyModel(const JsonModelConverterInterface* converter, - const SessionModel& source, SessionModel& target); - -//! Creates full deep copy of given model. All item's ID will be generated. -template <typename T = SessionModel> std::unique_ptr<T> CreateCopy(const T& model) -{ - auto result = std::make_unique<T>(); - auto converter = CreateModelCopyConverter(); - PopulateEmptyModel(converter.get(), model, *result.get()); - return result; -} - -//! Creates exact clone of given model. All item's ID will be preserved. -template <typename T = SessionModel> std::unique_ptr<T> CreateClone(const T& model) -{ - auto result = std::make_unique<T>(); - auto converter = CreateModelCloneConverter(); - PopulateEmptyModel(converter.get(), model, *result.get()); - return result; -} - -//! Removes and deletes item from its model. -MVVM_MODEL_EXPORT void DeleteItemFromModel(SessionItem* item); - -//! Moves item up (decrements row of the item). Works on children belonging to single tag. -MVVM_MODEL_EXPORT void MoveUp(SessionItem* item); - -//! Moves item down (increments row of the item). Works on children belonging to single tag. -MVVM_MODEL_EXPORT void MoveDown(SessionItem* item); - -//! Undo last model operation. If not undo/redo enabled, will do nothing. -MVVM_MODEL_EXPORT void Undo(SessionModel& model); - -//! Redo model operation which was undone just before. If not undo/redo enabled, will do nothing. -MVVM_MODEL_EXPORT void Redo(SessionModel& model); - -//! Begin undo/redo macros with given name. Works only if item belongs to the model, and model has -//! undo/redo enabled. Otherwise, do nothing. -MVVM_MODEL_EXPORT void BeginMacros(const SessionItem* item, const std::string& macro_name); - -//! Finishes undo/redo macros. Works only if item belongs to the model, and model has undo/redo -//! enabled. Otherwise, do nothing. -MVVM_MODEL_EXPORT void EndMacros(const SessionItem* item); - -} // namespace Utils -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_MODEL_MODELUTILS_H diff --git a/mvvm/model/mvvm/model/mvvm_types.h b/mvvm/model/mvvm/model/mvvm_types.h deleted file mode 100644 index c78656a7f3dcb6d499bde6283c84b92afcff78a6..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/model/mvvm_types.h +++ /dev/null @@ -1,67 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/model/mvvm_types.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_MODEL_MVVM_TYPES_H -#define BORNAGAIN_MVVM_MODEL_MVVM_MODEL_MVVM_TYPES_H - -#include "mvvm/core/types.h" -#include <string> - -namespace ModelView { - -class SessionItem; -class SessionModel; - -//! Defines constants to be used as SessionItem data role. - -namespace ItemDataRole { -const int IDENTIFIER = 0; //!< unique identifier -const int DATA = 1; //!< main data role -const int DISPLAY = 2; //!< display name -const int APPEARANCE = 3; //!< appearance flag -const int LIMITS = 4; //!< possibly limits on item's data -const int TOOLTIP = 5; //!< tooltip for item's data -const int EDITORTYPE = 6; //!< type of custom editor for the data role -} // namespace ItemDataRole - -enum Appearance { - NOFLAGS = 0x000, - ENABLED = 0x001, // enabled in Qt widgets; when disabled, will be shown in gray - EDITABLE = 0x002 // editable in Qt widgets; readonly otherwise -}; - -namespace GUI::Constants { -const model_type BaseType = "SessionItem"; -const model_type ColorMapItemType = "ColorMap"; -const model_type ColorMapViewportItemType = "ColorMapViewport"; -const model_type CompoundItemType = "Compound"; -const model_type ContainerItemType = "Container"; -const model_type Data1DItemType = "Data1D"; -const model_type Data2DItemType = "Data2D"; -const model_type FixedBinAxisItemType = "FixedBinAxis"; -const model_type GraphItemType = "Graph"; -const model_type GraphViewportItemType = "GraphViewport"; -const model_type GroupItemType = "Group"; -const model_type LinkedItemType = "Linked"; -const model_type PenItemType = "Pen"; -const model_type PointwiseAxisItemType = "PointwiseAxis"; -const model_type PropertyType = "Property"; -const model_type TextItemType = "Text"; -const model_type VectorItemType = "Vector"; -const model_type ViewportAxisItemType = "ViewportAxis"; -} // namespace GUI::Constants - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_MODEL_MVVM_TYPES_H diff --git a/mvvm/model/mvvm/model/path.cpp b/mvvm/model/mvvm/model/path.cpp deleted file mode 100644 index 71877a77d89dc8310e435c6146d339c0891cf563..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/model/path.cpp +++ /dev/null @@ -1,85 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/model/path.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/model/path.h" -#include <algorithm> -#include <iterator> -#include <numeric> -#include <sstream> - -using namespace ModelView; - -//! Constructs Path object from string containing sequence of integers ("0,0,1,3"). - -Path Path::fromString(const std::string& str) -{ - Path result; - - std::string str_spaces(str); - std::replace(str_spaces.begin(), str_spaces.end(), ',', ' '); - - std::istringstream iss(str_spaces); - std::for_each(std::istream_iterator<std::string>(iss), std::istream_iterator<std::string>(), - [&result](auto x) { result.append(std::stoi(x)); }); - return result; -} - -//! Constructs Path object from vector of integers.. - -Path Path::fromVector(const std::vector<int>& data) -{ - Path result; - std::for_each(data.begin(), data.end(), [&result](auto x) { result.append(x); }); - return result; -} - -//! Returns string representing path ("0,0,1,3"). - -std::string Path::str() const -{ - auto comma_fold = [](std::string a, int b) { return std::move(a) + ',' + std::to_string(b); }; - return m_data.empty() ? "" - : std::accumulate(std::next(m_data.begin()), m_data.end(), - std::to_string(m_data[0]), comma_fold); -} - -void Path::append(Path::PathElement element) -{ - m_data.push_back(element); -} - -void Path::prepend(Path::PathElement element) -{ - m_data.insert(m_data.begin(), element); -} - -Path::iterator Path::begin() -{ - return m_data.begin(); -} - -Path::const_iterator Path::begin() const -{ - return m_data.begin(); -} - -Path::iterator Path::end() -{ - return m_data.end(); -} - -Path::const_iterator Path::end() const -{ - return m_data.end(); -} diff --git a/mvvm/model/mvvm/model/path.h b/mvvm/model/mvvm/model/path.h deleted file mode 100644 index 9c0a8a3256dea4790a8584edde4111b5e48d3822..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/model/path.h +++ /dev/null @@ -1,65 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/model/path.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_MODEL_PATH_H -#define BORNAGAIN_MVVM_MODEL_MVVM_MODEL_PATH_H - -#include "mvvm/model_export.h" -#include <string> -#include <vector> - -namespace ModelView { - -//! Supports navigation through SessionModel. Contains a chain of indexes that have to -//! be used to reach the desired SessionItem starting from the root item. Path class plays -//! a role of simplified QModelIndex for SessionModel. Used for undo/redo only. - -//! Example of tree: -//! - root path:"" -//! - child path:"0" -//! - grandchild path:"0,0" -//! - grandchild path:"0,1" -//! - child path:"1" - -class MVVM_MODEL_EXPORT Path { -public: - using PathElement = int; - using container_t = std::vector<PathElement>; - using iterator = container_t::iterator; - using const_iterator = container_t::const_iterator; - - Path() = default; - - static Path fromString(const std::string& str); - - static Path fromVector(const std::vector<int>& data); - - std::string str() const; - - void append(PathElement element); - void prepend(PathElement element); - - iterator begin(); - const_iterator begin() const; - - iterator end(); - const_iterator end() const; - -private: - container_t m_data; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_MODEL_PATH_H diff --git a/mvvm/model/mvvm/model/propertyitem.cpp b/mvvm/model/mvvm/model/propertyitem.cpp deleted file mode 100644 index b3b3af04ba3c6aa77abd0833e031c8e1b3158dc6..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/model/propertyitem.cpp +++ /dev/null @@ -1,33 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/model/propertyitem.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/model/propertyitem.h" -#include "mvvm/model/customvariants.h" -#include "mvvm/model/mvvm_types.h" - -using namespace ModelView; - -PropertyItem::PropertyItem() : SessionItem(GUI::Constants::PropertyType) {} - -PropertyItem* PropertyItem::setDisplayName(const std::string& name) -{ - SessionItem::setDisplayName(name); - return this; -} - -PropertyItem* PropertyItem::setLimits(const RealLimits& value) -{ - this->setData(value, ItemDataRole::LIMITS); - return this; -} diff --git a/mvvm/model/mvvm/model/propertyitem.h b/mvvm/model/mvvm/model/propertyitem.h deleted file mode 100644 index bfc8feb240e72af556311d58a3514e834365d61b..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/model/propertyitem.h +++ /dev/null @@ -1,38 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/model/propertyitem.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_MODEL_PROPERTYITEM_H -#define BORNAGAIN_MVVM_MODEL_MVVM_MODEL_PROPERTYITEM_H - -#include "mvvm/model/sessionitem.h" - -namespace ModelView { - -class RealLimits; - -//! Item to carry concrete editable entity (e.g. 'double' value with limits). -//! Intended for use as a child or CompountItem, not expected to have own children. - -class MVVM_MODEL_EXPORT PropertyItem : public SessionItem { -public: - PropertyItem(); - - PropertyItem* setDisplayName(const std::string& name) override; - - PropertyItem* setLimits(const RealLimits& value); -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_MODEL_PROPERTYITEM_H diff --git a/mvvm/model/mvvm/model/sessionitem.cpp b/mvvm/model/mvvm/model/sessionitem.cpp deleted file mode 100644 index 46c8827eced92c2718d0f57f29e4fc22f27ef4f7..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/model/sessionitem.cpp +++ /dev/null @@ -1,393 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/model/sessionitem.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/model/sessionitem.h" -#include "mvvm/core/uniqueidgenerator.h" -#include "mvvm/model/customvariants.h" -#include "mvvm/model/sessionitemdata.h" -#include "mvvm/model/sessionitemtags.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/model/taginfo.h" -#include "mvvm/signals/itemmapper.h" -#include "mvvm/signals/modelmapper.h" -#include <stdexcept> - -using namespace ModelView; - -namespace { -int appearance(const ModelView::SessionItem& item) -{ - const int default_appearance = Appearance::EDITABLE | Appearance::ENABLED; - return item.hasData(ItemDataRole::APPEARANCE) ? item.data<int>(ItemDataRole::APPEARANCE) - : default_appearance; -} -} // namespace - -struct SessionItem::SessionItemImpl { - SessionItem* m_self{nullptr}; - SessionItem* m_parent{nullptr}; - SessionModel* m_model{nullptr}; - std::unique_ptr<ItemMapper> m_mapper; - std::unique_ptr<SessionItemData> m_data; - std::unique_ptr<SessionItemTags> m_tags; - model_type m_modelType; - - SessionItemImpl(SessionItem* this_item) - : m_self(this_item) - , m_data(std::make_unique<SessionItemData>()) - , m_tags(std::make_unique<SessionItemTags>()) - { - } - - bool do_setData(const Variant& variant, int role) - { - bool result = m_data->setData(variant, role); - if (result && m_model) - m_model->mapper()->callOnDataChange(m_self, role); - return result; - } -}; - -SessionItem::SessionItem(model_type modelType) : p_impl(std::make_unique<SessionItemImpl>(this)) -{ - p_impl->m_modelType = std::move(modelType); - setData(UniqueIdGenerator::generate(), ItemDataRole::IDENTIFIER); - setData(p_impl->m_modelType, ItemDataRole::DISPLAY); -} - -SessionItem::~SessionItem() -{ - if (p_impl->m_mapper) - p_impl->m_mapper->callOnItemDestroy(); - - if (p_impl->m_model) - p_impl->m_model->unregisterFromPool(this); -} - -//! Returns item's model type. - -model_type SessionItem::modelType() const -{ - return p_impl->m_modelType; -} - -//! Returns unique identifier. - -std::string SessionItem::identifier() const -{ - return data<std::string>(ItemDataRole::IDENTIFIER); -} - -//! Returns display name. - -std::string SessionItem::displayName() const -{ - return data<std::string>(ItemDataRole::DISPLAY); -} - -//! Sets display name (fluent interface). - -SessionItem* SessionItem::setDisplayName(const std::string& name) -{ - setData(name, ItemDataRole::DISPLAY); - return this; -} - -//! Returns the model to which given item belongs to. Will return nullptr if item doesn't have a -//! model. - -SessionModel* SessionItem::model() const -{ - return p_impl->m_model; -} - -//! Returns parent item. Will return nullptr if item doesn't have a parent. - -SessionItem* SessionItem::parent() const -{ - return p_impl->m_parent; -} - -//! Returns TagRow of this item under which it is accessible through its parent. - -TagRow SessionItem::tagRow() const -{ - return parent() ? parent()->tagRowOfItem(this) : TagRow(); -} - -//! Returns true if item has data on board with given role. - -bool SessionItem::hasData(int role) const -{ - return p_impl->m_data->hasData(role); -} - -//! Returns pointer to item's data container (const version). - -const SessionItemData* SessionItem::itemData() const -{ - return p_impl->m_data.get(); -} - -//! Returns pointer to item's data container (non-const version). - -SessionItemData* SessionItem::itemData() -{ - return const_cast<SessionItemData*>(static_cast<const SessionItem*>(this)->itemData()); -} - -//! Returns total number of children in all tags. - -int SessionItem::childrenCount() const -{ - return static_cast<int>(children().size()); -} - -//! Returns vector of children formed from all chidlren from all tags. - -std::vector<SessionItem*> SessionItem::children() const -{ - return p_impl->m_tags->allitems(); -} - -//! Returns number of items in given tag. - -int SessionItem::itemCount(const std::string& tag) const -{ - return p_impl->m_tags->itemCount(tag); -} - -//! Returns item at given row of given tag. - -SessionItem* SessionItem::getItem(const std::string& tag, int row) const -{ - return p_impl->m_tags->getItem({tag, row}); -} - -//! Returns all children stored at given tag. - -std::vector<SessionItem*> SessionItem::getItems(const std::string& tag) const -{ - return p_impl->m_tags->getItems(tag); -} - -//! Returns pair of tag and row corresponding to given item. -//! Returns {"", -1} if given item doesn't belong to children. - -TagRow SessionItem::tagRowOfItem(const SessionItem* item) const -{ - return p_impl->m_tags->tagRowOfItem(item); -} - -//! Returns pointer to internal collection of tag-registered items (const version). - -const SessionItemTags* SessionItem::itemTags() const -{ - return p_impl->m_tags.get(); -} - -//! Registers tag to hold items under given name. - -void SessionItem::registerTag(const TagInfo& tagInfo, bool set_as_default) -{ - p_impl->m_tags->registerTag(tagInfo, set_as_default); -} - -//! Returns pointer to internal collection of tag-registered items (non-const version). - -SessionItemTags* SessionItem::itemTags() -{ - return const_cast<SessionItemTags*>(static_cast<const SessionItem*>(this)->itemTags()); -} - -//! Insert item into given tag under the given row. - -bool SessionItem::insertItem(SessionItem* item, const TagRow& tagrow) -{ - // think of passing unique_ptr directly - - if (!item) - throw std::runtime_error("SessionItem::insertItem() -> Invalid item."); - - if (item->parent()) - throw std::runtime_error("SessionItem::insertItem() -> Existing parent."); - - if (item->model()) - throw std::runtime_error("SessionItem::insertItem() -> Existing model."); - - auto result = p_impl->m_tags->insertItem(item, tagrow); - if (result) { - item->setParent(this); - item->setModel(model()); - - if (p_impl->m_model) { - // FIXME think of actual_tagrow removal if input tag,row will be always valid - auto actual_tagrow = tagRowOfItem(item); - p_impl->m_model->mapper()->callOnItemInserted(this, actual_tagrow); - } - } - - return result; -} - -//! Removes item from given row from given tag, returns it to the caller. - -SessionItem* SessionItem::takeItem(const TagRow& tagrow) -{ - if (!p_impl->m_tags->canTakeItem(tagrow)) - return nullptr; - - if (p_impl->m_model) - p_impl->m_model->mapper()->callOnItemAboutToBeRemoved(this, tagrow); - - auto result = p_impl->m_tags->takeItem(tagrow); - result->setParent(nullptr); - result->setModel(nullptr); - // FIXME remaining problem is that ItemMapper still looking to the model - if (p_impl->m_model) - p_impl->m_model->mapper()->callOnItemRemoved(this, tagrow); - - return result; -} - -//! Returns true if this item has `editable` flag set. -//! The data value of an editable item normally can be changed when it appears in trees and tables. - -bool SessionItem::isEditable() const -{ - return appearance(*this) & Appearance::EDITABLE; -} - -//! Sets `editable` flag to given value (fluent interface). - -SessionItem* SessionItem::setEditable(bool value) -{ - setAppearanceFlag(Appearance::EDITABLE, value); - return this; -} - -//! Returns true if this item has `enabled` flag set. -//! Enabled items appear in normal color, disabled items are grayed out. - -bool SessionItem::isEnabled() const -{ - return appearance(*this) & Appearance::ENABLED; -} - -//! Sets `enabled` flag to given value (fluent interface). - -SessionItem* SessionItem::setEnabled(bool value) -{ - setAppearanceFlag(Appearance::ENABLED, value); - return this; -} - -//! Returns item tooltip, if exists. - -std::string SessionItem::toolTip() const -{ - return hasData(ItemDataRole::TOOLTIP) ? data<std::string>(ItemDataRole::TOOLTIP) : ""; -} - -//! Sets item tooltip (fluent interface). - -SessionItem* SessionItem::setToolTip(const std::string& tooltip) -{ - setData(tooltip, ItemDataRole::TOOLTIP); - return this; -} - -//! Returns editor type. - -std::string SessionItem::editorType() const -{ - return hasData(ItemDataRole::EDITORTYPE) ? data<std::string>(ItemDataRole::EDITORTYPE) : ""; -} - -//! Sets editor type (fluent interface). -//! Allows creating custom editors in the cells of Qt trees and tables. - -SessionItem* SessionItem::setEditorType(const std::string& editor_type) -{ - setData(editor_type, ItemDataRole::EDITORTYPE); - return this; -} - -//! Sets the data for given role. Method invented to hide implementaiton details. - -bool SessionItem::set_data_internal(const Variant& value, int role, bool direct) -{ - // If model is present, and undo stack is enabled, will forward request to the model - // (unless user explicitly asks for direct processing via direct=true flag). - const bool act_through_model = !direct && model() && model()->undoStack(); - return act_through_model ? model()->setData(this, value, role) - : p_impl->do_setData(value, role); -} - -//! Returns data for given role. Method invented to hide implementaiton details and avoid -//! placing sessionitemdata.h into 'sessionitem.h' header. - -Variant SessionItem::data_internal(int role) const -{ - return p_impl->m_data->data(role); -} - -void SessionItem::setParent(SessionItem* parent) -{ - p_impl->m_parent = parent; -} - -void SessionItem::setModel(SessionModel* model) -{ - if (p_impl->m_model) - p_impl->m_model->unregisterFromPool(this); - - p_impl->m_model = model; - - if (p_impl->m_model) - p_impl->m_model->registerInPool(this); - - for (auto child : children()) - child->setModel(model); -} - -void SessionItem::setAppearanceFlag(int flag, bool value) -{ - int flags = appearance(*this); - if (value) - flags |= flag; - else - flags &= ~flag; - - // By setting data with internal method we are bypassing the model, and so undo/redo. - // So current convention is to not invoke undo when changing appearance properties. - // Shall we change it? - p_impl->do_setData(flags, ItemDataRole::APPEARANCE); -} - -//! Returns item mapper. Allows subscribing to various events happening to the item. - -ItemMapper* SessionItem::mapper() -{ - if (!p_impl->m_mapper) - p_impl->m_mapper = std::make_unique<ItemMapper>(this); - return p_impl->m_mapper.get(); -} - -void SessionItem::setDataAndTags(std::unique_ptr<SessionItemData> data, - std::unique_ptr<SessionItemTags> tags) -{ - p_impl->m_data = std::move(data); - p_impl->m_tags = std::move(tags); -} diff --git a/mvvm/model/mvvm/model/sessionitem.h b/mvvm/model/mvvm/model/sessionitem.h deleted file mode 100644 index b6476306d6966bc2eb7da51445ad4a8891d4d9de..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/model/sessionitem.h +++ /dev/null @@ -1,206 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/model/sessionitem.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_MODEL_SESSIONITEM_H -#define BORNAGAIN_MVVM_MODEL_MVVM_MODEL_SESSIONITEM_H - -#include "mvvm/core/variant.h" -#include "mvvm/model/customvariants.h" -#include "mvvm/model/mvvm_types.h" -#include "mvvm/model/tagrow.h" -#include "mvvm/model_export.h" -#include <memory> -#include <stdexcept> -#include <vector> - -namespace ModelView { - -class SessionModel; -class TagInfo; -class ItemMapper; -class SessionItemData; -class SessionItemTags; - -//! The main object representing an editable/displayable/serializable entity. Serves as a -//! construction element (node) of SessionModel to represent all the data of GUI application. - -class MVVM_MODEL_EXPORT SessionItem { -public: - explicit SessionItem(model_type modelType = GUI::Constants::BaseType); - virtual ~SessionItem(); - SessionItem(const SessionItem&) = delete; - SessionItem& operator=(const SessionItem&) = delete; - - // basic item properties - - model_type modelType() const; - - std::string identifier() const; - - virtual SessionItem* setDisplayName(const std::string& name); - virtual std::string displayName() const; - - SessionModel* model() const; - - SessionItem* parent() const; - - TagRow tagRow() const; - - // methods to deal with item data - - bool hasData(int role = ItemDataRole::DATA) const; - - template <typename T> T data(int role = ItemDataRole::DATA) const; - - template <typename T> - bool setData(const T& value, int role = ItemDataRole::DATA, bool direct = false); - - SessionItemData* itemData(); - const SessionItemData* itemData() const; - - // children access - - int childrenCount() const; - - std::vector<SessionItem*> children() const; - - int itemCount(const std::string& tag) const; - - SessionItem* getItem(const std::string& tag, int row = 0) const; - - std::vector<SessionItem*> getItems(const std::string& tag) const; - - template <typename T> T* item(const std::string& tag) const; - template <typename T = SessionItem> std::vector<T*> items(const std::string& tag) const; - - TagRow tagRowOfItem(const SessionItem* item) const; - - void registerTag(const TagInfo& tagInfo, bool set_as_default = false); - - SessionItemTags* itemTags(); - const SessionItemTags* itemTags() const; - - // item manipulation - - bool insertItem(SessionItem* item, const TagRow& tagrow); - - SessionItem* takeItem(const TagRow& tagrow); - - // more convenience methods - - bool isEditable() const; - SessionItem* setEditable(bool value); - - bool isEnabled() const; - SessionItem* setEnabled(bool value); - - std::string toolTip() const; - SessionItem* setToolTip(const std::string& tooltip); - - std::string editorType() const; - SessionItem* setEditorType(const std::string& editor_type); - - template <typename T> T property(const std::string& tag) const; - template <typename T> void setProperty(const std::string& tag, const T& value); - void setProperty(const std::string& tag, const char* value); - - ItemMapper* mapper(); - -private: - friend class SessionModel; - friend class JsonItemConverter; - virtual void activate() {} - bool set_data_internal(const Variant& value, int role, bool direct); - Variant data_internal(int role) const; - void setParent(SessionItem* parent); - void setModel(SessionModel* model); - void setAppearanceFlag(int flag, bool value); - - void setDataAndTags(std::unique_ptr<SessionItemData> data, - std::unique_ptr<SessionItemTags> tags); - - struct SessionItemImpl; - std::unique_ptr<SessionItemImpl> p_impl; -}; - -//! Sets data for a given role. When extra parameter `direct` is false (default case), will act -//! through the model to register command in undo/redo framework (if enabled) and so allow later -//! undo. - -template <typename T> inline bool SessionItem::setData(const T& value, int role, bool direct) -{ - return set_data_internal(Variant::fromValue(value), role, direct); -} - -//! Returns data of given type T for given role. - -template <typename T> inline T SessionItem::data(int role) const -{ - return data_internal(role).value<T>(); -} - -//! Returns first item under given tag casted to a specified type. -//! Returns nullptr, if item doesn't exist. If item exists but can't be casted will throw. - -template <typename T> inline T* SessionItem::item(const std::string& tag) const -{ - if (auto item = getItem(tag); item) { - T* tag_item = dynamic_cast<T*>(item); - if (!tag_item) - throw std::runtime_error("Can't cast an item to given type"); - return tag_item; - } - return nullptr; -} - -//! Returns all items under given tag casted to specific type. - -template <typename T> std::vector<T*> SessionItem::items(const std::string& tag) const -{ - std::vector<T*> result; - for (auto item : getItems(tag)) - if (auto casted = dynamic_cast<T*>(item); casted) - result.push_back(casted); - return result; -} - -//! Returns data stored in property item. -//! Property is single item registered under certain tag via CompoundItem::addProperty method. - -template <typename T> inline T SessionItem::property(const std::string& tag) const -{ - return getItem(tag)->data<T>(); -} - -//! Sets value to property item. -//! Property is single item registered under certain tag via CompoundItem::addProperty method, the -//! value will be assigned to it's data role. - -template <typename T> inline void SessionItem::setProperty(const std::string& tag, const T& value) -{ - getItem(tag)->setData(value); -} - -//! Sets value to property item (specialized for special "const char *" case). -//! Property is single item registered under certain tag via CompoundItem::addProperty method, the -//! value will be assigned to it's data role. - -inline void SessionItem::setProperty(const std::string& tag, const char* value) -{ - setProperty(tag, std::string(value)); -} - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_MODEL_SESSIONITEM_H diff --git a/mvvm/model/mvvm/model/sessionitemcontainer.cpp b/mvvm/model/mvvm/model/sessionitemcontainer.cpp deleted file mode 100644 index fa9c4eacbaac8b494ac62b0e3bd60636f8e47f96..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/model/sessionitemcontainer.cpp +++ /dev/null @@ -1,155 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/model/sessionitemcontainer.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/model/sessionitemcontainer.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/utils/containerutils.h" - -using namespace ModelView; - -SessionItemContainer::SessionItemContainer(ModelView::TagInfo tag_info) - : m_tag_info(std::move(tag_info)) -{ -} - -SessionItemContainer::~SessionItemContainer() -{ - for (auto item : m_items) - delete item; -} - -bool SessionItemContainer::empty() const -{ - return m_items.empty(); -} - -//! Returns number of items in given tag. - -int SessionItemContainer::itemCount() const -{ - return static_cast<int>(m_items.size()); -} - -//! Returns vector of items in this container. - -std::vector<SessionItem*> SessionItemContainer::items() const -{ - return m_items; -} - -/*! -@brief Inserts item in a vector of children at given index, returns true in the case of success. -@param item Item to be inserted, ownership will be taken. -@param index Item insert index in a range [0, itemCount] - -Insert index is an index which item will have after insertion. If item can't be inserted -(wrong model type, wrong index or maximum number of items reached), will return false. -*/ - -bool SessionItemContainer::insertItem(SessionItem* item, int index) -{ - if (!canInsertItem(item, index)) - return false; - - m_items.insert(std::next(m_items.begin(), index), item); - return true; -} - -//! Removes item at given index and returns it to the user. - -SessionItem* SessionItemContainer::takeItem(int index) -{ - if (minimum_reached()) - return nullptr; - - SessionItem* result = itemAt(index); - if (result) - m_items.erase(std::next(m_items.begin(), index)); - - return result; -} - -//! Returns true if item can be taken. - -bool SessionItemContainer::canTakeItem(int index) const -{ - return itemAt(index) && !minimum_reached(); -} - -//! Returns true if given item can be inserted under given index. - -bool SessionItemContainer::canInsertItem(const SessionItem* item, int index) const -{ - const bool valid_index = (index >= 0 && index <= itemCount()); - const bool enough_place = !maximum_reached(); - return valid_index && enough_place && is_valid_item(item); -} - -//! Returns index of item in vector of items. -//! Returns -1 if item doesn't belong to us. - -int SessionItemContainer::indexOfItem(const SessionItem* item) const -{ - return Utils::IndexOfItem(m_items, item); -} - -//! Returns item at given index. Returns nullptr if index is invalid. - -SessionItem* SessionItemContainer::itemAt(int index) const -{ - return index >= 0 && index < itemCount() ? m_items[static_cast<size_t>(index)] : nullptr; -} - -//! Returns the name of SessionItemTag. - -std::string SessionItemContainer::name() const -{ - return m_tag_info.name(); -} - -TagInfo SessionItemContainer::tagInfo() const -{ - return m_tag_info; -} - -SessionItemContainer::const_iterator SessionItemContainer::begin() const -{ - return m_items.begin(); -} - -SessionItemContainer::const_iterator SessionItemContainer::end() const -{ - return m_items.end(); -} - -//! Returns true if no more items are allowed. - -bool SessionItemContainer::maximum_reached() const -{ - return m_tag_info.max() != -1 && m_tag_info.max() == itemCount(); -} - -//! Returns true if less items than now is not allowed. - -bool SessionItemContainer::minimum_reached() const -{ - return m_tag_info.min() != -1 && m_tag_info.min() == itemCount(); -} - -//! Returns true if item's modelType is intended for this tag. - -bool SessionItemContainer::is_valid_item(const SessionItem* item) const -{ - return item && m_tag_info.isValidChild(item->modelType()); -} diff --git a/mvvm/model/mvvm/model/sessionitemcontainer.h b/mvvm/model/mvvm/model/sessionitemcontainer.h deleted file mode 100644 index d51978e76f6b89b89c20ffbea977580e29e9c283..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/model/sessionitemcontainer.h +++ /dev/null @@ -1,74 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/model/sessionitemcontainer.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_MODEL_SESSIONITEMCONTAINER_H -#define BORNAGAIN_MVVM_MODEL_MVVM_MODEL_SESSIONITEMCONTAINER_H - -#include "mvvm/model/taginfo.h" -#include "mvvm/model_export.h" -#include <vector> - -namespace ModelView { - -class SessionItem; - -//! Holds collection of SessionItem objects related to the same tag. - -class MVVM_MODEL_EXPORT SessionItemContainer { -public: - using container_t = std::vector<SessionItem*>; - using const_iterator = container_t::const_iterator; - - SessionItemContainer(TagInfo tag_info); - SessionItemContainer(const SessionItemContainer&) = delete; - SessionItemContainer& operator=(const SessionItemContainer&) = delete; - ~SessionItemContainer(); - - bool empty() const; - - int itemCount() const; - - std::vector<SessionItem*> items() const; - - bool insertItem(SessionItem* item, int index); - - SessionItem* takeItem(int index); - - bool canTakeItem(int index) const; - - bool canInsertItem(const SessionItem* item, int index) const; - - int indexOfItem(const SessionItem* item) const; - - SessionItem* itemAt(int index) const; - - std::string name() const; - - TagInfo tagInfo() const; - - const_iterator begin() const; - - const_iterator end() const; - -private: - bool maximum_reached() const; - bool minimum_reached() const; - bool is_valid_item(const SessionItem* item) const; - TagInfo m_tag_info; - container_t m_items; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_MODEL_SESSIONITEMCONTAINER_H diff --git a/mvvm/model/mvvm/model/sessionitemdata.cpp b/mvvm/model/mvvm/model/sessionitemdata.cpp deleted file mode 100644 index c1359a09e97264b3f65b10a2c4cb513c4ddc9832..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/model/sessionitemdata.cpp +++ /dev/null @@ -1,95 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/model/sessionitemdata.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/model/sessionitemdata.h" -#include "mvvm/model/customvariants.h" -#include <algorithm> -#include <sstream> -#include <stdexcept> - -using namespace ModelView; - -std::vector<int> SessionItemData::roles() const -{ - std::vector<int> result; - for (const auto& value : m_values) - result.push_back(value.m_role); - return result; -} - -Variant SessionItemData::data(int role) const -{ - for (const auto& value : m_values) { - if (value.m_role == role) - return value.m_data; - } - return Variant(); -} - -//! Sets the data for given role. Returns true if data was changed. -//! If variant is invalid, corresponding role will be removed. - -bool SessionItemData::setData(const Variant& value, int role) -{ - assure_validity(value, role); - - for (auto it = m_values.begin(); it != m_values.end(); ++it) { - if (it->m_role == role) { - if (value.isValid()) { - if (Utils::IsTheSame(it->m_data, value)) - return false; - it->m_data = value; - } else { - m_values.erase(it); - } - return true; - } - } - m_values.push_back(DataRole(value, role)); - return true; -} - -SessionItemData::const_iterator SessionItemData::begin() const -{ - return m_values.begin(); -} - -SessionItemData::const_iterator SessionItemData::end() const -{ - return m_values.end(); -} - -//! Returns true if item has data with given role. - -bool SessionItemData::hasData(int role) const -{ - auto has_role = [role](const auto& x) { return x.m_role == role; }; - return std::find_if(m_values.begin(), m_values.end(), has_role) != m_values.end(); -} - -//! Check if variant is compatible - -void SessionItemData::assure_validity(const Variant& variant, int role) -{ - if (variant.typeName() == QStringLiteral("QString")) - throw std::runtime_error("Attempt to set QString based variant"); - - if (!Utils::CompatibleVariantTypes(data(role), variant)) { - std::ostringstream ostr; - ostr << "SessionItemData::assure_validity() -> Error. Variant types mismatch. " - << "Old variant type '" << data(role).typeName() << "' " - << "new variant type '" << variant.typeName() << "\n"; - throw std::runtime_error(ostr.str()); - } -} diff --git a/mvvm/model/mvvm/model/sessionitemdata.h b/mvvm/model/mvvm/model/sessionitemdata.h deleted file mode 100644 index 287509f524ac446f0367ad393c06126ab7ae0e4c..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/model/sessionitemdata.h +++ /dev/null @@ -1,49 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/model/sessionitemdata.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_MODEL_SESSIONITEMDATA_H -#define BORNAGAIN_MVVM_MODEL_MVVM_MODEL_SESSIONITEMDATA_H - -#include "mvvm/model/datarole.h" -#include "mvvm/model_export.h" -#include <vector> - -namespace ModelView { - -//! Handles data roles for SessionItem. - -class MVVM_MODEL_EXPORT SessionItemData { -public: - using container_type = std::vector<DataRole>; - using const_iterator = container_type::const_iterator; - - std::vector<int> roles() const; - - Variant data(int role) const; - - bool setData(const Variant& value, int role); - - const_iterator begin() const; - const_iterator end() const; - - bool hasData(int role) const; - -private: - void assure_validity(const Variant& variant, int role); - container_type m_values; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_MODEL_SESSIONITEMDATA_H diff --git a/mvvm/model/mvvm/model/sessionitemtags.cpp b/mvvm/model/mvvm/model/sessionitemtags.cpp deleted file mode 100644 index 4170372ae10a24be66fe49f992054c941d6ed467..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/model/sessionitemtags.cpp +++ /dev/null @@ -1,183 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/model/sessionitemtags.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/model/sessionitemtags.h" -#include "mvvm/model/sessionitemcontainer.h" -#include <stdexcept> - -using namespace ModelView; - -SessionItemTags::SessionItemTags() = default; - -SessionItemTags::~SessionItemTags() -{ - for (auto tag : m_containers) - delete tag; -} - -void SessionItemTags::registerTag(const TagInfo& tagInfo, bool set_as_default) -{ - if (isTag(tagInfo.name())) - throw std::runtime_error("SessionItemTags::registerTag() -> Error. Existing name '" - + tagInfo.name() + "'"); - - m_containers.push_back(new SessionItemContainer(tagInfo)); - if (set_as_default) - m_default_tag = tagInfo.name(); -} - -//! Returns true if container with such name exists. - -bool SessionItemTags::isTag(const std::string& name) const -{ - for (auto tag : m_containers) - if (tag->name() == name) - return true; - return false; -} - -//! Returns the name of the default tag. - -std::string SessionItemTags::defaultTag() const -{ - return m_default_tag; -} - -void SessionItemTags::setDefaultTag(const std::string& name) -{ - m_default_tag = name; -} - -int SessionItemTags::itemCount(const std::string& tag_name) const -{ - return container(tag_name)->itemCount(); -} - -//! Inserts item in container with given tag name and at given row. -//! Returns true in the case of success. If tag name is empty, default tag will be used. - -bool SessionItemTags::insertItem(SessionItem* item, const TagRow& tagrow) -{ - auto tag_container = container(tagrow.tag); - auto row = tagrow.row < 0 ? tag_container->itemCount() : tagrow.row; - return container(tagrow.tag)->insertItem(item, row); -} - -//! Removes item at given row and for given tag, returns it to the user. - -SessionItem* SessionItemTags::takeItem(const TagRow& tagrow) -{ - return container(tagrow.tag)->takeItem(tagrow.row); -} - -//! Returns true if item can be taken. - -bool SessionItemTags::canTakeItem(const TagRow& tagrow) const -{ - return container(tagrow.tag)->canTakeItem(tagrow.row); -} - -//! Returns item at given row of given tag. - -SessionItem* SessionItemTags::getItem(const TagRow& tagrow) const -{ - return container(tagrow.tag)->itemAt(tagrow.row); -} - -//! Returns vector of items in the container with given name. -//! If tag name is empty, default tag will be used. - -std::vector<SessionItem*> SessionItemTags::getItems(const std::string& tag) const -{ - return container(tag)->items(); -} - -std::vector<SessionItem*> SessionItemTags::allitems() const -{ - std::vector<SessionItem*> result; - for (auto cont : m_containers) { - auto container_items = cont->items(); - result.insert(result.end(), container_items.begin(), container_items.end()); - } - - return result; -} - -//! Returns tag name and row of item in container. - -TagRow SessionItemTags::tagRowOfItem(const SessionItem* item) const -{ - for (auto cont : m_containers) { - int row = cont->indexOfItem(item); - if (row != -1) - return {cont->name(), row}; - } - - return {}; -} - -SessionItemTags::const_iterator SessionItemTags::begin() const -{ - return m_containers.begin(); -} - -SessionItemTags::const_iterator SessionItemTags::end() const -{ - return m_containers.end(); -} - -//! Returns true if given tag corresponds to registered single property tag. - -bool SessionItemTags::isSinglePropertyTag(const std::string& tag) const -{ - auto cont = find_container(tag); - return cont ? cont->tagInfo().isSinglePropertyTag() : false; -} - -int SessionItemTags::tagsCount() const -{ - return static_cast<int>(m_containers.size()); -} - -SessionItemContainer& SessionItemTags::at(int index) -{ - if (index < 0 || index >= tagsCount()) - throw std::runtime_error("Error it SessionItemTags: wrong container index"); - return *m_containers.at(index); -} - -//! Returns container corresponding to given tag name. If name is empty, -//! default tag will be used. Exception is thrown if no such tag exists. - -SessionItemContainer* SessionItemTags::container(const std::string& tag_name) const -{ - std::string tagName = tag_name.empty() ? defaultTag() : tag_name; - auto container = find_container(tagName); - if (!container) - throw std::runtime_error("SessionItemTags::container() -> Error. No such container '" - + tagName + "'"); - - return container; -} - -//! Returns container corresponding to given tag name. - -SessionItemContainer* SessionItemTags::find_container(const std::string& tag_name) const -{ - for (auto cont : m_containers) - if (cont->name() == tag_name) - return cont; - - return nullptr; -} diff --git a/mvvm/model/mvvm/model/sessionitemtags.h b/mvvm/model/mvvm/model/sessionitemtags.h deleted file mode 100644 index 9483ee736b53809dbbb51f0e7e1425ec8a700e32..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/model/sessionitemtags.h +++ /dev/null @@ -1,88 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/model/sessionitemtags.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_MODEL_SESSIONITEMTAGS_H -#define BORNAGAIN_MVVM_MODEL_MVVM_MODEL_SESSIONITEMTAGS_H - -#include "mvvm/model/tagrow.h" -#include "mvvm/model_export.h" -#include <string> -#include <vector> - -namespace ModelView { - -class SessionItemContainer; -class TagInfo; -class SessionItem; - -//! Collection of SessionItem's containers according to their tags. - -class MVVM_MODEL_EXPORT SessionItemTags { -public: - using container_t = std::vector<SessionItemContainer*>; - using const_iterator = container_t::const_iterator; - - SessionItemTags(); - ~SessionItemTags(); - SessionItemTags(const SessionItemTags&) = delete; - SessionItemTags& operator=(const SessionItemTags&) = delete; - - // tag - - void registerTag(const TagInfo& tagInfo, bool set_as_default = false); - - bool isTag(const std::string& name) const; - - std::string defaultTag() const; - - void setDefaultTag(const std::string& name); - - int itemCount(const std::string& tag_name) const; - - // adding and removal - - bool insertItem(SessionItem* item, const TagRow& tagrow); - - SessionItem* takeItem(const TagRow& tagrow); - - bool canTakeItem(const TagRow& tagrow) const; - - // item access - SessionItem* getItem(const TagRow& tagrow) const; - - std::vector<SessionItem*> getItems(const std::string& tag = {}) const; - - std::vector<SessionItem*> allitems() const; - - TagRow tagRowOfItem(const SessionItem* item) const; - - const_iterator begin() const; - const_iterator end() const; - - bool isSinglePropertyTag(const std::string& tag) const; - - int tagsCount() const; - - SessionItemContainer& at(int index); - -private: - SessionItemContainer* container(const std::string& tag_name) const; - SessionItemContainer* find_container(const std::string& tag_name) const; - std::vector<SessionItemContainer*> m_containers; - std::string m_default_tag; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_MODEL_SESSIONITEMTAGS_H diff --git a/mvvm/model/mvvm/model/sessionmodel.cpp b/mvvm/model/mvvm/model/sessionmodel.cpp deleted file mode 100644 index a822c930ec8cf508965d79e4c5183026869e3eac..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/model/sessionmodel.cpp +++ /dev/null @@ -1,232 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/model/sessionmodel.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/model/sessionmodel.h" -#include "mvvm/commands/commandservice.h" -#include "mvvm/factories/itemcataloguefactory.h" -#include "mvvm/model/customvariants.h" -#include "mvvm/model/itemcatalogue.h" -#include "mvvm/model/itemfactory.h" -#include "mvvm/model/itemmanager.h" -#include "mvvm/model/itempool.h" -#include "mvvm/model/itemutils.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/model/taginfo.h" -#include "mvvm/model/tagrow.h" -#include "mvvm/signals/modelmapper.h" - -using namespace ModelView; - -//! Pimpl class for SessionModel. - -struct SessionModel::SessionModelImpl { - SessionModel* m_self{nullptr}; - std::string m_modelType; - std::unique_ptr<ItemManager> m_itemManager; - std::unique_ptr<CommandService> m_commands; - std::unique_ptr<ModelMapper> m_mapper; - std::unique_ptr<SessionItem> m_root_item; - SessionModelImpl(SessionModel* self, std::string modelType, std::shared_ptr<ItemPool> pool) - : m_self(self) - , m_modelType(std::move(modelType)) - , m_itemManager(std::make_unique<ItemManager>()) - , m_commands(std::make_unique<CommandService>(self)) - , m_mapper(std::make_unique<ModelMapper>(self)) - { - setItemPool(pool); - } - - void setItemPool(std::shared_ptr<ItemPool> pool) - { - m_itemManager->setItemPool(pool ? std::move(pool) : std::make_shared<ItemPool>()); - } - - //! Creates root item. - void createRootItem() - { - m_root_item = m_itemManager->createRootItem(); - m_root_item->setModel(m_self); - m_root_item->registerTag(TagInfo::universalTag("rootTag"), /*set_as_default*/ true); - } -}; - -//! Main c-tor. - -SessionModel::SessionModel(std::string model_type, std::shared_ptr<ItemPool> pool) - : p_impl(std::make_unique<SessionModelImpl>(this, std::move(model_type), std::move(pool))) - -{ - p_impl->createRootItem(); -} - -SessionModel::~SessionModel() -{ - // Explicitly call root item's destructor. It uses p_impl pointer during own descruction - // and we have to keep pimpl pointer intact. Without line below will crash on MacOS because - // of pecularities of MacOS libc++. See explanations here: - // http://ibob.github.io/blog/2019/11/07/dont-use-unique_ptr-for-pimpl/ - p_impl->m_root_item.reset(); - - p_impl->m_mapper->callOnModelDestroyed(); -} - -//! Insert new item using item's modelType. - -SessionItem* SessionModel::insertNewItem(const model_type& modelType, SessionItem* parent, - const TagRow& tagrow) -{ - // intentionally passing by value inside lambda - auto create_func = [this, modelType]() { return factory()->createItem(modelType); }; - return intern_insert(create_func, parent, tagrow); -} - -//! Removes given row from parent. - -void SessionModel::removeItem(SessionItem* parent, const TagRow& tagrow) -{ - p_impl->m_commands->removeItem(parent, tagrow); -} - -//! Move item from it's current parent to a new parent under given tag and row. -//! Old and new parents should belong to this model. - -void SessionModel::moveItem(SessionItem* item, SessionItem* new_parent, const TagRow& tagrow) -{ - p_impl->m_commands->moveItem(item, new_parent, tagrow); -} - -//! Copy item and insert it in parent's tag and row. Item could belong to any model/parent. - -SessionItem* SessionModel::copyItem(const SessionItem* item, SessionItem* parent, - const TagRow& tagrow) -{ - return p_impl->m_commands->copyItem(item, parent, tagrow); -} - -//! Returns the data for given item and role. - -Variant SessionModel::data(SessionItem* item, int role) const -{ - return item->data<Variant>(role); -} - -//! Sets the data for given item. - -bool SessionModel::setData(SessionItem* item, const Variant& value, int role) -{ - return p_impl->m_commands->setData(item, value, role); -} - -//! Returns model type. - -std::string SessionModel::modelType() const -{ - return p_impl->m_modelType; -} - -//! Returns root item of the model. - -SessionItem* SessionModel::rootItem() const -{ - return p_impl->m_root_item.get(); -} - -//! Returns model mapper. Can be used to subscribe to various model's signal. - -ModelMapper* SessionModel::mapper() -{ - return p_impl->m_mapper.get(); -} - -//! Returns command stack to perform undo/redo. - -UndoStackInterface* SessionModel::undoStack() const -{ - return p_impl->m_commands->undoStack(); -} - -//! Returns item factory which can generate all items supported by this model. - -const ItemFactoryInterface* SessionModel::factory() const -{ - return p_impl->m_itemManager->factory(); -} - -//! Returns SessionItem for given identifier. - -SessionItem* SessionModel::findItem(const identifier_type& id) -{ - return p_impl->m_itemManager->findItem(id); -} - -//! Sets brand new catalog of user-defined items. They become available for undo/redo and -//! serialization. Internally user catalog will be merged with the catalog of standard items. - -void SessionModel::setItemCatalogue(std::unique_ptr<ItemCatalogue> catalogue) -{ - // adding standard items to the user catalogue - std::unique_ptr<ItemCatalogue> full_catalogue = std::move(catalogue); - full_catalogue->merge(*CreateStandardItemCatalogue()); - p_impl->m_itemManager->setItemFactory(std::make_unique<ItemFactory>(std::move(full_catalogue))); -} - -//! Sets undo/redo either enabled or disabled. By default undo/redo is disabled. - -void SessionModel::setUndoRedoEnabled(bool value) -{ - p_impl->m_commands->setUndoRedoEnabled(value); -} - -//! Removes all items from the model. If callback is provided, use it to rebuild content of root -//! item (used while restoring the model from serialized content). - -void SessionModel::clear(std::function<void(SessionItem*)> callback) -{ - if (undoStack()) - undoStack()->clear(); - mapper()->callOnModelAboutToBeReset(); - p_impl->createRootItem(); - if (callback) - callback(rootItem()); - mapper()->callOnModelReset(); -} - -//! Registers item in pool. This will allow to find item pointer using its unique identifier. - -void SessionModel::registerInPool(SessionItem* item) -{ - p_impl->m_itemManager->registerInPool(item); - item->activate(); // activates buisiness logic -} - -//! Unregister item from pool. - -void SessionModel::unregisterFromPool(SessionItem* item) -{ - p_impl->m_itemManager->unregisterFromPool(item); -} - -//! Insert new item into given parent using factory function provided. - -SessionItem* SessionModel::intern_insert(const item_factory_func_t& func, SessionItem* parent, - const TagRow& tagrow) -{ - return p_impl->m_commands->insertNewItem(func, parent, tagrow); -} - -void SessionModel::intern_register(const model_type& modelType, const item_factory_func_t& func, - const std::string& label) -{ - p_impl->m_itemManager->factory()->registerItem(modelType, func, label); -} diff --git a/mvvm/model/mvvm/model/sessionmodel.h b/mvvm/model/mvvm/model/sessionmodel.h deleted file mode 100644 index 80e0d95fa61ac0f978ea34335727fb45ee73c0ea..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/model/sessionmodel.h +++ /dev/null @@ -1,142 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/model/sessionmodel.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_MODEL_SESSIONMODEL_H -#define BORNAGAIN_MVVM_MODEL_MVVM_MODEL_SESSIONMODEL_H - -#include "mvvm/core/types.h" -#include "mvvm/core/variant.h" -#include "mvvm/model/function_types.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/model/tagrow.h" -#include "mvvm/model_export.h" -#include <memory> - -namespace ModelView { - -class SessionItem; -class ItemCatalogue; -class ItemPool; -class ModelMapper; -class ItemFactoryInterface; -class UndoStackInterface; - -//! Main class to hold hierarchy of SessionItem objects. - -class MVVM_MODEL_EXPORT SessionModel { -public: - explicit SessionModel(std::string model_type = {}, std::shared_ptr<ItemPool> pool = {}); - virtual ~SessionModel(); - SessionModel(const SessionModel& other) = delete; - SessionModel& operator=(const SessionModel& other) = delete; - - // Methods to manipulate data and items. - - SessionItem* insertNewItem(const model_type& modelType, SessionItem* parent = nullptr, - const TagRow& tagrow = {}); - - template <typename T> T* insertItem(SessionItem* parent = nullptr, const TagRow& tagrow = {}); - - void removeItem(SessionItem* parent, const TagRow& tagrow); - - void moveItem(SessionItem* item, SessionItem* new_parent, const TagRow& tagrow); - - SessionItem* copyItem(const SessionItem* item, SessionItem* parent, const TagRow& tagrow = {}); - - Variant data(SessionItem* item, int role) const; - - bool setData(SessionItem* item, const Variant& value, int role); - - // Various getters. - - std::string modelType() const; - - SessionItem* rootItem() const; - - ModelMapper* mapper(); - - UndoStackInterface* undoStack() const; - - const ItemFactoryInterface* factory() const; - - SessionItem* findItem(const identifier_type& id); - - template <typename T = SessionItem> std::vector<T*> topItems() const; - - template <typename T = SessionItem> T* topItem() const; - - // Methods to steer global behaviour. - - void setItemCatalogue(std::unique_ptr<ItemCatalogue> catalogue); - - void setUndoRedoEnabled(bool value); - - void clear(std::function<void(SessionItem*)> callback = {}); - - template <typename T> void registerItem(const std::string& label = {}); - -private: - friend class SessionItem; - void registerInPool(SessionItem* item); - void unregisterFromPool(SessionItem* item); - SessionItem* intern_insert(const item_factory_func_t& func, SessionItem* parent, - const TagRow& tagrow); - void intern_register(const model_type& modelType, const item_factory_func_t& func, - const std::string& label); - - struct SessionModelImpl; - std::unique_ptr<SessionModelImpl> p_impl; -}; - -//! Inserts item into given parent under given tagrow. - -template <typename T> T* SessionModel::insertItem(SessionItem* parent, const TagRow& tagrow) -{ - return static_cast<T*>(intern_insert(ItemFactoryFunction<T>(), parent, tagrow)); -} - -//! Returns top items of the given type. -//! The top item is an item that is a child of an invisible root item. - -template <typename T> std::vector<T*> SessionModel::topItems() const -{ - std::vector<T*> result; - for (auto child : rootItem()->children()) { - if (auto item = dynamic_cast<T*>(child)) - result.push_back(item); - } - - return result; -} - -//! Returns top item of the given type. If more than one item exists, return the first one. -//! The top item is an item that is a child of an invisible root item. - -template <typename T> T* SessionModel::topItem() const -{ - auto items = topItems<T>(); - return items.empty() ? nullptr : items.front(); -} - -//! Register used defined item to use with the model. It will become possible to undo/redo -//! operations with this item, as well as serialize it to/from JSON. - -template <typename T> void SessionModel::registerItem(const std::string& label) -{ - intern_register(T().modelType(), ItemFactoryFunction<T>(), label); -} - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_MODEL_SESSIONMODEL_H diff --git a/mvvm/model/mvvm/model/taginfo.cpp b/mvvm/model/mvvm/model/taginfo.cpp deleted file mode 100644 index ed38fde009dc621e41c07475255ae50b7277e11b..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/model/taginfo.cpp +++ /dev/null @@ -1,89 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/model/taginfo.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/model/taginfo.h" -#include "mvvm/utils/containerutils.h" -#include <algorithm> -#include <sstream> -#include <stdexcept> - -ModelView::TagInfo::TagInfo() : m_min(0), m_max(-1) {} - -ModelView::TagInfo::TagInfo(std::string name, int min, int max, std::vector<std::string> modelTypes) - : m_name(std::move(name)), m_min(min), m_max(max), m_modelTypes(std::move(modelTypes)) -{ - if (m_min < 0 || (m_min > m_max && m_max >= 0) || m_name.empty()) { - std::ostringstream ostr; - ostr << "Invalid constructor parameters" - << " " << m_name << " " << m_min << " " << m_max; - throw std::runtime_error(ostr.str()); - } -} - -ModelView::TagInfo ModelView::TagInfo::universalTag(std::string name, - std::vector<std::string> modelTypes) -{ - return TagInfo(std::move(name), 0, -1, std::move(modelTypes)); -} - -ModelView::TagInfo ModelView::TagInfo::propertyTag(std::string name, std::string model_type) -{ - return TagInfo(std::move(name), 1, 1, {std::move(model_type)}); -} - -std::string ModelView::TagInfo::name() const -{ - return m_name; -} - -int ModelView::TagInfo::min() const -{ - return m_min; -} - -int ModelView::TagInfo::max() const -{ - return m_max; -} - -std::vector<std::string> ModelView::TagInfo::modelTypes() const -{ - return m_modelTypes; -} - -//! Returns true if given modelType matches the list of possible model types. - -bool ModelView::TagInfo::isValidChild(const std::string& modelType) const -{ - return m_modelTypes.empty() ? true : Utils::Contains(m_modelTypes, modelType); -} - -//! Returns true if this tag is used to store single properties. -//! Properties are children that are created in SessionItem constructor using ::addProperty method. - -bool ModelView::TagInfo::isSinglePropertyTag() const -{ - return m_min == 1 && m_max == 1; -} - -bool ModelView::TagInfo::operator==(const ModelView::TagInfo& other) const -{ - return m_name == other.m_name && m_min == other.m_min && m_max == other.m_max - && m_modelTypes == other.m_modelTypes; -} - -bool ModelView::TagInfo::operator!=(const ModelView::TagInfo& other) const -{ - return !(*this == other); -} diff --git a/mvvm/model/mvvm/model/taginfo.h b/mvvm/model/mvvm/model/taginfo.h deleted file mode 100644 index f352b1cf6ee44a6df0c4d664b70a415534c65167..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/model/taginfo.h +++ /dev/null @@ -1,66 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/model/taginfo.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_MODEL_TAGINFO_H -#define BORNAGAIN_MVVM_MODEL_MVVM_MODEL_TAGINFO_H - -#include "mvvm/model_export.h" -#include <string> -#include <vector> - -namespace ModelView { - -//! Holds info about single tag for SessionItem. -//! The tag specifies information about children that can be added to a SessionItem. A tag has a -//! name, min, max allowed number of children, and vector of all modelTypes that children can have. - -class MVVM_MODEL_EXPORT TagInfo { -public: - TagInfo(); - - TagInfo(std::string name, int min, int max, std::vector<std::string> modelTypes); - - //! Constructs universal tag intended for unlimited amount of various items. - static TagInfo universalTag(std::string name, std::vector<std::string> modelTypes = {}); - - //! Constructs tag intended for single property. - static TagInfo propertyTag(std::string name, std::string model_type); - - std::string name() const; - - int min() const; - - int max() const; - - std::vector<std::string> modelTypes() const; - - bool maximumReached() const; - - bool isValidChild(const std::string& modelType) const; - - bool isSinglePropertyTag() const; - - bool operator==(const TagInfo& other) const; - bool operator!=(const TagInfo& other) const; - -private: - std::string m_name; - int m_min; - int m_max; - std::vector<std::string> m_modelTypes; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_MODEL_TAGINFO_H diff --git a/mvvm/model/mvvm/model/tagrow.cpp b/mvvm/model/mvvm/model/tagrow.cpp deleted file mode 100644 index e0309b26186fc8b447b2e3aec662edf887701c42..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/model/tagrow.cpp +++ /dev/null @@ -1,57 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/model/tagrow.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/model/tagrow.h" - -//! Constructs new tagrow representing next row in given tag. -//! No validity check. - -ModelView::TagRow ModelView::TagRow::next() const -{ - return {tag, row + 1}; -} - -//! Constructs new tagrow representing previous row in given tag. -//! No validity check. - -ModelView::TagRow ModelView::TagRow::prev() const -{ - return {tag, row - 1}; -} - -//! Returns TagRow corresponding to the append to tag_name. -//! If tag_name =="" the default name will be used in SessionItemTags context. - -ModelView::TagRow ModelView::TagRow::append(const std::string& tag_name) -{ - return {tag_name, -1}; -} - -//! Returns TagRow corresponding to prepending to tag_name. -//! If tag_name =="" the default name will be used in SessionItemTags context. - -ModelView::TagRow ModelView::TagRow::prepend(const std::string& tag_name) -{ - return {tag_name, 0}; -} - -bool ModelView::TagRow::operator==(const ModelView::TagRow& other) const -{ - return row == other.row && tag == other.tag; -} - -bool ModelView::TagRow::operator!=(const ModelView::TagRow& other) const -{ - return !(*this == other); -} diff --git a/mvvm/model/mvvm/model/tagrow.h b/mvvm/model/mvvm/model/tagrow.h deleted file mode 100644 index bf66cd94613c96d033261613811b3708b4f64bc1..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/model/tagrow.h +++ /dev/null @@ -1,49 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/model/tagrow.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_MODEL_TAGROW_H -#define BORNAGAIN_MVVM_MODEL_MVVM_MODEL_TAGROW_H - -#include "mvvm/model_export.h" -#include <string> - -namespace ModelView { - -//! Aggregate to hold (tag, row) information for SessionModel. - -class MVVM_MODEL_EXPORT TagRow { -public: - std::string tag = {}; - int row = -1; - - TagRow() {} - - TagRow(const std::string& name, int row = -1) : tag(name), row(row) {} - TagRow(const char* name, int row = -1) : tag(name), row(row) {} - - TagRow next() const; - - TagRow prev() const; - - static TagRow append(const std::string& tag_name = {}); - - static TagRow prepend(const std::string& tag_name = {}); - - bool operator==(const TagRow& other) const; - bool operator!=(const TagRow& other) const; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_MODEL_TAGROW_H diff --git a/mvvm/model/mvvm/model/variant_constants.h b/mvvm/model/mvvm/model/variant_constants.h deleted file mode 100644 index bb7ca58dca917d1ec20691c4b493e372a04fb6f9..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/model/variant_constants.h +++ /dev/null @@ -1,38 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/model/variant_constants.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_MODEL_VARIANT_CONSTANTS_H -#define BORNAGAIN_MVVM_MODEL_MVVM_MODEL_VARIANT_CONSTANTS_H - -#include <string> - -//! @file mvvm/model/mvvm/model/variant_constants.h -//! Collection of constants with supported variant names. - -namespace ModelView::Constants { - -const std::string invalid_type_name = "invalid"; -const std::string bool_type_name = "bool"; -const std::string int_type_name = "int"; -const std::string string_type_name = "std::string"; -const std::string double_type_name = "double"; -const std::string vector_double_type_name = "std::vector<double>"; -const std::string comboproperty_type_name = "ModelView::ComboProperty"; -const std::string qcolor_type_name = "QColor"; -const std::string extproperty_type_name = "ModelView::ExternalProperty"; -const std::string reallimits_type_name = "ModelView::RealLimits"; - -} // namespace ModelView::Constants - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_MODEL_VARIANT_CONSTANTS_H diff --git a/mvvm/model/mvvm/project/CMakeLists.txt b/mvvm/model/mvvm/project/CMakeLists.txt deleted file mode 100644 index 2de7a9057c4ecfe706b302e61aa0981322a0778e..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/project/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -target_sources(${library_name} PRIVATE - modelhaschangedcontroller.cpp - modelhaschangedcontroller.h - project.cpp - project.h - project_types.h - projectchangecontroller.cpp - projectchangecontroller.h - projectmanager.cpp - projectmanager.h - projectmanagerdecorator.cpp - projectmanagerdecorator.h - projectutils.cpp - projectutils.h -) diff --git a/mvvm/model/mvvm/project/modelhaschangedcontroller.cpp b/mvvm/model/mvvm/project/modelhaschangedcontroller.cpp deleted file mode 100644 index 12642de6f1476b03f1bd0100f2e2c1e4cea82b1a..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/project/modelhaschangedcontroller.cpp +++ /dev/null @@ -1,52 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/project/modelhaschangedcontroller.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/project/modelhaschangedcontroller.h" - -using namespace ModelView; - -//! Constructor of ModelHasChangedController. -//! Acccept 'model' to listen, and a 'callback' to report about changes in a model. - -ModelHasChangedController::ModelHasChangedController(SessionModel* model, callback_t callback) - : ModelListener(model), m_callback(callback) -{ - setOnDataChange([this](auto, auto) { process_change(); }); - setOnItemInserted([this](auto, auto) { process_change(); }); - setOnItemRemoved([this](auto, auto) { process_change(); }); - setOnModelReset([this](auto) { process_change(); }); -} - -//! Returns true if the model was changed since last call of resetChanged. - -bool ModelHasChangedController::hasChanged() const -{ - return m_has_changed; -} - -//! Reset has_changed flag. - -void ModelHasChangedController::resetChanged() -{ - m_has_changed = false; -} - -//! Sets 'has_changed' flag and reports back to client. - -void ModelHasChangedController::process_change() -{ - m_has_changed = true; - if (m_callback) - m_callback(); -} diff --git a/mvvm/model/mvvm/project/modelhaschangedcontroller.h b/mvvm/model/mvvm/project/modelhaschangedcontroller.h deleted file mode 100644 index f2793beed9edb7c7127b126f26227bff76c6efee..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/project/modelhaschangedcontroller.h +++ /dev/null @@ -1,44 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/project/modelhaschangedcontroller.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_PROJECT_MODELHASCHANGEDCONTROLLER_H -#define BORNAGAIN_MVVM_MODEL_MVVM_PROJECT_MODELHASCHANGEDCONTROLLER_H - -#include "mvvm/signals/modellistener.h" -#include <functional> - -namespace ModelView { - -//! Tracks changes in the model. -//! Allows to check if model has been changed (e.g. modified, inserted or removed items) since last -//! call of ::resetChanged(). - -class MVVM_MODEL_EXPORT ModelHasChangedController : public ModelListener<SessionModel> { -public: - using callback_t = std::function<void()>; - ModelHasChangedController(SessionModel* model, callback_t callback = {}); - - bool hasChanged() const; - - void resetChanged(); - -private: - void process_change(); - bool m_has_changed{false}; - callback_t m_callback; //! informs the user about change in the model -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_PROJECT_MODELHASCHANGEDCONTROLLER_H diff --git a/mvvm/model/mvvm/project/project.cpp b/mvvm/model/mvvm/project/project.cpp deleted file mode 100644 index 2dad145672d489ce2c45ef9f1ce45a69b3f9334a..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/project/project.cpp +++ /dev/null @@ -1,86 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/project/project.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/project/project.h" -#include "mvvm/factories/modeldocumentfactory.h" -#include "mvvm/project/project_types.h" -#include "mvvm/project/projectchangecontroller.h" -#include "mvvm/project/projectutils.h" -#include "mvvm/utils/fileutils.h" -#include <functional> - -using namespace ModelView; - -struct Project::ProjectImpl { - std::string m_project_dir; - ProjectContext m_context; - ProjectChangedController m_change_controller; - - ProjectImpl(const ProjectContext& context) - : m_context(context) - , m_change_controller(context.m_models_callback(), context.m_modified_callback) - { - } - - //! Returns list of models which are subject to save/load. - std::vector<SessionModel*> models() const { return m_context.m_models_callback(); } - - //! Processes all models one by one and either save or load them to/from given directory. - //! Template parameter `method` specifies ModelDocumentInterface's method to use. - template <typename T> bool process(const std::string& dirname, T method) - { - if (!Utils::exists(dirname)) - return false; - - for (auto model : models()) { - auto document = CreateJsonDocument({model}); - auto filename = Utils::join(dirname, GUI::Project::Utils::SuggestFileName(*model)); - std::invoke(method, document, filename); - } - m_project_dir = dirname; - m_change_controller.resetChanged(); - return true; - } -}; - -Project::Project(const ProjectContext& context) : p_impl(std::make_unique<ProjectImpl>(context)) {} - -Project::~Project() = default; - -//! Returns the full path to a project directory. It is a name where the project has been last time -//! saved, or loaded from. - -std::string Project::projectDir() const -{ - return p_impl->m_project_dir; -} - -//! Saves all models to a given directory. Directory should exist. -//! Provided name will become 'projectDir'. - -bool Project::save(const std::string& dirname) const -{ - return p_impl->process(dirname, &ModelDocumentInterface::save); -} - -//! Loads all models from the given directory. -bool Project::load(const std::string& dirname) -{ - return p_impl->process(dirname, &ModelDocumentInterface::load); -} - -bool Project::isModified() const -{ - return p_impl->m_change_controller.hasChanged(); -} diff --git a/mvvm/model/mvvm/project/project.h b/mvvm/model/mvvm/project/project.h deleted file mode 100644 index fff9a3e34e5541cc805e0f1be52502a7c6186acc..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/project/project.h +++ /dev/null @@ -1,48 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/project/project.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_PROJECT_PROJECT_H -#define BORNAGAIN_MVVM_MODEL_MVVM_PROJECT_PROJECT_H - -#include "mvvm/interfaces/projectinterface.h" -#include <memory> - -namespace ModelView { - -struct ProjectContext; - -//! Project represents content of all application models in a folder on disk. -//! Responsible for saving/loading application models to/from disk. - -class MVVM_MODEL_EXPORT Project : public ModelView::ProjectInterface { -public: - Project(const ProjectContext& context); - ~Project(); - - std::string projectDir() const override; - - bool save(const std::string& dirname) const override; - - bool load(const std::string& dirname) override; - - bool isModified() const override; - -private: - struct ProjectImpl; - std::unique_ptr<ProjectImpl> p_impl; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_PROJECT_PROJECT_H diff --git a/mvvm/model/mvvm/project/project_types.h b/mvvm/model/mvvm/project/project_types.h deleted file mode 100644 index 4f7f3bf0c53c932b8d08bd5813fadb497fb26b0c..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/project/project_types.h +++ /dev/null @@ -1,65 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/project/project_types.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_PROJECT_PROJECT_TYPES_H -#define BORNAGAIN_MVVM_MODEL_MVVM_PROJECT_PROJECT_TYPES_H - -#include "mvvm/model_export.h" -#include <functional> -#include <string> -#include <vector> - -namespace ModelView { - -class SessionModel; - -//! Possible user answers on question "Project was modified". -enum class SaveChangesAnswer { SAVE = 0, DISCARD = 1, CANCEL = 2 }; - -//! Provides necessary information for Project construction. - -struct MVVM_MODEL_EXPORT ProjectContext { - //!< To notify about the change of the project with respect to what was written on disk. - using modified_callback_t = std::function<void()>; - - //! To ask for a vector of models to save/load to/from disk. - //! This is intentionally obtained via callback since save request might come after - //! the Project construction. - using models_callback_t = std::function<std::vector<SessionModel*>()>; - - modified_callback_t m_modified_callback; - models_callback_t m_models_callback; -}; - -//! Defines the context to interact with the user regarding save/save-as/create-new project -//! scenarious. - -struct MVVM_MODEL_EXPORT UserInteractionContext { - //!< To ask the user to select existing directory, returns full path to the directory. - using select_dir_callback_t = std::function<"">; - - //!< To ask the user to create a new directory, returns full path to the directory. - using create_dir_callback_t = std::function<"">; - - //!< To ask the user what to do with modified project. - using answer_callback_t = std::function<SaveChangesAnswer()>; - - select_dir_callback_t m_select_dir_callback; - create_dir_callback_t m_create_dir_callback; - answer_callback_t m_answer_callback; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_PROJECT_PROJECT_TYPES_H diff --git a/mvvm/model/mvvm/project/projectchangecontroller.cpp b/mvvm/model/mvvm/project/projectchangecontroller.cpp deleted file mode 100644 index 24fd2317d4d981a48a067b992c6c34dccad11150..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/project/projectchangecontroller.cpp +++ /dev/null @@ -1,82 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/project/projectchangecontroller.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/project/projectchangecontroller.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/project/modelhaschangedcontroller.h" - -using namespace ModelView; - -struct ProjectChangedController::ProjectChangedControllerImpl { - std::vector<SessionModel*> m_models; - std::vector<std::unique_ptr<ModelHasChangedController>> change_controllers; - callback_t m_project_changed_callback; - bool m_project_has_changed{false}; - - ProjectChangedControllerImpl(const std::vector<SessionModel*>& models, callback_t callback) - : m_models(models), m_project_changed_callback(callback) - { - create_controllers(); - } - - void create_controllers() - { - auto on_model_changed = [this]() { onProjectHasChanged(); }; - change_controllers.clear(); - for (auto model : m_models) - change_controllers.emplace_back( - std::make_unique<ModelHasChangedController>(model, on_model_changed)); - } - - bool hasChanged() const { return m_project_has_changed; } - - void resetChanged() - { - for (auto& controller : change_controllers) - controller->resetChanged(); - m_project_has_changed = false; - } - - void onProjectHasChanged() - { - if (!m_project_has_changed) { - m_project_has_changed = true; - if (m_project_changed_callback) - m_project_changed_callback(); - } - } -}; - -ProjectChangedController::ProjectChangedController(const std::vector<SessionModel*>& models, - callback_t project_changed_callback) - : p_impl(std::make_unique<ProjectChangedControllerImpl>(models, project_changed_callback)) -{ -} - -ProjectChangedController::~ProjectChangedController() = default; - -//! Returns true if the change in the models has been registered since the last call of -//! resetChanged. - -bool ProjectChangedController::hasChanged() const -{ - return p_impl->hasChanged(); -} - -//! Reset controller to initial state, pretending that no changes has been registered. - -void ProjectChangedController::resetChanged() -{ - return p_impl->resetChanged(); -} diff --git a/mvvm/model/mvvm/project/projectchangecontroller.h b/mvvm/model/mvvm/project/projectchangecontroller.h deleted file mode 100644 index 1b380bfa034524e5b0ff689015fdbc763240e4c6..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/project/projectchangecontroller.h +++ /dev/null @@ -1,54 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/project/projectchangecontroller.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_PROJECT_PROJECTCHANGECONTROLLER_H -#define BORNAGAIN_MVVM_MODEL_MVVM_PROJECT_PROJECTCHANGECONTROLLER_H - -#include "mvvm/model_export.h" -#include <functional> -#include <memory> -#include <vector> - -namespace ModelView { - -class SessionModel; -class ModelHasChangedController; - -//! Tracks changes in all models. -//! Allows to check if one or more models have been changed since last call of ::resetChanged(). -//! This is intended to work together with the Project class. It will take care of calling -//! resetChanged after own saving. - -//! To avoid extra signaling while being in already "changed" mode, the controller reports only -//! once. - -class MVVM_MODEL_EXPORT ProjectChangedController { -public: - using callback_t = std::function<void()>; - ProjectChangedController(const std::vector<SessionModel*>& models, - callback_t project_changed_callback = {}); - ~ProjectChangedController(); - - bool hasChanged() const; - - void resetChanged(); - -private: - struct ProjectChangedControllerImpl; - std::unique_ptr<ProjectChangedControllerImpl> p_impl; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_PROJECT_PROJECTCHANGECONTROLLER_H diff --git a/mvvm/model/mvvm/project/projectmanager.cpp b/mvvm/model/mvvm/project/projectmanager.cpp deleted file mode 100644 index 5d564e23faa8e9fbeffcb4b5898aab5e58571391..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/project/projectmanager.cpp +++ /dev/null @@ -1,132 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/project/projectmanager.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/project/projectmanager.h" -#include "mvvm/interfaces/projectinterface.h" -#include "mvvm/project/project_types.h" -#include "mvvm/project/projectutils.h" - -using namespace ModelView; - -namespace { -const bool succeeded = true; -const bool failed = false; -} // namespace - -struct ProjectManager::ProjectManagerImpl { - std::unique_ptr<ProjectInterface> m_current_project; - ProjectContext m_project_context; - - ProjectManagerImpl(ProjectContext context) : m_project_context(std::move(context)) - { - createNewProject(); - } - - //! Closes current project. Used in assumption that project was already saved. - void createNewProject() - { - m_current_project = GUI::Project::Utils::CreateUntitledProject(m_project_context); - } - - //! Returns true if the project has directory already defined. - bool projectHasDir() const { return !m_current_project->projectDir().empty(); } - - //! Saves project in project directory. If directory is not defined - bool saveCurrentProject() { return saveCurrentProjectAs(m_current_project->projectDir()); } - - //! Saves the project into a given directory. - bool saveCurrentProjectAs(const std::string& dirname) - { - return m_current_project->save(dirname); - } - - //! Loads the project from a given directory. - bool loadFrom(const std::string& dirname) { return m_current_project->load(dirname); } - - //! Returns true if project has been modified after the last save. - bool isModified() const { return m_current_project->isModified(); } -}; - -//! Constructor for ProjectManager. - -ProjectManager::ProjectManager(const ProjectContext& context) - : p_impl(std::make_unique<ProjectManagerImpl>(context)) -{ -} - -ProjectManager::~ProjectManager() = default; - -//! Creates a new project, returns 'true' in the case of success. -//! Current project has to be in a saved state, otherwise will return false. - -bool ProjectManager::createNewProject(const std::string& dirname) -{ - if (p_impl->isModified()) - return failed; - p_impl->createNewProject(); - return p_impl->saveCurrentProjectAs(dirname); -} - -//! Saves current project, returns 'true' in the case of success. -//! The project should have a project directory defined to succeed. - -bool ProjectManager::saveCurrentProject() -{ - if (!p_impl->projectHasDir()) - return failed; - return p_impl->saveCurrentProject(); -} - -//! Saves the project under a given directory, returns true in the case of success. -//! The directory should exist already. - -bool ProjectManager::saveProjectAs(const std::string& dirname) -{ - return p_impl->saveCurrentProjectAs(dirname); -} - -//! Opens existing project, returns 'true' in the case of success. -//! Current project should be in a saved state, new project should exist. - -bool ProjectManager::openExistingProject(const std::string& dirname) -{ - if (p_impl->isModified()) - return failed; - p_impl->createNewProject(); - return p_impl->loadFrom(dirname); -} - -//! Returns current project directory. - -std::string ProjectManager::currentProjectDir() const -{ - return p_impl->m_current_project ? p_impl->m_current_project->projectDir() : ""; -} - -//! Returns true if project was modified since last save. - -bool ProjectManager::isModified() const -{ - return p_impl->isModified(); -} - -//! Closes current project (without saving). -//! No checks whether it is modified or not being performed. - -bool ProjectManager::closeCurrentProject() const -{ - // no special operation is required to close the project - p_impl->createNewProject(); // ready for further actions - return succeeded; -} diff --git a/mvvm/model/mvvm/project/projectmanager.h b/mvvm/model/mvvm/project/projectmanager.h deleted file mode 100644 index 5e728132c5f531cd66c8aded4dbd00b2c3a990d0..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/project/projectmanager.h +++ /dev/null @@ -1,61 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/project/projectmanager.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_PROJECT_PROJECTMANAGER_H -#define BORNAGAIN_MVVM_MODEL_MVVM_PROJECT_PROJECTMANAGER_H - -#include "mvvm/interfaces/projectmanagerinterface.h" -#include <memory> - -namespace ModelView { - -struct ProjectContext; - -//! Responsible for handling new/save/save-as/close Project logic, where the Project represents -//! a collection of serialized application models in the project directory. - -//! This ProjectManager requires certain prerequisites to function properly: for example, -//! the creation of a new project will be possible only if the old project is in a saved state. See -//! description to the class methods. - -class MVVM_MODEL_EXPORT ProjectManager : public ModelView::ProjectManagerInterface { -public: - ProjectManager(const ProjectContext& context); - ~ProjectManager() override; - - ProjectManager(const ProjectManager& other) = delete; - ProjectManager& operator=(const ProjectManager& other) = delete; - - bool createNewProject(const std::string& dirname) override; - - bool saveCurrentProject() override; - - bool saveProjectAs(const std::string& dirname) override; - - bool openExistingProject(const std::string& dirname) override; - - std::string currentProjectDir() const override; - - bool isModified() const override; - - bool closeCurrentProject() const override; - -private: - struct ProjectManagerImpl; - std::unique_ptr<ProjectManagerImpl> p_impl; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_PROJECT_PROJECTMANAGER_H diff --git a/mvvm/model/mvvm/project/projectmanagerdecorator.cpp b/mvvm/model/mvvm/project/projectmanagerdecorator.cpp deleted file mode 100644 index b40d2986abbbab20927fd9cca187785a66459f68..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/project/projectmanagerdecorator.cpp +++ /dev/null @@ -1,192 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/project/projectmanagerdecorator.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/project/projectmanagerdecorator.h" -#include "mvvm/interfaces/projectinterface.h" -#include "mvvm/project/project_types.h" -#include "mvvm/project/projectmanager.h" -#include <stdexcept> - -using namespace ModelView; - -namespace { -const bool succeeded = true; -const bool failed = false; -} // namespace - -struct ProjectManagerDecorator::ProjectManagerImpl { - ProjectContext m_project_context; - UserInteractionContext m_user_context; - std::unique_ptr<ProjectManager> project_manager; - - ProjectManagerImpl(ProjectContext project_context, UserInteractionContext user_context) - : m_project_context(std::move(project_context)), m_user_context(std::move(user_context)) - { - project_manager = std::make_unique<ProjectManager>(m_project_context); - } - - //! Returns true if the project has directory already defined. - bool projectHasDir() const { return !project_manager->currentProjectDir().empty(); } - - //! Saves project in project directory. If directory is not defined, will acquire - //! directory susing callback provided. - bool saveCurrentProject() - { - // Feature FIXME?: already saved project (i.e. isModified=false) will be saved again. - // Files will be same, but creation date will be changed. - - auto save_dir = - projectHasDir() ? project_manager->currentProjectDir() : acquireNewProjectDir(); - return saveCurrentProjectAs(save_dir); - } - - //! Saves current project under directory selected. - bool saveCurrentProjectAs(const std::string& dirname) - { - // empty dirname varible means 'cancel' during directory selection - return dirname.empty() ? failed : project_manager->saveProjectAs(dirname); - } - - std::string currentProjectDir() const { return project_manager->currentProjectDir(); } - - bool isModified() const { return project_manager->isModified(); } - - //! Performs saving of previous project before creating a new one. - bool saveBeforeClosing() - { - if (isModified()) { - switch (acquireSaveChangesAnswer()) { - case SaveChangesAnswer::SAVE: - return saveCurrentProject(); - case SaveChangesAnswer::CANCEL: - return failed; // saving was interrupted by the 'cancel' button - case SaveChangesAnswer::DISCARD: - project_manager->closeCurrentProject(); - return succeeded; - default: - throw std::runtime_error("Error in ProjectManager: unexpected answer."); - } - } - return succeeded; - } - - //! Asks the user whether to save/cancel/discard the project using callback provided. - SaveChangesAnswer acquireSaveChangesAnswer() const - { - if (!m_user_context.m_answer_callback) - throw std::runtime_error("Error in ProjectManager: absent save_callback"); - return m_user_context.m_answer_callback(); - } - - //! Acquire the name of the new project directory using callback provided. - std::string acquireNewProjectDir() - { - if (!m_user_context.m_create_dir_callback) - throw std::runtime_error("Error in ProjectManager: absent creat_dir callback."); - return m_user_context.m_create_dir_callback(); - } - - //! Acquire the name of the existing project directory using callback provided. - std::string acquireExistingProjectDir() - { - if (!m_user_context.m_select_dir_callback) - throw std::runtime_error("Error in ProjectManager: absent open_dir callback."); - return m_user_context.m_select_dir_callback(); - } -}; - -//! Constructor for ProjectManagerDecorator. - -ProjectManagerDecorator::ProjectManagerDecorator(const ProjectContext& project_context, - const UserInteractionContext& user_context) - : p_impl(std::make_unique<ProjectManagerImpl>(project_context, user_context)) -{ -} - -ProjectManagerDecorator::~ProjectManagerDecorator() = default; - -//! Creates a new project in the directory 'dirname', returns 'true' in the case of success. -//! The directory should exist. -//! If provided name is empty, will call directory selector dialog using callback provided. -//! If current project is in unsaved state, will perform 'save-before-closing' procedure before -//! proceeding further. - -bool ProjectManagerDecorator::createNewProject(const std::string& dirname) -{ - if (!p_impl->saveBeforeClosing()) - return failed; - - auto project_dir = dirname.empty() ? p_impl->acquireNewProjectDir() : dirname; - // empty project_dir string denotes 'cancel' during directory creation dialog - return project_dir.empty() ? failed : p_impl->project_manager->createNewProject(project_dir); -} - -//! Saves current project, returns 'true' in the case of success. -//! The project should have a project directory defined, if it is not the case, it will -//! launch the procedure of directory selection using callback provided. - -bool ProjectManagerDecorator::saveCurrentProject() -{ - return p_impl->saveCurrentProject(); -} - -//! Saves the project under a given directory, returns true in the case of success. -//! The directory should exist already. If provided 'dirname' variable is empty, -//! it will acquire a new project directory using dialog provided. - -bool ProjectManagerDecorator::saveProjectAs(const std::string& dirname) -{ - auto project_dir = dirname.empty() ? p_impl->acquireNewProjectDir() : dirname; - // empty project_dir variable denotes 'cancel' during directory creation dialog - return project_dir.empty() ? failed : p_impl->saveCurrentProjectAs(project_dir); -} - -//! Opens existing project, returns 'true' in the case of success. -//! If provided name is empty, will call directory selector dialog using callback provided. -//! If current project is in unsaved state, it will perform 'save-before-closing' procedure before -//! proceeding further. - -bool ProjectManagerDecorator::openExistingProject(const std::string& dirname) -{ - if (!p_impl->saveBeforeClosing()) - return failed; - auto project_dir = dirname.empty() ? p_impl->acquireExistingProjectDir() : dirname; - // empty project_dir variable denotes 'cancel' during directory selection dialog - return project_dir.empty() ? failed : p_impl->project_manager->openExistingProject(project_dir); -} - -//! Returns current project directory. - -std::string ProjectManagerDecorator::currentProjectDir() const -{ - return p_impl->currentProjectDir(); -} - -//! Returns true if project was modified since last save. - -bool ProjectManagerDecorator::isModified() const -{ - return p_impl->isModified(); -} - -//! Closes current project, returns 'true' if succeeded. -//! Will show the dialog, via callback provided, asking the user whether to save/discard/cancel. -//! Returns 'false' only if user has selected 'cancel' button. - -bool ProjectManagerDecorator::closeCurrentProject() const -{ - if (!p_impl->saveBeforeClosing()) - return failed; - return succeeded; -} diff --git a/mvvm/model/mvvm/project/projectmanagerdecorator.h b/mvvm/model/mvvm/project/projectmanagerdecorator.h deleted file mode 100644 index f759aff59ea116ab22e5856b97e2864c821cf924..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/project/projectmanagerdecorator.h +++ /dev/null @@ -1,62 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/project/projectmanagerdecorator.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_PROJECT_PROJECTMANAGERDECORATOR_H -#define BORNAGAIN_MVVM_MODEL_MVVM_PROJECT_PROJECTMANAGERDECORATOR_H - -#include "mvvm/interfaces/projectmanagerinterface.h" -#include <memory> - -namespace ModelView { - -struct ProjectContext; -struct UserInteractionContext; - -//! Decorator for ProjectManager to provide interaction with the user on open/save-as requests. -//! It relies on the same interface and adds additional logic related to "unsaved" data. - -//! For example, on createNewProject it will check if previous project is saved, and will -//! call external dialog save/discard/cancel via provided callback. - -class MVVM_MODEL_EXPORT ProjectManagerDecorator : public ProjectManagerInterface { -public: - ProjectManagerDecorator(const ProjectContext& project_context, - const UserInteractionContext& user_context); - - ~ProjectManagerDecorator() override; - ProjectManagerDecorator(const ProjectManagerDecorator& other) = delete; - ProjectManagerDecorator& operator=(const ProjectManagerDecorator& other) = delete; - - bool createNewProject(const std::string& dirname = {}) override; - - bool saveCurrentProject() override; - - bool saveProjectAs(const std::string& dirname = {}) override; - - bool openExistingProject(const std::string& dirname = {}) override; - - std::string currentProjectDir() const override; - - bool isModified() const override; - - bool closeCurrentProject() const override; - -private: - struct ProjectManagerImpl; - std::unique_ptr<ProjectManagerImpl> p_impl; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_PROJECT_PROJECTMANAGERDECORATOR_H diff --git a/mvvm/model/mvvm/project/projectutils.cpp b/mvvm/model/mvvm/project/projectutils.cpp deleted file mode 100644 index 72a0cac24cfae7413e10197c5faf008ca437d46e..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/project/projectutils.cpp +++ /dev/null @@ -1,76 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/project/projectutils.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/project/projectutils.h" -#include "mvvm/interfaces/applicationmodelsinterface.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/project/project.h" -#include "mvvm/project/project_types.h" -#include "mvvm/utils/fileutils.h" -#include <cctype> - -namespace { -const std::string json_extention = ".json"; -const std::string untitled_name = "Untitled"; -} // namespace - -namespace ModelView { - -//! Suggests file name which can be used to store json content of given model. -//! Uses the model type to construct a filename: MaterialModel -> materialmodel.json - -std::string GUI::Project::Utils::SuggestFileName(const SessionModel& model) -{ - std::string result = model.modelType(); - std::transform(result.begin(), result.end(), result.begin(), ::tolower); - return result + json_extention; -} - -//! Returns 'true' if given directory might be a project directory. -//! This simplified check counts number of files with json extention. - -bool GUI::Project::Utils::IsPossibleProjectDir(const std::string& project_dir) -{ - return !Utils::FindFiles(project_dir, json_extention).empty(); -} - -//! Creates new untitled project. - -std::unique_ptr<ProjectInterface> -GUI::Project::Utils::CreateUntitledProject(const ProjectContext& context) -{ - return std::make_unique<Project>(context); -} - -//! Returns a MainWindow title for given project. - -std::string GUI::Project::Utils::ProjectWindowTitle(const ProjectInterface& project) -{ - return ProjectWindowTitle(project.projectDir(), project.isModified()); -} - -//! Returns a title composed from last part of project path, and `is_modified` flag. -//! Project without projectDir will be "Untitled", modified project will be "*Untitled". -//! Project with projectDir in "/home/user/project1" will get title "project1". - -std::string GUI::Project::Utils::ProjectWindowTitle(const std::string& project_dir, - bool is_modified) -{ - auto pos = project_dir.find_last_of('/'); - auto project_name = (pos == std::string::npos ? untitled_name : project_dir.substr(pos + 1)); - auto unsaved_status = is_modified ? "*" : ""; - return unsaved_status + project_name; -} - -} // namespace ModelView diff --git a/mvvm/model/mvvm/project/projectutils.h b/mvvm/model/mvvm/project/projectutils.h deleted file mode 100644 index cfb6edafd6bc1635e7c6df9c8eda54572e7304e4..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/project/projectutils.h +++ /dev/null @@ -1,48 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/project/projectutils.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_PROJECT_PROJECTUTILS_H -#define BORNAGAIN_MVVM_MODEL_MVVM_PROJECT_PROJECTUTILS_H - -#include "mvvm/model_export.h" -#include <memory> -#include <string> -#include <vector> - -namespace ModelView { - -class SessionModel; -class ProjectInterface; -struct ProjectContext; - -//! Collection of utility functions to handle project saving and loading. - -namespace GUI::Project::Utils { - -MVVM_MODEL_EXPORT std::string SuggestFileName(const SessionModel& model); - -MVVM_MODEL_EXPORT bool IsPossibleProjectDir(const std::string& project_dir); - -MVVM_MODEL_EXPORT std::unique_ptr<ProjectInterface> -CreateUntitledProject(const ProjectContext& context); - -MVVM_MODEL_EXPORT std::string ProjectWindowTitle(const ProjectInterface& project); - -MVVM_MODEL_EXPORT std::string ProjectWindowTitle(const std::string& project_dir, bool is_modified); - -} // namespace GUI::Project::Utils - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_PROJECT_PROJECTUTILS_H diff --git a/mvvm/model/mvvm/serialization/CMakeLists.txt b/mvvm/model/mvvm/serialization/CMakeLists.txt deleted file mode 100644 index 64a9d95b90bfc4c19549063379ab5dcab1775e1f..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/serialization/CMakeLists.txt +++ /dev/null @@ -1,35 +0,0 @@ -target_sources(${library_name} PRIVATE - compatibilityutils.cpp - compatibilityutils.h - jsonconverterinterfaces.h - jsondocument.cpp - jsondocument.h - jsonitem_types.h - jsonitembackupstrategy.cpp - jsonitembackupstrategy.h - jsonitemcontainerconverter.cpp - jsonitemcontainerconverter.h - jsonitemconverter.cpp - jsonitemconverter.h - jsonitemconverterinterface.h - jsonitemcopystrategy.cpp - jsonitemcopystrategy.h - jsonitemdataconverter.cpp - jsonitemdataconverter.h - jsonitemdataconverterinterface.h - jsonitemformatassistant.cpp - jsonitemformatassistant.h - jsonitemtagsconverter.cpp - jsonitemtagsconverter.h - jsonmodelconverter.cpp - jsonmodelconverter.h - jsonmodelconverterinterface.h - jsontaginfoconverter.cpp - jsontaginfoconverter.h - jsontaginfoconverterinterface.h - jsonutils.cpp - jsonutils.h - jsonvariantconverter.cpp - jsonvariantconverter.h - jsonvariantconverterinterface.h -) diff --git a/mvvm/model/mvvm/serialization/compatibilityutils.cpp b/mvvm/model/mvvm/serialization/compatibilityutils.cpp deleted file mode 100644 index eb276955fe8ef27274c0e4bda0aba1347e2dde77..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/serialization/compatibilityutils.cpp +++ /dev/null @@ -1,79 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/serialization/compatibilityutils.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/serialization/compatibilityutils.h" -#include "mvvm/model/groupitem.h" -#include "mvvm/model/sessionitemcontainer.h" -#include "mvvm/model/sessionitemdata.h" -#include <set> - -namespace ModelView ::Compatibility { - -/* -Returns `true` if given TagInfo is compatible with given container. -Here, `container` is what exists at runtime, `taginfo` has been obtained from the serialization. -Container is considered to be compatible (i.e. can be updated from serialized content), if it has -exactly same tag, and it is empty. -*/ - -bool IsCompatibleUniversalTag(const SessionItemContainer& container, const TagInfo& taginfo) -{ - auto container_taginfo = container.tagInfo(); - - bool is_empty = container.empty(); - bool both_are_universal = - !container_taginfo.isSinglePropertyTag() && !taginfo.isSinglePropertyTag(); - bool same_tags = container_taginfo == taginfo; - - return both_are_universal && same_tags && is_empty; -} - -/* -Returns `true` if given TagInfo is a single property tag which is compatible with given container. -Here, `container` is what exists at runtime, `taginfo` has been obtained from the serialization. -Container is considered to be compatible (i.e. can be updated from serialized content), if it has -exactly same tag, and property item ready for update. -*/ - -bool IsCompatibleSinglePropertyTag(const SessionItemContainer& container, const TagInfo& taginfo) -{ - auto container_taginfo = container.tagInfo(); - - bool has_item = !container.empty(); - bool both_are_properties = - container_taginfo.isSinglePropertyTag() && taginfo.isSinglePropertyTag(); - bool same_tags = container_taginfo == taginfo; - - return both_are_properties && same_tags && has_item; -} - -/* -Returns `true` if given TagInfo is compatible with given container. -Here, `container` is what exists at runtime, `taginfo` has been obtained from the serialization. -Container is considered to be compatible (i.e. can be updated from serialized content), -if it has exactly same tag, and it's name corresponds to GroupItem. -*/ - -bool IsCompatibleGroupTag(const SessionItemContainer& container, const TagInfo& taginfo) -{ - auto container_taginfo = container.tagInfo(); - bool has_item = !container.empty(); - bool same_tags = container_taginfo == taginfo; - bool both_are_universal = - !container_taginfo.isSinglePropertyTag() && !taginfo.isSinglePropertyTag(); - bool valid_tag_name = taginfo.name() == GroupItem::T_GROUP_ITEMS; - return both_are_universal && same_tags && has_item && valid_tag_name; -} - -} // namespace ModelView::Compatibility diff --git a/mvvm/model/mvvm/serialization/compatibilityutils.h b/mvvm/model/mvvm/serialization/compatibilityutils.h deleted file mode 100644 index 0810cb196a162c5cce08d9615461522a2e855501..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/serialization/compatibilityutils.h +++ /dev/null @@ -1,54 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/serialization/compatibilityutils.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_SERIALIZATION_COMPATIBILITYUTILS_H -#define BORNAGAIN_MVVM_MODEL_MVVM_SERIALIZATION_COMPATIBILITYUTILS_H - -//! @file mvvm/model/mvvm/serialization/compatibilityutils.h -//! @brief Place for utils to fix back compatibility of serialized projects. - -#include "mvvm/model_export.h" -#include <memory> - -namespace ModelView { - -class SessionItemData; -class SessionItemContainer; -class TagInfo; - -namespace Compatibility { - -//! Returns `true` if given TagInfo is compatible with given container. -//! See explanations in the code. - -MVVM_MODEL_EXPORT -bool IsCompatibleUniversalTag(const SessionItemContainer& container, const TagInfo& taginfo); - -//! Returns `true` if given TagInfo is a single property tag which is compatible with given -//! container. See more explanations in the code. - -MVVM_MODEL_EXPORT -bool IsCompatibleSinglePropertyTag(const SessionItemContainer& container, const TagInfo& taginfo); - -//! Returns `true` if given TagInfo is a tag from GroupItem which is compatible with given -//! container. See more explanations in the code. - -MVVM_MODEL_EXPORT bool IsCompatibleGroupTag(const SessionItemContainer& container, - const TagInfo& taginfo); - -} // namespace Compatibility - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_SERIALIZATION_COMPATIBILITYUTILS_H diff --git a/mvvm/model/mvvm/serialization/jsonconverterinterfaces.h b/mvvm/model/mvvm/serialization/jsonconverterinterfaces.h deleted file mode 100644 index 2c6f4dd2a74075cd919a5754af3cbe2580343329..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/serialization/jsonconverterinterfaces.h +++ /dev/null @@ -1,24 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/serialization/jsonconverterinterfaces.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_SERIALIZATION_JSONCONVERTERINTERFACES_H -#define BORNAGAIN_MVVM_MODEL_MVVM_SERIALIZATION_JSONCONVERTERINTERFACES_H - -#include "mvvm/serialization/jsonitemconverterinterface.h" -#include "mvvm/serialization/jsonitemdataconverterinterface.h" -#include "mvvm/serialization/jsonmodelconverterinterface.h" -#include "mvvm/serialization/jsontaginfoconverterinterface.h" -#include "mvvm/serialization/jsonvariantconverterinterface.h" - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_SERIALIZATION_JSONCONVERTERINTERFACES_H diff --git a/mvvm/model/mvvm/serialization/jsondocument.cpp b/mvvm/model/mvvm/serialization/jsondocument.cpp deleted file mode 100644 index 4974dc84548a041123262c3dbfef631c8dd0e8b7..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/serialization/jsondocument.cpp +++ /dev/null @@ -1,84 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/serialization/jsondocument.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/serialization/jsondocument.h" -#include "mvvm/factories/modelconverterfactory.h" -#include "mvvm/model/sessionmodel.h" -#include <QFile> -#include <QJsonArray> -#include <QJsonDocument> -#include <QJsonObject> -#include <sstream> -#include <stdexcept> - -using namespace ModelView; - -struct JsonDocument::JsonDocumentImpl { - std::vector<SessionModel*> models; - JsonDocumentImpl(const std::vector<SessionModel*>& models) : models(models) {} -}; - -JsonDocument::JsonDocument(const std::vector<SessionModel*>& models) - : p_impl(std::make_unique<JsonDocumentImpl>(models)) -{ -} - -//! Saves models on disk. -void JsonDocument::save(const std::string& file_name) const -{ - auto converter = ModelView::CreateModelProjectConverter(); - QJsonArray array; - - for (auto model : p_impl->models) - array.push_back(converter->to_json(*model)); - - QJsonDocument document(array); - QFile file(QString::fromStdString(file_name)); - - if (!file.open(QIODevice::WriteOnly)) - throw std::runtime_error("Error in JsonDocument: can't save the file '" + file_name + "'"); - - file.write(document.toJson()); - - file.close(); -} - -//! Loads models from disk. If models have some data already, it will be rewritten. - -void JsonDocument::load(const std::string& file_name) -{ - QFile file(QString::fromStdString(file_name)); - if (!file.open(QIODevice::ReadOnly)) - throw std::runtime_error("Error in JsonDocument: can't read the file '" + file_name + "'"); - - auto document = QJsonDocument::fromJson(file.readAll()); - auto array = document.array(); - if (array.size() != static_cast<int>(p_impl->models.size())) { - std::ostringstream ostr; - ostr << "Error in JsonDocument: number of application models " << p_impl->models.size() - << " and number of json models " << array.size() << " doesn't match"; - throw std::runtime_error(ostr.str()); - } - - auto converter = ModelView::CreateModelProjectConverter(); - int index(0); - for (auto model : p_impl->models) { - converter->from_json(array.at(index).toObject(), *model); - ++index; - } - - file.close(); -} - -JsonDocument::~JsonDocument() = default; diff --git a/mvvm/model/mvvm/serialization/jsondocument.h b/mvvm/model/mvvm/serialization/jsondocument.h deleted file mode 100644 index bbee9147ce4edb48a378309d4d9ee5261efd6b2b..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/serialization/jsondocument.h +++ /dev/null @@ -1,44 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/serialization/jsondocument.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_SERIALIZATION_JSONDOCUMENT_H -#define BORNAGAIN_MVVM_MODEL_MVVM_SERIALIZATION_JSONDOCUMENT_H - -#include "mvvm/interfaces/modeldocumentinterface.h" -#include <memory> -#include <vector> - -namespace ModelView { - -class SessionModel; - -//! Saves and restores list of SessionModel's to/from disk using json format. -//! Single JsonDocument corresponds to a single file on disk. - -class MVVM_MODEL_EXPORT JsonDocument : public ModelDocumentInterface { -public: - JsonDocument(const std::vector<SessionModel*>& models); - ~JsonDocument() override; - - void save(const std::string& file_name) const override; - void load(const std::string& file_name) override; - -private: - struct JsonDocumentImpl; - std::unique_ptr<JsonDocumentImpl> p_impl; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_SERIALIZATION_JSONDOCUMENT_H diff --git a/mvvm/model/mvvm/serialization/jsonitem_types.h b/mvvm/model/mvvm/serialization/jsonitem_types.h deleted file mode 100644 index fdb35ccb1d9115ff6931e1c5e37d6ec3fa716753..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/serialization/jsonitem_types.h +++ /dev/null @@ -1,76 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/serialization/jsonitem_types.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_SERIALIZATION_JSONITEM_TYPES_H -#define BORNAGAIN_MVVM_MODEL_MVVM_SERIALIZATION_JSONITEM_TYPES_H - -//! @file mvvm/model/mvvm/serialization/jsonitem_types.h -//! Collection of custom types involved into SessionItem and JSON mutual convertion. - -#include "mvvm/model_export.h" -#include <functional> -#include <memory> -#include <vector> - -class QJsonObject; - -namespace ModelView { - -class SessionItem; -class ItemFactoryInterface; - -//! Provides necessary callbacks to convert SessionItem to JSON and back. - -struct MVVM_MODEL_EXPORT ConverterCallbacks { - using create_json_t = std::function<QJsonObject(const SessionItem&)>; - using create_item_t = std::function<std::unique_ptr<SessionItem>(const QJsonObject&)>; - using update_item_t = std::function<void(const QJsonObject&, SessionItem*)>; - - create_json_t m_create_json; //! creates JSON object from session item - create_item_t m_create_item; //! creates new SessionItem from JSON object - update_item_t m_update_item; //! updates existing SessionItem from JSON object -}; - -//! Flags to define converter behavior on the way from SessionItem to JSON and back. - -enum class ConverterMode { - none, //!< undefined converter mode - clone, //!< full deep copying with item identifiers preserved - copy, //!< full deep copying with item identifiers regenerated - project //!< selective copying for saving/loading the project (tags and data created by item, - //!< updated from JSON) -}; - -//! Returns true if given mode requires ID regeneration instead of using the one stored in JSON. -inline bool isRegenerateIdWhenBackFromJson(ConverterMode mode) -{ - return mode == ConverterMode::copy; -} - -//! Returns true if item content should be reconstructed from JSON -inline bool isRebuildItemDataAndTagFromJson(ConverterMode mode) -{ - return mode != ConverterMode::project; -} - -//! Collection of input paramters for SessionItemConverter - -struct MVVM_MODEL_EXPORT ConverterContext { - const ItemFactoryInterface* m_factory{nullptr}; - ConverterMode m_mode = ConverterMode::none; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_SERIALIZATION_JSONITEM_TYPES_H diff --git a/mvvm/model/mvvm/serialization/jsonitembackupstrategy.cpp b/mvvm/model/mvvm/serialization/jsonitembackupstrategy.cpp deleted file mode 100644 index 035455fe54e097016b50a0bf366be30b20784401..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/serialization/jsonitembackupstrategy.cpp +++ /dev/null @@ -1,43 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/serialization/jsonitembackupstrategy.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/serialization/jsonitembackupstrategy.h" -#include "mvvm/factories/itemconverterfactory.h" -#include "mvvm/model/sessionitem.h" -#include <QJsonObject> - -using namespace ModelView; - -struct JsonItemBackupStrategy::JsonItemBackupStrategyImpl { - std::unique_ptr<JsonItemConverterInterface> m_converter; - QJsonObject m_json; -}; - -JsonItemBackupStrategy::JsonItemBackupStrategy(const ItemFactoryInterface* item_factory) - : p_impl(std::make_unique<JsonItemBackupStrategyImpl>()) -{ - p_impl->m_converter = CreateItemCloneConverter(item_factory); -} - -JsonItemBackupStrategy::~JsonItemBackupStrategy() = default; - -std::unique_ptr<SessionItem> JsonItemBackupStrategy::restoreItem() const -{ - return p_impl->m_converter->from_json(p_impl->m_json); -} - -void JsonItemBackupStrategy::saveItem(const SessionItem* item) -{ - p_impl->m_json = p_impl->m_converter->to_json(item); -} diff --git a/mvvm/model/mvvm/serialization/jsonitembackupstrategy.h b/mvvm/model/mvvm/serialization/jsonitembackupstrategy.h deleted file mode 100644 index d407da0fdcef33fcfdb296c837bfbfd54c11281d..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/serialization/jsonitembackupstrategy.h +++ /dev/null @@ -1,44 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/serialization/jsonitembackupstrategy.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_SERIALIZATION_JSONITEMBACKUPSTRATEGY_H -#define BORNAGAIN_MVVM_MODEL_MVVM_SERIALIZATION_JSONITEMBACKUPSTRATEGY_H - -#include "mvvm/interfaces/itembackupstrategy.h" -#include <memory> - -namespace ModelView { - -class SessionItem; -class ItemFactoryInterface; - -//! Provide backup of SessionItem using json strategy. - -class MVVM_MODEL_EXPORT JsonItemBackupStrategy : public ItemBackupStrategy { -public: - JsonItemBackupStrategy(const ItemFactoryInterface* item_factory); - ~JsonItemBackupStrategy() override; - - std::unique_ptr<SessionItem> restoreItem() const override; - - void saveItem(const SessionItem* item) override; - -private: - struct JsonItemBackupStrategyImpl; - std::unique_ptr<JsonItemBackupStrategyImpl> p_impl; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_SERIALIZATION_JSONITEMBACKUPSTRATEGY_H diff --git a/mvvm/model/mvvm/serialization/jsonitemcontainerconverter.cpp b/mvvm/model/mvvm/serialization/jsonitemcontainerconverter.cpp deleted file mode 100644 index bc364dff83b74052a0bba47fcf194340d4927460..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/serialization/jsonitemcontainerconverter.cpp +++ /dev/null @@ -1,155 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/serialization/jsonitemcontainerconverter.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/serialization/jsonitemcontainerconverter.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/model/sessionitemcontainer.h" -#include "mvvm/model/sessionitemtags.h" -#include "mvvm/model/tagrow.h" -#include "mvvm/serialization/compatibilityutils.h" -#include "mvvm/serialization/jsonitem_types.h" -#include "mvvm/serialization/jsonitemformatassistant.h" -#include "mvvm/serialization/jsontaginfoconverter.h" -#include <QJsonArray> -#include <QJsonObject> - -using namespace ModelView; - -struct JsonItemContainerConverter::JsonItemContainerConverterImpl { - std::unique_ptr<JsonTagInfoConverterInterface> m_taginfo_converter; - ConverterCallbacks m_converter_callbacks; - - JsonItemContainerConverterImpl(ConverterCallbacks callbacks = {}) - : m_converter_callbacks(std::move(callbacks)) - { - m_taginfo_converter = std::make_unique<JsonTagInfoConverter>(); - } - - QJsonObject create_json(const SessionItem& item) - { - return m_converter_callbacks.m_create_json ? m_converter_callbacks.m_create_json(item) - : QJsonObject(); - } - - std::unique_ptr<SessionItem> create_item(const QJsonObject& json) - { - return m_converter_callbacks.m_create_item ? m_converter_callbacks.m_create_item(json) - : std::unique_ptr<SessionItem>(); - } - - void update_item(const QJsonObject& json, SessionItem* item) - { - if (m_converter_callbacks.m_update_item) - m_converter_callbacks.m_update_item(json, item); - } - - //! Update container from json content. Number of existing container items should match size - //! of json array. - void update_items(const QJsonObject& json, SessionItemContainer& container) - { - auto array = json[JsonItemFormatAssistant::itemsKey].toArray(); - if (array.size() != container.itemCount()) - throw std::runtime_error("Error in JsonItemContainerConverter: size is different"); - int index{0}; - for (const auto obj : array) - update_item(obj.toObject(), container.itemAt(index++)); - } - - void create_items(const QJsonObject& json, SessionItemContainer& container) - { - for (const auto obj : json[JsonItemFormatAssistant::itemsKey].toArray()) { - if (auto item = create_item(obj.toObject()); item) - container.insertItem(item.release(), container.itemCount()); - } - } - - //! Populates container with content reconstructed from JSON object. Container must be empty. - - void populate_container(const QJsonObject& json, SessionItemContainer& container) - { - if (!container.empty()) - throw std::runtime_error( - "Error in JsonItemContainerConverter: container is not empty."); - - create_items(json, container); - } - - //! Update container with content reconstructed from JSON object. - //! It is assumed, that container has some items already created. - - void update_container(const QJsonObject& json, SessionItemContainer& container) - { - TagInfo tagInfo = - m_taginfo_converter->from_json(json[JsonItemFormatAssistant::tagInfoKey].toObject()); - - if (Compatibility::IsCompatibleSinglePropertyTag(container, tagInfo)) - update_items(json, container); - - else if (Compatibility::IsCompatibleGroupTag(container, tagInfo)) - update_items(json, container); - - else if (Compatibility::IsCompatibleUniversalTag(container, tagInfo)) - create_items(json, container); - - else - throw std::runtime_error("Error in JsonItemContainerConverter: can't convert json"); - } -}; - -JsonItemContainerConverter::JsonItemContainerConverter(ConverterCallbacks callbacks) - : p_impl(std::make_unique<JsonItemContainerConverterImpl>(std::move(callbacks))) -{ -} - -JsonItemContainerConverter::~JsonItemContainerConverter() = default; - -QJsonObject JsonItemContainerConverter::to_json(const SessionItemContainer& container) -{ - QJsonObject result; - result[JsonItemFormatAssistant::tagInfoKey] = - p_impl->m_taginfo_converter->to_json(container.tagInfo()); - - QJsonArray itemArray; - for (auto item : container) - itemArray.append(p_impl->create_json(*item)); - result[JsonItemFormatAssistant::itemsKey] = itemArray; - - return result; -} - -//! Reconstructs SessionItemContainer from the content of JSON object. Can work in two modes: -//! + If SessionItemContainer is empty, the content will be reconstructed from JSON -//! + If SessionItemContainer contains some items already, they will be populated from JSON. -//! Second mode is used when loading project from disk to allow back compatibility. - -void JsonItemContainerConverter::from_json(const QJsonObject& json, SessionItemContainer& container) -{ - static JsonItemFormatAssistant assistant; - - if (!assistant.isSessionItemContainer(json)) - throw std::runtime_error("Error in JsonItemContainerConverter: given JSON can't represent " - "SessionItemContainer."); - - TagInfo tagInfo = p_impl->m_taginfo_converter->from_json( - json[JsonItemFormatAssistant::tagInfoKey].toObject()); - - if (tagInfo.name() != container.tagInfo().name()) - throw std::runtime_error("Error in JsonItemContainerConverter: attempt to update " - "container from JSON representing another container."); - - if (container.empty()) - p_impl->populate_container(json, container); - else - p_impl->update_container(json, container); -} diff --git a/mvvm/model/mvvm/serialization/jsonitemcontainerconverter.h b/mvvm/model/mvvm/serialization/jsonitemcontainerconverter.h deleted file mode 100644 index 01448965671a3e7760c774dcc188e566cea1505b..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/serialization/jsonitemcontainerconverter.h +++ /dev/null @@ -1,48 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/serialization/jsonitemcontainerconverter.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_SERIALIZATION_JSONITEMCONTAINERCONVERTER_H -#define BORNAGAIN_MVVM_MODEL_MVVM_SERIALIZATION_JSONITEMCONTAINERCONVERTER_H - -#include "mvvm/model_export.h" -#include <functional> -#include <memory> - -class QJsonObject; - -namespace ModelView { - -class SessionItem; -class SessionItemContainer; -struct ConverterCallbacks; - -//! Converter between SessionItemContainer and JSON object. - -class MVVM_MODEL_EXPORT JsonItemContainerConverter { -public: - JsonItemContainerConverter(ConverterCallbacks callbacks); - ~JsonItemContainerConverter(); - - QJsonObject to_json(const SessionItemContainer& container); - - void from_json(const QJsonObject& json, SessionItemContainer& container); - -private: - struct JsonItemContainerConverterImpl; - std::unique_ptr<JsonItemContainerConverterImpl> p_impl; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_SERIALIZATION_JSONITEMCONTAINERCONVERTER_H diff --git a/mvvm/model/mvvm/serialization/jsonitemconverter.cpp b/mvvm/model/mvvm/serialization/jsonitemconverter.cpp deleted file mode 100644 index 3e8e9164d5d6240a7f5704245b9557ecc9481d08..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/serialization/jsonitemconverter.cpp +++ /dev/null @@ -1,141 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/serialization/jsonitemconverter.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/serialization/jsonitemconverter.h" -#include "mvvm/core/uniqueidgenerator.h" -#include "mvvm/interfaces/itemfactoryinterface.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/model/sessionitemdata.h" -#include "mvvm/model/sessionitemtags.h" -#include "mvvm/serialization/jsonitem_types.h" -#include "mvvm/serialization/jsonitemdataconverter.h" -#include "mvvm/serialization/jsonitemformatassistant.h" -#include "mvvm/serialization/jsonitemtagsconverter.h" -#include <QJsonArray> -#include <QJsonObject> - -using namespace ModelView; - -namespace { - -//! Creates converter for SessionItemData/JSON. - -std::unique_ptr<JsonItemDataConverterInterface> createDataConverter(const ConverterMode& mode) -{ - return mode == ConverterMode::project ? JsonItemDataConverter::createProjectConverter() - : JsonItemDataConverter::createCopyConverter(); -} - -} // namespace - -struct JsonItemConverter::JsonItemConverterImpl { - JsonItemConverter* m_self{nullptr}; - std::unique_ptr<JsonItemDataConverterInterface> m_itemdata_converter; - std::unique_ptr<JsonItemTagsConverter> m_itemtags_converter; - ConverterContext m_context; - - JsonItemConverterImpl(JsonItemConverter* parent, const ConverterContext& context) - : m_self(parent), m_context(context) - { - //! Callback to convert SessionItem to JSON object. - auto create_json = [this](const SessionItem& item) { return m_self->to_json(&item); }; - - //! Callback to create SessionItem from JSON object. - auto create_item = [this](const QJsonObject& json) { return m_self->from_json(json); }; - - //! Callback to update SessionItem from JSON object. - auto update_item = [this](const QJsonObject& json, SessionItem* item) { - populate_item(json, *item); - }; - - ConverterCallbacks callbacks{create_json, create_item, update_item}; - - m_itemdata_converter = createDataConverter(m_context.m_mode); - m_itemtags_converter = std::make_unique<JsonItemTagsConverter>(callbacks); - } - - const ItemFactoryInterface* factory() { return m_context.m_factory; } - - void populate_item_data(const QJsonArray& json, SessionItemData& item_data) - { - m_itemdata_converter->from_json(json, item_data); - } - - void populate_item_tags(const QJsonObject& json, SessionItemTags& item_tags) - { - m_itemtags_converter->from_json(json, item_tags); - } - - void populate_item(const QJsonObject& json, SessionItem& item) - { - auto modelType = json[JsonItemFormatAssistant::modelKey].toString().toStdString(); - - if (modelType != item.modelType()) - throw std::runtime_error("Item model mismatch"); - - if (isRebuildItemDataAndTagFromJson(m_context.m_mode)) { - item.setDataAndTags(std::make_unique<SessionItemData>(), - std::make_unique<SessionItemTags>()); - } - - populate_item_data(json[JsonItemFormatAssistant::itemDataKey].toArray(), *item.itemData()); - populate_item_tags(json[JsonItemFormatAssistant::itemTagsKey].toObject(), *item.itemTags()); - - for (auto child : item.children()) - child->setParent(&item); - - if (isRegenerateIdWhenBackFromJson(m_context.m_mode)) - item.setData(UniqueIdGenerator::generate(), ItemDataRole::IDENTIFIER); - } - - QJsonObject item_to_json(const SessionItem& item) const - { - QJsonObject result; - result[JsonItemFormatAssistant::modelKey] = QString::fromStdString(item.modelType()); - result[JsonItemFormatAssistant::itemDataKey] = - m_itemdata_converter->to_json(*item.itemData()); - result[JsonItemFormatAssistant::itemTagsKey] = - m_itemtags_converter->to_json(*item.itemTags()); - - return result; - } -}; - -JsonItemConverter::JsonItemConverter(const ConverterContext& context) - : p_impl(std::make_unique<JsonItemConverterImpl>(this, context)) -{ -} - -JsonItemConverter::~JsonItemConverter() = default; - -QJsonObject JsonItemConverter::to_json(const SessionItem* item) const -{ - return item ? p_impl->item_to_json(*item) : QJsonObject(); -} - -std::unique_ptr<SessionItem> JsonItemConverter::from_json(const QJsonObject& json) const -{ - static JsonItemFormatAssistant assistant; - - if (!assistant.isSessionItem(json)) - throw std::runtime_error("JsonItemConverterV2::from_json() -> Error. Given json object " - "can't represent a SessionItem."); - - auto modelType = json[JsonItemFormatAssistant::modelKey].toString().toStdString(); - auto result = p_impl->factory()->createItem(modelType); - - p_impl->populate_item(json, *result); - - return result; -} diff --git a/mvvm/model/mvvm/serialization/jsonitemconverter.h b/mvvm/model/mvvm/serialization/jsonitemconverter.h deleted file mode 100644 index 4232437cf0cc4a1ea39ec857476b4de17c7eb196..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/serialization/jsonitemconverter.h +++ /dev/null @@ -1,46 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/serialization/jsonitemconverter.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_SERIALIZATION_JSONITEMCONVERTER_H -#define BORNAGAIN_MVVM_MODEL_MVVM_SERIALIZATION_JSONITEMCONVERTER_H - -#include "mvvm/serialization/jsonitemconverterinterface.h" - -namespace ModelView { - -class ItemFactoryInterface; -struct ConverterContext; - -//! Converter between SessionItem and JSON object. - -class MVVM_MODEL_EXPORT JsonItemConverter : public JsonItemConverterInterface { -public: - JsonItemConverter(const ConverterContext& context); - JsonItemConverter(const JsonItemConverter&) = delete; - JsonItemConverter& operator=(const JsonItemConverter&) = delete; - - ~JsonItemConverter() override; - - QJsonObject to_json(const SessionItem* item) const override; - - std::unique_ptr<SessionItem> from_json(const QJsonObject& json) const override; - -private: - struct JsonItemConverterImpl; - std::unique_ptr<JsonItemConverterImpl> p_impl; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_SERIALIZATION_JSONITEMCONVERTER_H diff --git a/mvvm/model/mvvm/serialization/jsonitemconverterinterface.h b/mvvm/model/mvvm/serialization/jsonitemconverterinterface.h deleted file mode 100644 index 562c7aeb63c4349b772f2cc484bc41841e4a9270..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/serialization/jsonitemconverterinterface.h +++ /dev/null @@ -1,42 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/serialization/jsonitemconverterinterface.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_SERIALIZATION_JSONITEMCONVERTERINTERFACE_H -#define BORNAGAIN_MVVM_MODEL_MVVM_SERIALIZATION_JSONITEMCONVERTERINTERFACE_H - -#include "mvvm/model_export.h" -#include <memory> - -class QJsonObject; - -namespace ModelView { - -class SessionItem; - -//! Base class for all converters of SessionItem to/from JSON object. - -class MVVM_MODEL_EXPORT JsonItemConverterInterface { -public: - virtual ~JsonItemConverterInterface() = default; - - //! Converts item to JSON. - virtual QJsonObject to_json(const SessionItem* item) const = 0; - - //! Creates item from JSON. - virtual std::unique_ptr<SessionItem> from_json(const QJsonObject&) const = 0; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_SERIALIZATION_JSONITEMCONVERTERINTERFACE_H diff --git a/mvvm/model/mvvm/serialization/jsonitemcopystrategy.cpp b/mvvm/model/mvvm/serialization/jsonitemcopystrategy.cpp deleted file mode 100644 index acae455e3da3ecd13b62aa106af08b20a6513a4d..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/serialization/jsonitemcopystrategy.cpp +++ /dev/null @@ -1,38 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/serialization/jsonitemcopystrategy.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/serialization/jsonitemcopystrategy.h" -#include "mvvm/factories/itemconverterfactory.h" -#include "mvvm/model/sessionitem.h" -#include <QJsonObject> - -using namespace ModelView; - -struct JsonItemCopyStrategy::JsonItemCopyStrategyImpl { - std::unique_ptr<JsonItemConverterInterface> m_converter; -}; - -JsonItemCopyStrategy::JsonItemCopyStrategy(const ItemFactoryInterface* item_factory) - : p_impl(std::make_unique<JsonItemCopyStrategyImpl>()) -{ - p_impl->m_converter = CreateItemCopyConverter(item_factory); -} - -JsonItemCopyStrategy::~JsonItemCopyStrategy() = default; - -std::unique_ptr<SessionItem> JsonItemCopyStrategy::createCopy(const SessionItem* item) const -{ - auto json = p_impl->m_converter->to_json(item); - return p_impl->m_converter->from_json(json); -} diff --git a/mvvm/model/mvvm/serialization/jsonitemcopystrategy.h b/mvvm/model/mvvm/serialization/jsonitemcopystrategy.h deleted file mode 100644 index 4daa97ee116460a5e2d4c7a620500e367efe90c3..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/serialization/jsonitemcopystrategy.h +++ /dev/null @@ -1,42 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/serialization/jsonitemcopystrategy.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_SERIALIZATION_JSONITEMCOPYSTRATEGY_H -#define BORNAGAIN_MVVM_MODEL_MVVM_SERIALIZATION_JSONITEMCOPYSTRATEGY_H - -#include "mvvm/interfaces/itemcopystrategy.h" -#include <memory> - -namespace ModelView { - -class SessionItem; -class ItemFactoryInterface; - -//! Provide SessionItem copying using json based strategy. - -class MVVM_MODEL_EXPORT JsonItemCopyStrategy : public ItemCopyStrategy { -public: - JsonItemCopyStrategy(const ItemFactoryInterface* item_factory); - ~JsonItemCopyStrategy(); - - std::unique_ptr<SessionItem> createCopy(const SessionItem* item) const; - -private: - struct JsonItemCopyStrategyImpl; - std::unique_ptr<JsonItemCopyStrategyImpl> p_impl; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_SERIALIZATION_JSONITEMCOPYSTRATEGY_H diff --git a/mvvm/model/mvvm/serialization/jsonitemdataconverter.cpp b/mvvm/model/mvvm/serialization/jsonitemdataconverter.cpp deleted file mode 100644 index 4fa5fde8fd6b6c6931af962c7896f63d1c2e9c5f..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/serialization/jsonitemdataconverter.cpp +++ /dev/null @@ -1,121 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/serialization/jsonitemdataconverter.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/serialization/jsonitemdataconverter.h" -#include "mvvm/model/mvvm_types.h" -#include "mvvm/model/sessionitemdata.h" -#include "mvvm/serialization/jsonitemformatassistant.h" -#include "mvvm/serialization/jsonvariantconverter.h" -#include <QJsonArray> -#include <QJsonObject> -#include <set> -#include <stdexcept> - -using namespace ModelView; - -namespace { -QJsonValue keyValue(const QJsonValue& parent_value, const QString& key) -{ - const QJsonObject& parent_object = parent_value.toObject(); - return parent_object.value(key); -} -} // namespace - -JsonItemDataConverter::JsonItemDataConverter(accept_strategy_t to_json_accept, - accept_strategy_t from_json_accept) - : m_to_json_accept(to_json_accept) - , m_from_json_accept(from_json_accept) - , m_variant_converter(std::make_unique<JsonVariantConverter>()) -{ -} - -JsonItemDataConverter::~JsonItemDataConverter() = default; - -QJsonArray JsonItemDataConverter::to_json(const SessionItemData& data) -{ - QJsonArray result; - - for (const auto& x : data) { - QJsonObject object; - if (isRoleToJson(x.m_role)) { - object[JsonItemFormatAssistant::roleKey] = x.m_role; - object[JsonItemFormatAssistant::variantKey] = m_variant_converter->get_json(x.m_data); - result.append(object); - } - } - - return result; -} - -//! Updates existing data with JSON content. - -void JsonItemDataConverter::from_json(const QJsonArray& object, SessionItemData& data) -{ - static JsonItemFormatAssistant assistant; - auto persistent_data = std::make_unique<SessionItemData>(); - - for (const auto& x : object) { - if (!assistant.isSessionItemData(x.toObject())) - throw std::runtime_error("JsonItemData::get_data() -> Invalid json object."); - auto role = keyValue(x, JsonItemFormatAssistant::roleKey).toInt(); - auto variant = m_variant_converter->get_variant( - keyValue(x, JsonItemFormatAssistant::variantKey).toObject()); - if (isRoleFromJson(role)) - persistent_data->setData(variant, role); - } - - auto runtime_roles = data.roles(); - auto persistent_roles = persistent_data->roles(); - - std::set<int> roles(runtime_roles.begin(), runtime_roles.end()); - roles.insert(persistent_roles.begin(), persistent_roles.end()); - - for (auto role : roles) { - // all roles existing in `persistent` will be taken from there - if (persistent_data->hasData(role)) - data.setData(persistent_data->data(role), role); - } -} - -//! Creates JSON data converter intended for simple data copying. Nothing is filtered out. - -std::unique_ptr<JsonItemDataConverterInterface> JsonItemDataConverter::createCopyConverter() -{ - return std::make_unique<JsonItemDataConverter>(); -} - -//! Creates JSON data converter intended for project saving. Only IDENTIFIER and DATA gous to/from -//! JSON. - -std::unique_ptr<JsonItemDataConverterInterface> JsonItemDataConverter::createProjectConverter() -{ - auto accept_roles = [](auto role) { - return role == ItemDataRole::IDENTIFIER || role == ItemDataRole::DATA; - }; - return std::make_unique<JsonItemDataConverter>(accept_roles, accept_roles); -} - -//! Returns true if given role should be saved in json object. - -bool JsonItemDataConverter::isRoleToJson(int role) const -{ - return m_to_json_accept ? m_to_json_accept(role) : true; -} - -//! Returns true if given role should be parsed from json object. - -bool JsonItemDataConverter::isRoleFromJson(int role) const -{ - return m_from_json_accept ? m_from_json_accept(role) : true; -} diff --git a/mvvm/model/mvvm/serialization/jsonitemdataconverter.h b/mvvm/model/mvvm/serialization/jsonitemdataconverter.h deleted file mode 100644 index 767f4ed862bd9ee7c79a0b8a65aa4c99533837f3..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/serialization/jsonitemdataconverter.h +++ /dev/null @@ -1,59 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/serialization/jsonitemdataconverter.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_SERIALIZATION_JSONITEMDATACONVERTER_H -#define BORNAGAIN_MVVM_MODEL_MVVM_SERIALIZATION_JSONITEMDATACONVERTER_H - -#include "mvvm/serialization/jsonitemdataconverterinterface.h" -#include <QString> -#include <functional> -#include <memory> - -class QJsonObject; - -namespace ModelView { - -class JsonVariantConverterInterface; - -//! Default converter of SessionItemData to/from json object. - -class MVVM_MODEL_EXPORT JsonItemDataConverter : public JsonItemDataConverterInterface { -public: - using accept_strategy_t = std::function<bool(int)>; - - JsonItemDataConverter(accept_strategy_t to_json_accept = {}, - accept_strategy_t from_json_accept = {}); - - ~JsonItemDataConverter() override; - - QJsonArray to_json(const SessionItemData& data) override; - - void from_json(const QJsonArray& object, SessionItemData& data) override; - - static std::unique_ptr<JsonItemDataConverterInterface> createCopyConverter(); - - static std::unique_ptr<JsonItemDataConverterInterface> createProjectConverter(); - -private: - bool isRoleToJson(int role) const; - bool isRoleFromJson(int role) const; - - accept_strategy_t m_to_json_accept; //!< callback to find whether to write role to json - accept_strategy_t m_from_json_accept; //!< callback to find whether to read role from json - std::unique_ptr<JsonVariantConverterInterface> m_variant_converter; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_SERIALIZATION_JSONITEMDATACONVERTER_H diff --git a/mvvm/model/mvvm/serialization/jsonitemdataconverterinterface.h b/mvvm/model/mvvm/serialization/jsonitemdataconverterinterface.h deleted file mode 100644 index edd4a36a2699bdf2d9309956512792f9fe64b4d1..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/serialization/jsonitemdataconverterinterface.h +++ /dev/null @@ -1,42 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/serialization/jsonitemdataconverterinterface.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_SERIALIZATION_JSONITEMDATACONVERTERINTERFACE_H -#define BORNAGAIN_MVVM_MODEL_MVVM_SERIALIZATION_JSONITEMDATACONVERTERINTERFACE_H - -#include "mvvm/model_export.h" -#include <memory> - -class QJsonArray; - -namespace ModelView { - -class SessionItemData; - -//! Base class for all converters of SessionItemData to/from JSON object. - -class MVVM_MODEL_EXPORT JsonItemDataConverterInterface { -public: - virtual ~JsonItemDataConverterInterface() = default; - - //! Converts SessionItemData to JSON; - virtual QJsonArray to_json(const SessionItemData&) = 0; - - //! Converts SessionItemData from JSON; - virtual void from_json(const QJsonArray& object, SessionItemData& data) = 0; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_SERIALIZATION_JSONITEMDATACONVERTERINTERFACE_H diff --git a/mvvm/model/mvvm/serialization/jsonitemformatassistant.cpp b/mvvm/model/mvvm/serialization/jsonitemformatassistant.cpp deleted file mode 100644 index 94f379110249de60cfd2f091d116cc143da224e6..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/serialization/jsonitemformatassistant.cpp +++ /dev/null @@ -1,140 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/serialization/jsonitemformatassistant.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/serialization/jsonitemformatassistant.h" -#include <QJsonObject> -#include <QStringList> - -using namespace ModelView; - -namespace { -//! Returns list of keys which should be in QJsonObject to represent SessionItem. -QStringList expected_item_keys() -{ - QStringList result{JsonItemFormatAssistant::modelKey, JsonItemFormatAssistant::itemDataKey, - JsonItemFormatAssistant::itemTagsKey}; - std::sort(result.begin(), result.end()); - return result; -} - -//! Returns list of keys which should be in QJsonObject to represent SessionItemData. - -QStringList expected_itemdata_keys() -{ - QStringList result{JsonItemFormatAssistant::roleKey, JsonItemFormatAssistant::variantKey}; - std::sort(result.begin(), result.end()); - return result; -} - -//! Returns list of keys which should be in QJsonObject to represent SessionItemTags. - -QStringList expected_tags_keys() -{ - QStringList result{JsonItemFormatAssistant::defaultTagKey, - JsonItemFormatAssistant::containerKey}; - std::sort(result.begin(), result.end()); - return result; -} - -//! Returns list of keys which should be in QJsonObject to represent SessionItemContainer. - -QStringList expected_itemcontainer_keys() -{ - QStringList result = {JsonItemFormatAssistant::tagInfoKey, JsonItemFormatAssistant::itemsKey}; - std::sort(result.begin(), result.end()); - return result; -} - -//! Returns list of keys which should be in QJsonObject to represent SessionModel. - -QStringList expected_sessionmodel_keys() -{ - QStringList result{JsonItemFormatAssistant::sessionModelKey, JsonItemFormatAssistant::itemsKey}; - std::sort(result.begin(), result.end()); - return result; -} - -} // namespace - -//! Returns true if given json object represents SessionItem. - -bool JsonItemFormatAssistant::isSessionItem(const QJsonObject& json) const -{ - static const QStringList expected = expected_item_keys(); - - if (json.keys() != expected) - return false; - - if (!json[itemDataKey].isArray()) - return false; - - if (!json[itemTagsKey].isObject()) - return false; - - return true; -} - -bool JsonItemFormatAssistant::isSessionItemData(const QJsonObject& json) const -{ - static const QStringList expected = expected_itemdata_keys(); - return json.keys() == expected; -} - -//! Returns true if given json object represents SessionItemTags. - -bool JsonItemFormatAssistant::isSessionItemTags(const QJsonObject& json) const -{ - static const QStringList expected = expected_tags_keys(); - - if (json.keys() != expected) - return false; - - if (!json[containerKey].isArray()) - return false; - - return true; -} - -//! Returns true if given json object represents SessionItemContainer. - -bool JsonItemFormatAssistant::isSessionItemContainer(const QJsonObject& json) const -{ - static const QStringList expected = expected_itemcontainer_keys(); - - if (json.keys() != expected) - return false; - - if (!json[tagInfoKey].isObject()) - return false; - - if (!json[itemsKey].isArray()) - return false; - - return true; -} - -//! Returns true if given json object represents SessionModel. - -bool JsonItemFormatAssistant::isSessionModel(const QJsonObject& object) const -{ - static const QStringList expected = expected_sessionmodel_keys(); - - if (object.keys() != expected) - return false; - - if (!object[itemsKey].isArray()) - return false; - - return true; -} diff --git a/mvvm/model/mvvm/serialization/jsonitemformatassistant.h b/mvvm/model/mvvm/serialization/jsonitemformatassistant.h deleted file mode 100644 index 197e6246ee4655d4693174cf8cc55acb110c5ca4..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/serialization/jsonitemformatassistant.h +++ /dev/null @@ -1,53 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/serialization/jsonitemformatassistant.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_SERIALIZATION_JSONITEMFORMATASSISTANT_H -#define BORNAGAIN_MVVM_MODEL_MVVM_SERIALIZATION_JSONITEMFORMATASSISTANT_H - -#include "mvvm/serialization/jsonitemconverterinterface.h" -#include <QString> -#include <memory> - -namespace ModelView { - -class ItemFactoryInterface; - -//! Utility class to determine, whether given JSON object can represent various parts of -//! SessionModel. It is made a class (and not a set of free functions) to allow different formats in -//! the future. - -class MVVM_MODEL_EXPORT JsonItemFormatAssistant { -public: - static inline const QString modelKey = "model"; - static inline const QString itemDataKey = "itemData"; - static inline const QString itemTagsKey = "itemTags"; - static inline const QString defaultTagKey = "defaultTag"; - static inline const QString containerKey = "containers"; - static inline const QString tagInfoKey = "tagInfo"; - static inline const QString itemsKey = "items"; - static inline const QString sessionModelKey = "sessionmodel"; - static inline const QString versionKey = "version"; - static inline const QString roleKey = "role"; - static inline const QString variantKey = "variant"; - - bool isSessionItem(const QJsonObject& json) const; - bool isSessionItemData(const QJsonObject& json) const; - bool isSessionItemTags(const QJsonObject& json) const; - bool isSessionItemContainer(const QJsonObject& json) const; - bool isSessionModel(const QJsonObject& object) const; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_SERIALIZATION_JSONITEMFORMATASSISTANT_H diff --git a/mvvm/model/mvvm/serialization/jsonitemtagsconverter.cpp b/mvvm/model/mvvm/serialization/jsonitemtagsconverter.cpp deleted file mode 100644 index f95576a70a12bc97252f0f7b10082099cc93b539..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/serialization/jsonitemtagsconverter.cpp +++ /dev/null @@ -1,116 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/serialization/jsonitemtagsconverter.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/serialization/jsonitemtagsconverter.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/model/sessionitemtags.h" -#include "mvvm/model/taginfo.h" -#include "mvvm/serialization/jsonitem_types.h" -#include "mvvm/serialization/jsonitemcontainerconverter.h" -#include "mvvm/serialization/jsonitemformatassistant.h" -#include "mvvm/serialization/jsontaginfoconverter.h" -#include <QJsonArray> -#include <QJsonObject> - -using namespace ModelView; - -struct JsonItemTagsConverter::JsonItemTagsConverterImpl { - std::unique_ptr<JsonItemContainerConverter> m_container_converter; - std::unique_ptr<JsonTagInfoConverterInterface> m_taginfo_converter; - - JsonItemTagsConverterImpl(ConverterCallbacks callbacks = {}) - { - m_container_converter = std::make_unique<JsonItemContainerConverter>(std::move(callbacks)); - m_taginfo_converter = std::make_unique<JsonTagInfoConverter>(); - } - - //! Create containers from JSON. SessionItemTags should be empty. - - void create_containers(const QJsonObject& json, SessionItemTags& item_tags) - { - if (item_tags.tagsCount()) - throw std::runtime_error("Error in JsonItemTagsConverter: no containers expected."); - - auto default_tag = json[JsonItemFormatAssistant::defaultTagKey].toString().toStdString(); - item_tags.setDefaultTag(default_tag); - - auto container_array = json[JsonItemFormatAssistant::containerKey].toArray(); - - for (const auto ref : container_array) { - QJsonObject json_container = ref.toObject(); - QJsonObject json_taginfo = - json_container[JsonItemFormatAssistant::tagInfoKey].toObject(); - TagInfo tagInfo = m_taginfo_converter->from_json(json_taginfo); - item_tags.registerTag(tagInfo); - } - } - - //! Populate containers from JSON. Container must be already created. - - void populate_containers(const QJsonObject& json, SessionItemTags& item_tags) - { - auto container_array = json[JsonItemFormatAssistant::containerKey].toArray(); - - if (container_array.size() != item_tags.tagsCount()) - throw std::runtime_error("Error in JsonItemTagsConverter: mismatch in number of tags"); - - auto default_tag = json[JsonItemFormatAssistant::defaultTagKey].toString().toStdString(); - if (default_tag != item_tags.defaultTag()) - throw std::runtime_error("Error in JsonItemTagsConverter: default tag mismatch."); - - int index(0); - for (const auto container_ref : container_array) - m_container_converter->from_json(container_ref.toObject(), item_tags.at(index++)); - } -}; - -JsonItemTagsConverter::JsonItemTagsConverter(ConverterCallbacks callbacks) - : p_impl(std::make_unique<JsonItemTagsConverterImpl>(callbacks)) -{ -} - -JsonItemTagsConverter::~JsonItemTagsConverter() = default; - -QJsonObject JsonItemTagsConverter::to_json(const SessionItemTags& item_tags) -{ - QJsonObject result; - result[JsonItemFormatAssistant::defaultTagKey] = QString::fromStdString(item_tags.defaultTag()); - - QJsonArray containerArray; - for (auto container : item_tags) - containerArray.append(p_impl->m_container_converter->to_json(*container)); - result[JsonItemFormatAssistant::containerKey] = containerArray; - - return result; -} - -//! Reconstructs SessionItemTags from the content of JSON object. Can work in two modes: -//! + If SessionItemTags is empty, all tags will be reconstructed as in JSON, and then populated -//! with the content. -//! + If SessionItemTags contains some tags already, they will be populated from JSON. in this -//! case it will be assumed, that existing item's tags are matching JSON. - -void JsonItemTagsConverter::from_json(const QJsonObject& json, SessionItemTags& item_tags) -{ - static JsonItemFormatAssistant assistant; - - if (!assistant.isSessionItemTags(json)) - throw std::runtime_error( - "Error in JsonItemTagsConverter: given json object can't represent a SessionItemTags."); - - if (!item_tags.tagsCount()) - p_impl->create_containers(json, item_tags); - - p_impl->populate_containers(json, item_tags); -} diff --git a/mvvm/model/mvvm/serialization/jsonitemtagsconverter.h b/mvvm/model/mvvm/serialization/jsonitemtagsconverter.h deleted file mode 100644 index 36c17e80f69afcde16dc1e170365f83c510de76b..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/serialization/jsonitemtagsconverter.h +++ /dev/null @@ -1,48 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/serialization/jsonitemtagsconverter.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_SERIALIZATION_JSONITEMTAGSCONVERTER_H -#define BORNAGAIN_MVVM_MODEL_MVVM_SERIALIZATION_JSONITEMTAGSCONVERTER_H - -#include "mvvm/model_export.h" -#include <functional> -#include <memory> - -class QJsonObject; - -namespace ModelView { - -class SessionItem; -class SessionItemTags; -struct ConverterCallbacks; - -//! Converter between SessionItemTags and JSON object. - -class MVVM_MODEL_EXPORT JsonItemTagsConverter { -public: - JsonItemTagsConverter(ConverterCallbacks callbacks); - ~JsonItemTagsConverter(); - - QJsonObject to_json(const SessionItemTags& item_tags); - - void from_json(const QJsonObject& json, SessionItemTags& item_tags); - -private: - struct JsonItemTagsConverterImpl; - std::unique_ptr<JsonItemTagsConverterImpl> p_impl; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_SERIALIZATION_JSONITEMTAGSCONVERTER_H diff --git a/mvvm/model/mvvm/serialization/jsonmodelconverter.cpp b/mvvm/model/mvvm/serialization/jsonmodelconverter.cpp deleted file mode 100644 index ae79b411dfce8b99505b54e5c49e0e5319720414..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/serialization/jsonmodelconverter.cpp +++ /dev/null @@ -1,94 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/serialization/jsonmodelconverter.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/serialization/jsonmodelconverter.h" -#include "mvvm/factories/itemconverterfactory.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/serialization/jsonitem_types.h" -#include "mvvm/serialization/jsonitemconverter.h" -#include "mvvm/serialization/jsonitemformatassistant.h" -#include <QJsonArray> -#include <QJsonObject> -#include <stdexcept> - -using namespace ModelView; - -namespace { -std::unique_ptr<JsonItemConverterInterface> CreateConverter(const ItemFactoryInterface* factory, - ConverterMode mode) -{ - if (mode == ConverterMode::clone) - return CreateItemCloneConverter(factory); - else if (mode == ConverterMode::copy) - return CreateItemCopyConverter(factory); - else if (mode == ConverterMode::project) - return CreateItemProjectConverter(factory); - else - throw std::runtime_error("Error in JsonModelConverter: unknown converter mode"); -} - -} // namespace - -JsonModelConverter::JsonModelConverter(ConverterMode mode) : m_mode(mode) {} - -JsonModelConverter::~JsonModelConverter() = default; - -QJsonObject JsonModelConverter::to_json(const SessionModel& model) const -{ - QJsonObject result; - - if (!model.rootItem()) - throw std::runtime_error("JsonModel::to_json() -> Error. Model is not initialized."); - - result[JsonItemFormatAssistant::sessionModelKey] = QString::fromStdString(model.modelType()); - - QJsonArray itemArray; - - auto itemConverter = CreateConverter(model.factory(), m_mode); - - for (auto item : model.rootItem()->children()) - itemArray.append(itemConverter->to_json(item)); - - result[JsonItemFormatAssistant::itemsKey] = itemArray; - - return result; -} - -void JsonModelConverter::from_json(const QJsonObject& json, SessionModel& model) const -{ - if (!model.rootItem()) - throw std::runtime_error("JsonModel::json_to_model() -> Error. Model is not initialized."); - - JsonItemFormatAssistant assistant; - if (!assistant.isSessionModel(json)) - throw std::runtime_error("JsonModel::json_to_model() -> Error. Invalid json object."); - - if (json[JsonItemFormatAssistant::sessionModelKey].toString() - != QString::fromStdString(model.modelType())) - throw std::runtime_error( - "JsonModel::json_to_model() -> Unexpected model type '" + model.modelType() - + "', json key '" - + json[JsonItemFormatAssistant::sessionModelKey].toString().toStdString() + "'"); - - auto itemConverter = CreateConverter(model.factory(), m_mode); - - auto rebuild_root = [&json, &itemConverter](auto parent) { - for (const auto ref : json[JsonItemFormatAssistant::itemsKey].toArray()) { - auto item = itemConverter->from_json(ref.toObject()); - parent->insertItem(item.release(), TagRow::append()); - } - }; - model.clear(rebuild_root); -} diff --git a/mvvm/model/mvvm/serialization/jsonmodelconverter.h b/mvvm/model/mvvm/serialization/jsonmodelconverter.h deleted file mode 100644 index e31e68d612f2aac5a610c546fd326949b5be8327..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/serialization/jsonmodelconverter.h +++ /dev/null @@ -1,46 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/serialization/jsonmodelconverter.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_SERIALIZATION_JSONMODELCONVERTER_H -#define BORNAGAIN_MVVM_MODEL_MVVM_SERIALIZATION_JSONMODELCONVERTER_H - -#include "mvvm/serialization/jsonmodelconverterinterface.h" - -class QJsonObject; - -namespace ModelView { - -class SessionModel; -enum class ConverterMode; - -//! Converter of SessionModel to/from json object with posibility to select one of convertion modes. - -class MVVM_MODEL_EXPORT JsonModelConverter : public JsonModelConverterInterface { -public: - JsonModelConverter(ConverterMode mode); - ~JsonModelConverter() override; - - //! Writes content of model into json. - QJsonObject to_json(const SessionModel& model) const override; - - //! Reads json object and build the model. - void from_json(const QJsonObject& json, SessionModel& model) const override; - -private: - ConverterMode m_mode; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_SERIALIZATION_JSONMODELCONVERTER_H diff --git a/mvvm/model/mvvm/serialization/jsonmodelconverterinterface.h b/mvvm/model/mvvm/serialization/jsonmodelconverterinterface.h deleted file mode 100644 index f02f5328993d9790bac2e9c9d2f237474b36accd..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/serialization/jsonmodelconverterinterface.h +++ /dev/null @@ -1,39 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/serialization/jsonmodelconverterinterface.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_SERIALIZATION_JSONMODELCONVERTERINTERFACE_H -#define BORNAGAIN_MVVM_MODEL_MVVM_SERIALIZATION_JSONMODELCONVERTERINTERFACE_H - -#include "mvvm/model_export.h" - -class QJsonObject; - -namespace ModelView { - -class SessionModel; - -//! Base class for all converters of SessionModel to/from json object. - -class MVVM_MODEL_EXPORT JsonModelConverterInterface { -public: - virtual ~JsonModelConverterInterface() = default; - - virtual QJsonObject to_json(const SessionModel&) const = 0; - - virtual void from_json(const QJsonObject&, SessionModel&) const = 0; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_SERIALIZATION_JSONMODELCONVERTERINTERFACE_H diff --git a/mvvm/model/mvvm/serialization/jsontaginfoconverter.cpp b/mvvm/model/mvvm/serialization/jsontaginfoconverter.cpp deleted file mode 100644 index 4839664f7f35a4d05bd65da3bed54b8bf6d572b9..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/serialization/jsontaginfoconverter.cpp +++ /dev/null @@ -1,77 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/serialization/jsontaginfoconverter.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/serialization/jsontaginfoconverter.h" -#include "mvvm/model/taginfo.h" -#include <QJsonArray> -#include <QJsonObject> -#include <QStringList> -#include <stdexcept> - -using namespace ModelView; - -namespace { -QStringList expected_taginfo_keys() -{ - QStringList result = QStringList() - << JsonTagInfoConverter::nameKey << JsonTagInfoConverter::minKey - << JsonTagInfoConverter::maxKey << JsonTagInfoConverter::modelsKey; - std::sort(result.begin(), result.end()); - return result; -} -} // namespace - -QJsonObject JsonTagInfoConverter::to_json(const ModelView::TagInfo& tag) -{ - QJsonObject result; - result[nameKey] = QString::fromStdString(tag.name()); - result[minKey] = tag.min(); - result[maxKey] = tag.max(); - QJsonArray str_array; - for (const auto& str : tag.modelTypes()) - str_array.append(QString::fromStdString(str)); - result[modelsKey] = str_array; - - return result; -} - -TagInfo JsonTagInfoConverter::from_json(const QJsonObject& object) -{ - if (!isTagInfo(object)) - throw std::runtime_error("JsonTagInfo::get_tags() -> Invalid json object."); - - auto name = object[nameKey].toString().toStdString(); - auto min = object[minKey].toInt(); - auto max = object[maxKey].toInt(); - std::vector<std::string> models; - for (const auto ref : object[modelsKey].toArray()) - models.push_back(ref.toString().toStdString()); - - return TagInfo(name, min, max, models); -} - -//! Returns true if given json object represents TagInfo object. - -bool JsonTagInfoConverter::isTagInfo(const QJsonObject& object) -{ - static const QStringList expected = expected_taginfo_keys(); - - if (object.keys() != expected) - return false; - - if (!object[modelsKey].isArray()) - return false; - - return true; -} diff --git a/mvvm/model/mvvm/serialization/jsontaginfoconverter.h b/mvvm/model/mvvm/serialization/jsontaginfoconverter.h deleted file mode 100644 index f9178f92d1a640b3d3d812f8a77a3fd63f77bdfa..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/serialization/jsontaginfoconverter.h +++ /dev/null @@ -1,41 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/serialization/jsontaginfoconverter.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_SERIALIZATION_JSONTAGINFOCONVERTER_H -#define BORNAGAIN_MVVM_MODEL_MVVM_SERIALIZATION_JSONTAGINFOCONVERTER_H - -#include "mvvm/serialization/jsontaginfoconverterinterface.h" -#include <QString> - -namespace ModelView { - -//! Default converter between TagInfo and json object. - -class MVVM_MODEL_EXPORT JsonTagInfoConverter : public JsonTagInfoConverterInterface { -public: - static inline const QString nameKey = "name"; - static inline const QString minKey = "min"; - static inline const QString maxKey = "max"; - static inline const QString modelsKey = "models"; - - QJsonObject to_json(const TagInfo& tag) override; - - TagInfo from_json(const QJsonObject& object) override; - - bool isTagInfo(const QJsonObject& object); -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_SERIALIZATION_JSONTAGINFOCONVERTER_H diff --git a/mvvm/model/mvvm/serialization/jsontaginfoconverterinterface.h b/mvvm/model/mvvm/serialization/jsontaginfoconverterinterface.h deleted file mode 100644 index affd33cfc150653c38379eabe9a595e503a9f40f..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/serialization/jsontaginfoconverterinterface.h +++ /dev/null @@ -1,39 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/serialization/jsontaginfoconverterinterface.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_SERIALIZATION_JSONTAGINFOCONVERTERINTERFACE_H -#define BORNAGAIN_MVVM_MODEL_MVVM_SERIALIZATION_JSONTAGINFOCONVERTERINTERFACE_H - -#include "mvvm/model_export.h" - -class QJsonObject; - -namespace ModelView { - -class TagInfo; - -//! Base class for all converters of TagInfo to/from json object - -class MVVM_MODEL_EXPORT JsonTagInfoConverterInterface { -public: - virtual ~JsonTagInfoConverterInterface() = default; - - virtual QJsonObject to_json(const TagInfo&) = 0; - - virtual TagInfo from_json(const QJsonObject&) = 0; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_SERIALIZATION_JSONTAGINFOCONVERTERINTERFACE_H diff --git a/mvvm/model/mvvm/serialization/jsonutils.cpp b/mvvm/model/mvvm/serialization/jsonutils.cpp deleted file mode 100644 index 76e491bd62a5e34a6c84f289cd2f5871e376269a..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/serialization/jsonutils.cpp +++ /dev/null @@ -1,76 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/serialization/jsonutils.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/serialization/jsonutils.h" -#include "mvvm/factories/modelconverterfactory.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/utils/reallimits.h" -#include <QJsonDocument> -#include <QJsonObject> -#include <stdexcept> - -namespace { -const std::string text_limitless = "limitless"; -const std::string text_positive = "positive"; -const std::string text_nonnegative = "nonnegative"; -const std::string text_lowerlimited = "lowerlimited"; -const std::string text_upperlimited = "upperlimited"; -const std::string text_limited = "limited"; -const std::string separator = " "; -} // namespace -using namespace ModelView; - -std::string JsonUtils::ModelToJsonString(const ModelView::SessionModel& model) -{ - auto converter = CreateModelCopyConverter(); - QJsonObject json_source = converter->to_json(model); - QJsonDocument document(json_source); - return QString(document.toJson(QJsonDocument::Indented)).toStdString(); -} - -std::string JsonUtils::ToString(const ModelView::RealLimits& limits) -{ - if (limits.isLimitless()) - return text_limitless; - else if (limits.isPositive()) - return text_positive; - else if (limits.isNonnegative()) - return text_nonnegative; - else if (limits.isLowerLimited()) - return text_lowerlimited; - else if (limits.isUpperLimited()) - return text_upperlimited; - else if (limits.isLimited()) - return text_limited; - else - throw std::runtime_error("JsonUtils::ToString() -> Unknown type"); -} - -RealLimits JsonUtils::CreateLimits(const std::string& text, double min, double max) -{ - if (text == text_limitless) - return RealLimits(); - else if (text == text_positive) - return RealLimits::positive(); - else if (text == text_nonnegative) - return RealLimits::nonnegative(); - else if (text == text_lowerlimited) - return RealLimits::lowerLimited(min); - else if (text == text_upperlimited) - return RealLimits::upperLimited(max); - else if (text == text_limited) - return RealLimits::limited(min, max); - else - throw std::runtime_error("JsonUtils::CreateLimits -> Unknown type"); -} diff --git a/mvvm/model/mvvm/serialization/jsonutils.h b/mvvm/model/mvvm/serialization/jsonutils.h deleted file mode 100644 index 1dc53908945b47c3d1b515ce7bf5b0ca1846d8bd..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/serialization/jsonutils.h +++ /dev/null @@ -1,41 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/serialization/jsonutils.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_SERIALIZATION_JSONUTILS_H -#define BORNAGAIN_MVVM_MODEL_MVVM_SERIALIZATION_JSONUTILS_H - -#include "mvvm/model_export.h" -#include <string> - -namespace ModelView { - -class SessionModel; -class RealLimits; - -namespace JsonUtils { - -//! Returns multiline string representing model content as json. -MVVM_MODEL_EXPORT std::string ModelToJsonString(const SessionModel& model); - -//! Returns string representation of RealLimits. -MVVM_MODEL_EXPORT std::string ToString(const RealLimits& limits); - -MVVM_MODEL_EXPORT RealLimits CreateLimits(const std::string& text, double min = 0.0, - double max = 0.0); - -} // namespace JsonUtils - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_SERIALIZATION_JSONUTILS_H diff --git a/mvvm/model/mvvm/serialization/jsonvariantconverter.cpp b/mvvm/model/mvvm/serialization/jsonvariantconverter.cpp deleted file mode 100644 index e4fe1b3f2f46e6649b8e2afaeecf5bd2e1e8d187..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/serialization/jsonvariantconverter.cpp +++ /dev/null @@ -1,313 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/serialization/jsonvariantconverter.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/serialization/jsonvariantconverter.h" -#include "mvvm/model/comboproperty.h" -#include "mvvm/model/customvariants.h" -#include "mvvm/model/externalproperty.h" -#include "mvvm/model/variant_constants.h" -#include "mvvm/serialization/jsonutils.h" -#include "mvvm/utils/reallimits.h" -#include <QJsonArray> -#include <QJsonObject> -#include <stdexcept> - -using namespace ModelView; - -namespace { - -const QString variantTypeKey = "type"; -const QString variantValueKey = "value"; -const QString comboValuesKey = "values"; -const QString comboSelectionKey = "selections"; -const QString extPropertyTextKey = "text"; -const QString extPropertyColorKey = "color"; -const QString extPropertyIdKey = "identifier"; -const QString realLimitsTextKey = "text"; -const QString realLimitsMinKey = "min"; -const QString realLimitsMaxKey = "max"; - -QStringList expected_variant_keys(); - -QJsonObject from_invalid(const Variant& variant); -Variant to_invalid(const QJsonObject& object); - -QJsonObject from_bool(const Variant& variant); -Variant to_bool(const QJsonObject& object); - -QJsonObject from_int(const Variant& variant); -Variant to_int(const QJsonObject& object); - -QJsonObject from_string(const Variant& variant); -Variant to_string(const QJsonObject& object); - -QJsonObject from_double(const Variant& variant); -Variant to_double(const QJsonObject& object); - -QJsonObject from_vector_double(const Variant& variant); -Variant to_vector_double(const QJsonObject& object); - -QJsonObject from_comboproperty(const Variant& variant); -Variant to_comboproperty(const QJsonObject& object); - -QJsonObject from_qcolor(const Variant& variant); -Variant to_qcolor(const QJsonObject& object); - -QJsonObject from_extproperty(const Variant& variant); -Variant to_extproperty(const QJsonObject& object); - -QJsonObject from_reallimits(const Variant& variant); -Variant to_reallimits(const QJsonObject& object); - -} // namespace - -JsonVariantConverter::JsonVariantConverter() -{ - m_converters[GUI::Constants::invalid_type_name] = {from_invalid, to_invalid}; - m_converters[GUI::Constants::bool_type_name] = {from_bool, to_bool}; - m_converters[GUI::Constants::int_type_name] = {from_int, to_int}; - m_converters[GUI::Constants::string_type_name] = {from_string, to_string}; - m_converters[GUI::Constants::double_type_name] = {from_double, to_double}; - m_converters[GUI::Constants::vector_double_type_name] = {from_vector_double, to_vector_double}; - m_converters[GUI::Constants::comboproperty_type_name] = {from_comboproperty, to_comboproperty}; - m_converters[GUI::Constants::qcolor_type_name] = {from_qcolor, to_qcolor}; - m_converters[GUI::Constants::extproperty_type_name] = {from_extproperty, to_extproperty}; - m_converters[GUI::Constants::reallimits_type_name] = {from_reallimits, to_reallimits}; -} - -QJsonObject JsonVariantConverter::get_json(const Variant& variant) -{ - const std::string type_name = Utils::VariantName(variant); - - if (m_converters.find(type_name) == m_converters.end()) - throw std::runtime_error("json::get_json() -> Error. Unknown variant type '" + type_name - + "'."); - - return m_converters[type_name].variant_to_json(variant); -} - -Variant JsonVariantConverter::get_variant(const QJsonObject& object) -{ - if (!isVariant(object)) - throw std::runtime_error("json::get_variant() -> Error. Invalid json object"); - - const auto type_name = object[variantTypeKey].toString().toStdString(); - if (m_converters.find(type_name) == m_converters.end()) - throw std::runtime_error("json::get_variant() -> Error. Unknown variant type '" + type_name - + "' in json object."); - - return m_converters[type_name].json_to_variant(object); -} - -//! Returns true if given json object represents variant. - -bool JsonVariantConverter::isVariant(const QJsonObject& object) const -{ - static const QStringList expected = expected_variant_keys(); - return object.keys() == expected; -} - -namespace { - -QStringList expected_variant_keys() -{ - QStringList result = QStringList() << variantTypeKey << variantValueKey; - std::sort(result.begin(), result.end()); - return result; -} - -QJsonObject from_invalid(const Variant& variant) -{ - (void)variant; - QJsonObject result; - result[variantTypeKey] = QString::fromStdString(GUI::Constants::invalid_type_name); - result[variantValueKey] = QJsonValue(); - return result; -} - -Variant to_invalid(const QJsonObject& object) -{ - (void)object; - return Variant(); -} - -QJsonObject from_bool(const Variant& variant) -{ - QJsonObject result; - result[variantTypeKey] = QString::fromStdString(GUI::Constants::bool_type_name); - result[variantValueKey] = variant.value<bool>(); - return result; -} - -Variant to_bool(const QJsonObject& object) -{ - return object[variantValueKey].toVariant(); -} - -QJsonObject from_int(const Variant& variant) -{ - QJsonObject result; - result[variantTypeKey] = QString::fromStdString(GUI::Constants::int_type_name); - result[variantValueKey] = variant.value<int>(); - return result; -} - -Variant to_int(const QJsonObject& object) -{ - // deliberately recreating variant, otherwise it is changing type to Qariant::Double - return Variant::fromValue(object[variantValueKey].toVariant().value<int>()); -} - -QJsonObject from_string(const Variant& variant) -{ - QJsonObject result; - result[variantTypeKey] = QString::fromStdString(GUI::Constants::string_type_name); - result[variantValueKey] = QString::fromStdString(variant.value<std::string>()); - return result; -} - -Variant to_string(const QJsonObject& object) -{ - std::string value = object[variantValueKey].toString().toStdString(); - return Variant::fromValue(value); -} - -QJsonObject from_double(const Variant& variant) -{ - QJsonObject result; - result[variantTypeKey] = QString::fromStdString(GUI::Constants::double_type_name); - result[variantValueKey] = variant.value<double>(); - return result; -} - -Variant to_double(const QJsonObject& object) -{ - // deliberately recreating variant, otherwise it is changing type to qlonglong for - // numbers like 43.0 - return object[variantValueKey].toVariant().value<double>(); -} - -// --- std::vector<double> ------ - -QJsonObject from_vector_double(const Variant& variant) -{ - QJsonObject result; - result[variantTypeKey] = QString::fromStdString(GUI::Constants::vector_double_type_name); - QJsonArray array; - auto data = variant.value<std::vector<double>>(); - std::copy(data.begin(), data.end(), std::back_inserter(array)); - result[variantValueKey] = array; - return result; -} - -Variant to_vector_double(const QJsonObject& object) -{ - std::vector<double> vec; - for (auto x : object[variantValueKey].toArray()) - vec.push_back(x.toDouble()); - return Variant::fromValue(vec); -} - -// --- ComboProperty ------ - -QJsonObject from_comboproperty(const Variant& variant) -{ - QJsonObject result; - result[variantTypeKey] = QString::fromStdString(GUI::Constants::comboproperty_type_name); - auto combo = variant.value<ComboProperty>(); - QJsonObject json_data; - json_data[comboValuesKey] = QString::fromStdString(combo.stringOfValues()); - json_data[comboSelectionKey] = QString::fromStdString(combo.stringOfSelections()); - result[variantValueKey] = json_data; - return result; -} - -Variant to_comboproperty(const QJsonObject& object) -{ - ComboProperty combo; - QJsonObject json_data = object[variantValueKey].toObject(); - combo.setStringOfValues(json_data[comboValuesKey].toString().toStdString()); - combo.setStringOfSelections(json_data[comboSelectionKey].toString().toStdString()); - return Variant::fromValue(combo); -} - -// --- QColor ------ - -QJsonObject from_qcolor(const Variant& variant) -{ - QJsonObject result; - result[variantTypeKey] = QString::fromStdString(GUI::Constants::qcolor_type_name); - auto color = variant.value<QColor>(); - result[variantValueKey] = color.name(QColor::HexArgb); - return result; -} - -Variant to_qcolor(const QJsonObject& object) -{ - return Variant::fromValue(QColor(object[variantValueKey].toString())); -} - -// --- ExternalProperty ------ - -QJsonObject from_extproperty(const Variant& variant) -{ - QJsonObject result; - result[variantTypeKey] = QString::fromStdString(GUI::Constants::extproperty_type_name); - auto extprop = variant.value<ExternalProperty>(); - QJsonObject json_data; - json_data[extPropertyTextKey] = QString::fromStdString(extprop.text()); - json_data[extPropertyColorKey] = extprop.color().name(QColor::HexArgb); - json_data[extPropertyIdKey] = QString::fromStdString(extprop.identifier()); - result[variantValueKey] = json_data; - return result; -} - -Variant to_extproperty(const QJsonObject& object) -{ - QJsonObject json_data = object[variantValueKey].toObject(); - const std::string text = json_data[extPropertyTextKey].toString().toStdString(); - const std::string color = json_data[extPropertyColorKey].toString().toStdString(); - const std::string id = json_data[extPropertyIdKey].toString().toStdString(); - - return Variant::fromValue(ExternalProperty(text, QColor(QString::fromStdString(color)), id)); -} - -// --- RealLimits ------ - -QJsonObject from_reallimits(const Variant& variant) -{ - QJsonObject result; - result[variantTypeKey] = QString::fromStdString(GUI::Constants::reallimits_type_name); - auto limits = variant.value<RealLimits>(); - QJsonObject json_data; - - json_data[realLimitsTextKey] = QString::fromStdString(JsonUtils::ToString(limits)); - json_data[realLimitsMinKey] = limits.lowerLimit(); - json_data[realLimitsMaxKey] = limits.upperLimit(); - - result[variantValueKey] = json_data; - return result; -} - -Variant to_reallimits(const QJsonObject& object) -{ - QJsonObject json_data = object[variantValueKey].toObject(); - const std::string text = json_data[realLimitsTextKey].toString().toStdString(); - const double min = json_data[realLimitsMinKey].toDouble(); - const double max = json_data[realLimitsMaxKey].toDouble(); - - return Variant::fromValue(JsonUtils::CreateLimits(text, min, max)); -} - -} // namespace diff --git a/mvvm/model/mvvm/serialization/jsonvariantconverter.h b/mvvm/model/mvvm/serialization/jsonvariantconverter.h deleted file mode 100644 index 154fc1cf1c839b10fda83823831bca1fa45f3db7..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/serialization/jsonvariantconverter.h +++ /dev/null @@ -1,52 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/serialization/jsonvariantconverter.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_SERIALIZATION_JSONVARIANTCONVERTER_H -#define BORNAGAIN_MVVM_MODEL_MVVM_SERIALIZATION_JSONVARIANTCONVERTER_H - -#include "mvvm/core/variant.h" -#include "mvvm/serialization/jsonvariantconverterinterface.h" -#include <functional> -#include <map> -#include <string> - -class QJsonObject; -class QJsonVariant; - -namespace ModelView { - -//! Default converter between supported variants and json objects. - -class MVVM_MODEL_EXPORT JsonVariantConverter : public JsonVariantConverterInterface { -public: - JsonVariantConverter(); - - QJsonObject get_json(const Variant& variant) override; - - Variant get_variant(const QJsonObject& object) override; - - bool isVariant(const QJsonObject& object) const; - -private: - struct Converters { - std::function<QJsonObject(const Variant& variant)> variant_to_json; - std::function<Variant(const QJsonObject& json)> json_to_variant; - }; - - std::map<std::string, Converters> m_converters; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_SERIALIZATION_JSONVARIANTCONVERTER_H diff --git a/mvvm/model/mvvm/serialization/jsonvariantconverterinterface.h b/mvvm/model/mvvm/serialization/jsonvariantconverterinterface.h deleted file mode 100644 index 60f09f99c214109639002223dac3867d76218bbc..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/serialization/jsonvariantconverterinterface.h +++ /dev/null @@ -1,38 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/serialization/jsonvariantconverterinterface.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_SERIALIZATION_JSONVARIANTCONVERTERINTERFACE_H -#define BORNAGAIN_MVVM_MODEL_MVVM_SERIALIZATION_JSONVARIANTCONVERTERINTERFACE_H - -#include "mvvm/core/variant.h" -#include "mvvm/model_export.h" - -class QJsonObject; - -namespace ModelView { - -//! Base class for all supported converters of Variant to/from json object - -class MVVM_MODEL_EXPORT JsonVariantConverterInterface { -public: - virtual ~JsonVariantConverterInterface() = default; - - virtual QJsonObject get_json(const Variant&) = 0; - - virtual Variant get_variant(const QJsonObject&) = 0; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_SERIALIZATION_JSONVARIANTCONVERTERINTERFACE_H diff --git a/mvvm/model/mvvm/signals/CMakeLists.txt b/mvvm/model/mvvm/signals/CMakeLists.txt deleted file mode 100644 index c25a84b2bb8ac2ccb1b17b0c1ad54ffc6e0d7537..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/signals/CMakeLists.txt +++ /dev/null @@ -1,14 +0,0 @@ -target_sources(${library_name} PRIVATE - callback_types.h - callbackcontainer.h - itemlistener.h - itemlistenerbase.cpp - itemlistenerbase.h - itemmapper.cpp - itemmapper.h - modellistener.h - modellistenerbase.cpp - modellistenerbase.h - modelmapper.cpp - modelmapper.h -) diff --git a/mvvm/model/mvvm/signals/callback_types.h b/mvvm/model/mvvm/signals/callback_types.h deleted file mode 100644 index ecb76cfc975bb9997194d6562f1eacc236b6f753..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/signals/callback_types.h +++ /dev/null @@ -1,38 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/signals/callback_types.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_SIGNALS_CALLBACK_TYPES_H -#define BORNAGAIN_MVVM_MODEL_MVVM_SIGNALS_CALLBACK_TYPES_H - -#include "mvvm/model/tagrow.h" -#include <functional> -#include <string> - -namespace ModelView { - -class SessionItem; -class SessionModel; - -namespace Callbacks { -using slot_t = const void*; -using item_t = std::function<void(SessionItem*)>; -using item_int_t = std::function<void(SessionItem*, int)>; -using item_str_t = std::function<void(SessionItem*, std::string)>; -using item_tagrow_t = std::function<void(SessionItem*, TagRow)>; -using model_t = std::function<void(SessionModel*)>; -} // namespace Callbacks - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_SIGNALS_CALLBACK_TYPES_H diff --git a/mvvm/model/mvvm/signals/callbackcontainer.h b/mvvm/model/mvvm/signals/callbackcontainer.h deleted file mode 100644 index 34cb3073d094ee3800ea8d23eceb64c2125cbfa3..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/signals/callbackcontainer.h +++ /dev/null @@ -1,75 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/signals/callbackcontainer.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_SIGNALS_CALLBACKCONTAINER_H -#define BORNAGAIN_MVVM_MODEL_MVVM_SIGNALS_CALLBACKCONTAINER_H - -#include "mvvm/model_export.h" -#include "mvvm/signals/callback_types.h" -#include <algorithm> -#include <functional> -#include <list> - -namespace ModelView { - -class SessionItem; -class SessionModel; - -//! Container to hold callbacks in the context of ModelMapper. - -template <typename T, typename U> class SignalBase { -public: - SignalBase() = default; - - void connect(T callback, U client); - - template <typename... Args> void operator()(Args... args); - - void remove_client(U client); - -private: - std::list<std::pair<T, U>> m_callbacks; -}; - -template <typename T, typename U> void SignalBase<T, U>::connect(T callback, U client) -{ - m_callbacks.push_back(std::make_pair(callback, client)); -} - -//! Notify clients using given list of arguments. -template <typename T, typename U> -template <typename... Args> -void SignalBase<T, U>::operator()(Args... args) -{ - for (const auto& f : m_callbacks) { - f.first(args...); - } -} - -//! Remove client from the list to call back. - -template <typename T, typename U> void SignalBase<T, U>::remove_client(U client) -{ - m_callbacks.remove_if( - [client](const std::pair<T, U>& x) -> bool { return (x.second == client ? true : false); }); -} - -//! Callback container for specific client type. - -template <typename T> class Signal : public SignalBase<T, Callbacks::slot_t> { -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_SIGNALS_CALLBACKCONTAINER_H diff --git a/mvvm/model/mvvm/signals/itemlistener.h b/mvvm/model/mvvm/signals/itemlistener.h deleted file mode 100644 index 076b52b05ec243cdb51e4ff5fba65c7fcecfa831..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/signals/itemlistener.h +++ /dev/null @@ -1,33 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/signals/itemlistener.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_SIGNALS_ITEMLISTENER_H -#define BORNAGAIN_MVVM_MODEL_MVVM_SIGNALS_ITEMLISTENER_H - -#include "mvvm/signals/itemlistenerbase.h" - -namespace ModelView { - -class SessionItem; - -//! Base class to subscribe to signals generated by SessionItem of certin type. - -template <typename T> class ItemListener : public ItemListenerBase { -public: - T* currentItem() const { return static_cast<T*>(item()); } -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_SIGNALS_ITEMLISTENER_H diff --git a/mvvm/model/mvvm/signals/itemlistenerbase.cpp b/mvvm/model/mvvm/signals/itemlistenerbase.cpp deleted file mode 100644 index 830f47038091ab782d9887c5ce9f6e0f6fa10868..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/signals/itemlistenerbase.cpp +++ /dev/null @@ -1,125 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/signals/itemlistenerbase.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "itemlistenerbase.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/signals/itemmapper.h" - -ModelView::ItemListenerBase::ItemListenerBase(ModelView::SessionItem* item) -{ - setItem(item); -} - -ModelView::ItemListenerBase::~ItemListenerBase() -{ - if (m_item) - m_item->mapper()->unsubscribe(this); -} - -void ModelView::ItemListenerBase::setItem(ModelView::SessionItem* item) -{ - if (m_item == item) - return; - - unsubscribe_from_current(); - - m_item = item; - - if (!m_item) - return; - - auto on_item_destroy = [this](auto) { - m_item = nullptr; - unsubscribe(); - }; - m_item->mapper()->setOnItemDestroy(on_item_destroy, this); - - subscribe(); -} - -void ModelView::ItemListenerBase::setOnItemDestroy(ModelView::Callbacks::item_t f) -{ - item()->mapper()->setOnItemDestroy(f, this); -} - -//! Sets callback to be notified on item's data change. -//! Callback will be called with (SessionItem*, data_role). - -void ModelView::ItemListenerBase::setOnDataChange(ModelView::Callbacks::item_int_t f) -{ - item()->mapper()->setOnDataChange(f, this); -} - -//! Sets callback to be notified on item's property change. -//! Callback will be called with (compound_item, property_name). - -void ModelView::ItemListenerBase::setOnPropertyChange(ModelView::Callbacks::item_str_t f) -{ - item()->mapper()->setOnPropertyChange(f, this); -} - -//! Sets callback to be notified on item's children property change. -//! Callback will be called with (compound_item, property_name). For MultiLayer containing the -//! layer with "thickness" property, the signal will be triggered on thickness change using -//! (layeritem*, "thickness") as callback parameters. - -void ModelView::ItemListenerBase::setOnChildPropertyChange(ModelView::Callbacks::item_str_t f) -{ - item()->mapper()->setOnChildPropertyChange(f, this); -} - -//! Sets callback to be notified on child insertion. -//! Callback will be called with (compound_item, tag, row). For MultiLayer containing the T_LAYERS -//! tag, the signal will be triggered on layer insertion with -//! (multilayer*, {T_LAYER, row}) as callback parameters. - -void ModelView::ItemListenerBase::setOnItemInserted(ModelView::Callbacks::item_tagrow_t f) -{ - item()->mapper()->setOnItemInserted(f, this); -} - -//! Sets callback to be notified on child removal. -//! Callback will be called with (compound_item, tag, row). For MultiLayer containing the T_LAYERS -//! tag, the signal will be triggered on layer removal with -//! (multilayer*, {T_LAYER, oldrow}) as callback parameters. - -void ModelView::ItemListenerBase::setOnItemRemoved(ModelView::Callbacks::item_tagrow_t f) -{ - item()->mapper()->setOnItemRemoved(f, this); -} - -void ModelView::ItemListenerBase::setOnAboutToRemoveItem(ModelView::Callbacks::item_tagrow_t f) -{ - item()->mapper()->setOnAboutToRemoveItem(f, this); -} - -//! Sets callback to be notified when row is about to be removed. -//! Callback will be called with (compound_item, tagrow). For MultiLayer containing the T_LAYERS -//! tag, the signal will be triggered on layer deletion with -//! (multilayer*, {T_LAYER, row}) as callback parameters. - -ModelView::SessionItem* ModelView::ItemListenerBase::item() const -{ - return m_item; -} - -void ModelView::ItemListenerBase::unsubscribe_from_current() -{ - if (!m_item) - return; - - unsubscribe(); - - m_item->mapper()->unsubscribe(this); -} diff --git a/mvvm/model/mvvm/signals/itemlistenerbase.h b/mvvm/model/mvvm/signals/itemlistenerbase.h deleted file mode 100644 index cc92626522ee0afc7248d99bcf6ef5d64bf10956..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/signals/itemlistenerbase.h +++ /dev/null @@ -1,61 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/signals/itemlistenerbase.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_SIGNALS_ITEMLISTENERBASE_H -#define BORNAGAIN_MVVM_MODEL_MVVM_SIGNALS_ITEMLISTENERBASE_H - -#include "mvvm/model_export.h" -#include "mvvm/signals/callback_types.h" - -namespace ModelView { - -class SessionItem; - -//! Provides sets of methods to subscribe to various signals generated by SessionItem. -//! Used to implement user actions on item change. - -//! Automatically tracks the time of life of SessionItem. Unsubscribes from the item on -//! own destruction. Can be switched from tracking one item to another of the same type. - -class MVVM_MODEL_EXPORT ItemListenerBase { -public: - explicit ItemListenerBase(SessionItem* item = nullptr); - virtual ~ItemListenerBase(); - - ItemListenerBase& operator=(const ItemListenerBase& other) = delete; - ItemListenerBase(const ItemListenerBase& other) = delete; - - void setItem(SessionItem* item); - - void setOnItemDestroy(Callbacks::item_t f); - void setOnDataChange(Callbacks::item_int_t f); - void setOnPropertyChange(Callbacks::item_str_t f); - void setOnChildPropertyChange(Callbacks::item_str_t f); - void setOnItemInserted(Callbacks::item_tagrow_t f); - void setOnItemRemoved(Callbacks::item_tagrow_t f); - void setOnAboutToRemoveItem(Callbacks::item_tagrow_t f); - -protected: - virtual void subscribe() {} //! For necessary manipulations on new item. - virtual void unsubscribe() {} //! For necessary manipulations on unsubscription. - SessionItem* item() const; - -private: - void unsubscribe_from_current(); - SessionItem* m_item{nullptr}; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_SIGNALS_ITEMLISTENERBASE_H diff --git a/mvvm/model/mvvm/signals/itemmapper.cpp b/mvvm/model/mvvm/signals/itemmapper.cpp deleted file mode 100644 index 920a484062f8f9f1a903c3f33605f2b85c226bb1..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/signals/itemmapper.cpp +++ /dev/null @@ -1,232 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/signals/itemmapper.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/signals/itemmapper.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/signals/callbackcontainer.h" -#include "mvvm/signals/modelmapper.h" -#include <stdexcept> - -using namespace ModelView; - -struct ItemMapper::ItemMapperImpl { - ItemMapper* m_itemMapper{nullptr}; - Signal<Callbacks::item_t> m_on_item_destroy; - Signal<Callbacks::item_int_t> m_on_data_change; - Signal<Callbacks::item_str_t> m_on_property_change; - Signal<Callbacks::item_str_t> m_on_child_property_change; - Signal<Callbacks::item_tagrow_t> m_on_item_inserted; - Signal<Callbacks::item_tagrow_t> m_on_item_removed; - Signal<Callbacks::item_tagrow_t> m_on_about_to_remove_item; - - bool m_active{true}; - SessionItem* m_item{nullptr}; - - ItemMapperImpl(ItemMapper* item_mapper) : m_itemMapper(item_mapper) {} - - void unsubscribe(Callbacks::slot_t client) - { - m_on_item_destroy.remove_client(client); - m_on_data_change.remove_client(client); - m_on_property_change.remove_client(client); - m_on_child_property_change.remove_client(client); - m_on_item_inserted.remove_client(client); - m_on_item_removed.remove_client(client); - m_on_about_to_remove_item.remove_client(client); - } - - int nestlingDepth(SessionItem* item, int level = 0) - { - if (item == nullptr || item == m_itemMapper->model()->rootItem()) - return -1; - if (item == m_item) - return level; - return nestlingDepth(item->parent(), level + 1); - } - - //! Processes signals from the model when item data changed. - - void processDataChange(SessionItem* item, int role) - { - int nestling = nestlingDepth(item); - - // own item data changed - if (nestling == 0) - callOnDataChange(item, role); - - // data of item's property changed - if (nestling == 1) - callOnPropertyChange(m_item, m_item->tagRowOfItem(item).tag); - - // child property changed - if (nestling == 2) { - if (auto parent = item->parent()) - callOnChildPropertyChange(parent, parent->tagRowOfItem(item).tag); - } - } - - void processItemInserted(SessionItem* parent, const TagRow& tagrow) - { - if (parent == m_item) - callOnItemInserted(m_item, tagrow); - } - - void processItemRemoved(SessionItem* parent, const TagRow& tagrow) - { - if (parent == m_item) - callOnItemRemoved(m_item, tagrow); - } - - void processAboutToRemoveItem(SessionItem* parent, const TagRow& tagrow) - { - if (parent == m_item) - callOnAboutToRemoveItem(m_item, tagrow); - } - - //! Notifies all callbacks subscribed to "item data is changed" event. - - void callOnDataChange(SessionItem* item, int role) - { - if (m_active) - m_on_data_change(item, role); - } - - //! Notifies all callbacks subscribed to "item property is changed" event. - - void callOnPropertyChange(SessionItem* item, const std::string& property_name) - { - if (m_active) - m_on_property_change(item, property_name); - } - - //! Notifies all callbacks subscribed to "child property changed" event. - - void callOnChildPropertyChange(SessionItem* item, const std::string& property_name) - { - if (m_active) - m_on_child_property_change(item, property_name); - } - - //! Notifies all callbacks subscribed to "on row inserted" event. - - void callOnItemInserted(SessionItem* parent, const TagRow& tagrow) - { - if (m_active) - m_on_item_inserted(parent, tagrow); - } - - //! Notifies all callbacks subscribed to "on row removed" event. - - void callOnItemRemoved(SessionItem* parent, const TagRow& tagrow) - { - if (m_active) - m_on_item_removed(parent, tagrow); - } - - //! Notifies all callbacks subscribed to "on row about to be removed". - - void callOnAboutToRemoveItem(SessionItem* parent, const TagRow& tagrow) - { - if (m_active) - m_on_about_to_remove_item(parent, tagrow); - } -}; - -ItemMapper::ItemMapper(SessionItem* item) - : ModelListener(item->model()), p_impl(std::make_unique<ItemMapperImpl>(this)) -{ - if (!item) - throw std::runtime_error("ItemMapper::ItemMapper() -> Not initialized item"); - - if (!item->model()) - throw std::runtime_error("ItemMapper::ItemMapper() -> Item doesn't have model"); - - p_impl->m_item = item; - - auto on_data_change = [this](auto item, auto role) { p_impl->processDataChange(item, role); }; - ModelListener::setOnDataChange(on_data_change); - - auto on_item_inserted = [this](auto item, auto tagrow) { - p_impl->processItemInserted(item, tagrow); - }; - ModelListener::setOnItemInserted(on_item_inserted, this); - - auto on_item_removed = [this](auto item, auto tagrow) { - p_impl->processItemRemoved(item, tagrow); - }; - ModelListener::setOnItemRemoved(on_item_removed, this); - - auto on_about_to_remove_item = [this](auto item, auto tagrow) { - p_impl->processAboutToRemoveItem(item, tagrow); - }; - ModelListener::setOnAboutToRemoveItem(on_about_to_remove_item, this); -} - -ItemMapper::~ItemMapper() = default; - -void ItemMapper::setOnItemDestroy(Callbacks::item_t f, Callbacks::slot_t owner) -{ - p_impl->m_on_item_destroy.connect(std::move(f), owner); -} - -void ItemMapper::setOnDataChange(Callbacks::item_int_t f, Callbacks::slot_t owner) -{ - p_impl->m_on_data_change.connect(std::move(f), owner); -} - -void ItemMapper::setOnPropertyChange(Callbacks::item_str_t f, Callbacks::slot_t owner) -{ - p_impl->m_on_property_change.connect(std::move(f), owner); -} - -void ItemMapper::setOnChildPropertyChange(Callbacks::item_str_t f, Callbacks::slot_t owner) -{ - p_impl->m_on_child_property_change.connect(std::move(f), owner); -} - -void ItemMapper::setOnItemInserted(Callbacks::item_tagrow_t f, Callbacks::slot_t owner) -{ - p_impl->m_on_item_inserted.connect(std::move(f), owner); -} - -void ItemMapper::setOnItemRemoved(Callbacks::item_tagrow_t f, Callbacks::slot_t owner) -{ - p_impl->m_on_item_removed.connect(std::move(f), owner); -} - -void ItemMapper::setOnAboutToRemoveItem(Callbacks::item_tagrow_t f, Callbacks::slot_t owner) -{ - p_impl->m_on_about_to_remove_item.connect(std::move(f), owner); -} - -void ItemMapper::unsubscribe(Callbacks::slot_t client) -{ - p_impl->unsubscribe(client); -} - -//! Sets activity flag to given value. Will disable all callbacks if false. - -void ItemMapper::setActive(bool value) -{ - p_impl->m_active = value; -} - -//! Calls all callbacks subscribed to "item is destroyed" event. - -void ItemMapper::callOnItemDestroy() -{ - if (p_impl->m_active) - p_impl->m_on_item_destroy(p_impl->m_item); -} diff --git a/mvvm/model/mvvm/signals/itemmapper.h b/mvvm/model/mvvm/signals/itemmapper.h deleted file mode 100644 index 1d48b5dd4dd0321c9a787007a94abacaf20b7c97..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/signals/itemmapper.h +++ /dev/null @@ -1,59 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/signals/itemmapper.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_SIGNALS_ITEMMAPPER_H -#define BORNAGAIN_MVVM_MODEL_MVVM_SIGNALS_ITEMMAPPER_H - -#include "mvvm/interfaces/itemlistenerinterface.h" -#include "mvvm/signals/modellistener.h" -#include <memory> - -namespace ModelView { - -class SessionItem; - -//! Provides notifications on various changes for a specific item. -//! ItemMapper listens signals coming from the model (i.e. via ModelMapper) and processes only whose -//! signals which are related to the given item. Notifies all interested subscribers about things -//! going with the item and its relatives. - -class MVVM_MODEL_EXPORT ItemMapper : public ItemListenerInterface, - private ModelListener<SessionModel> { -public: - ItemMapper(SessionItem* item); - ~ItemMapper(); - - void setOnItemDestroy(Callbacks::item_t f, Callbacks::slot_t owner) override; - void setOnDataChange(Callbacks::item_int_t f, Callbacks::slot_t owner) override; - void setOnPropertyChange(Callbacks::item_str_t f, Callbacks::slot_t owner) override; - void setOnChildPropertyChange(Callbacks::item_str_t f, Callbacks::slot_t owner) override; - void setOnItemInserted(Callbacks::item_tagrow_t f, Callbacks::slot_t owner) override; - void setOnItemRemoved(Callbacks::item_tagrow_t f, Callbacks::slot_t owner) override; - void setOnAboutToRemoveItem(Callbacks::item_tagrow_t f, Callbacks::slot_t owner) override; - - void unsubscribe(Callbacks::slot_t client) override; - - void setActive(bool value); - -private: - friend class SessionItem; - void callOnItemDestroy(); - - struct ItemMapperImpl; - std::unique_ptr<ItemMapperImpl> p_impl; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_SIGNALS_ITEMMAPPER_H diff --git a/mvvm/model/mvvm/signals/modellistener.h b/mvvm/model/mvvm/signals/modellistener.h deleted file mode 100644 index 594102480ead98b98800cafb0528bcc81b1e0c72..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/signals/modellistener.h +++ /dev/null @@ -1,35 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/signals/modellistener.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_SIGNALS_MODELLISTENER_H -#define BORNAGAIN_MVVM_MODEL_MVVM_SIGNALS_MODELLISTENER_H - -#include "mvvm/signals/modellistenerbase.h" - -namespace ModelView { - -class SessionItem; - -//! Templated class for all objects willing to listen for changes in concrete SessionModel. - -template <typename T> class ModelListener : public ModelListenerBase { -public: - ModelListener(T* session_model) : ModelListenerBase(session_model) {} - - T* model() const { return static_cast<T*>(m_model); } -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_SIGNALS_MODELLISTENER_H diff --git a/mvvm/model/mvvm/signals/modellistenerbase.cpp b/mvvm/model/mvvm/signals/modellistenerbase.cpp deleted file mode 100644 index 4a8afb3663e364465a7e0bed0f8a2b841c2684db..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/signals/modellistenerbase.cpp +++ /dev/null @@ -1,92 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/signals/modellistenerbase.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/signals/modellistenerbase.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/signals/modelmapper.h" -#include <stdexcept> - -using namespace ModelView; - -ModelListenerBase::ModelListenerBase(SessionModel* model) : m_model(model) -{ - if (!m_model) - throw std::runtime_error("Error in ModelListenerBase: no model defined"); - setOnModelDestroyed([this](SessionModel*) { m_model = nullptr; }); -} - -ModelListenerBase::~ModelListenerBase() -{ - unsubscribe(); -} - -//! Sets callback to be notified on item's data change. The callback will be called -//! with (SessionItem*, data_role). - -void ModelListenerBase::setOnDataChange(ModelView::Callbacks::item_int_t f, Callbacks::slot_t) -{ - m_model->mapper()->setOnDataChange(f, this); -} - -//! Sets callback to be notified on item insert. The callback will be called with -//! (SessionItem* parent, tagrow), where 'tagrow' denotes inserted child position. - -void ModelListenerBase::setOnItemInserted(ModelView::Callbacks::item_tagrow_t f, Callbacks::slot_t) -{ - m_model->mapper()->setOnItemInserted(f, this); -} - -//! Sets callback to be notified on item remove. The callback will be called with -//! (SessionItem* parent, tagrow), where 'tagrow' denotes child position before the removal. - -void ModelListenerBase::setOnItemRemoved(ModelView::Callbacks::item_tagrow_t f, Callbacks::slot_t) -{ - m_model->mapper()->setOnItemRemoved(f, this); -} - -//! Sets callback to be notified when the item is about to be removed. The callback will be called -//! with (SessionItem* parent, tagrow), where 'tagrow' denotes child position being removed. - -void ModelListenerBase::setOnAboutToRemoveItem(ModelView::Callbacks::item_tagrow_t f, - Callbacks::slot_t) -{ - m_model->mapper()->setOnAboutToRemoveItem(f, this); -} - -//! Sets the callback for notifications on model destruction. - -void ModelListenerBase::setOnModelDestroyed(Callbacks::model_t f, Callbacks::slot_t) -{ - m_model->mapper()->setOnModelDestroyed(f, this); -} - -//! Sets the callback to be notified before model's full reset (root item recreated). - -void ModelListenerBase::setOnModelAboutToBeReset(Callbacks::model_t f, Callbacks::slot_t) -{ - m_model->mapper()->setOnModelAboutToBeReset(f, this); -} - -//! Sets the callback to be notified after model was fully reset (root item recreated). - -void ModelListenerBase::setOnModelReset(ModelView::Callbacks::model_t f, Callbacks::slot_t) -{ - m_model->mapper()->setOnModelReset(f, this); -} - -void ModelListenerBase::unsubscribe(Callbacks::slot_t) -{ - if (m_model) - m_model->mapper()->unsubscribe(this); -} diff --git a/mvvm/model/mvvm/signals/modellistenerbase.h b/mvvm/model/mvvm/signals/modellistenerbase.h deleted file mode 100644 index cdd2f940e9b1b2873a05012a7aa119ffae593951..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/signals/modellistenerbase.h +++ /dev/null @@ -1,51 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/signals/modellistenerbase.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_SIGNALS_MODELLISTENERBASE_H -#define BORNAGAIN_MVVM_MODEL_MVVM_SIGNALS_MODELLISTENERBASE_H - -#include "mvvm/interfaces/modellistenerinterface.h" - -namespace ModelView { - -class SessionModel; - -//! Provides sets of methods to subscribe to various signals generated by SessionModel. -//! Automatically tracks the time of life of SessionModel. Unsubscribes from the model on -//! own destruction. - -class MVVM_MODEL_EXPORT ModelListenerBase : public ModelListenerInterface { -public: - ModelListenerBase(SessionModel* model); - ~ModelListenerBase() override; - - // 'client' is not used here, since 'this' is used - - void setOnDataChange(Callbacks::item_int_t f, Callbacks::slot_t client = {}) override; - void setOnItemInserted(Callbacks::item_tagrow_t f, Callbacks::slot_t client = {}) override; - void setOnItemRemoved(Callbacks::item_tagrow_t f, Callbacks::slot_t client = {}) override; - void setOnAboutToRemoveItem(Callbacks::item_tagrow_t f, Callbacks::slot_t client = {}) override; - void setOnModelDestroyed(Callbacks::model_t f, Callbacks::slot_t client = {}) override; - void setOnModelAboutToBeReset(Callbacks::model_t f, Callbacks::slot_t client = {}) override; - void setOnModelReset(Callbacks::model_t f, Callbacks::slot_t client = {}) override; - - void unsubscribe(Callbacks::slot_t client = {}) override; - -protected: - SessionModel* m_model{nullptr}; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_SIGNALS_MODELLISTENERBASE_H diff --git a/mvvm/model/mvvm/signals/modelmapper.cpp b/mvvm/model/mvvm/signals/modelmapper.cpp deleted file mode 100644 index 2fef63ad9dc8b8f0dbada699c1563800106bf95d..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/signals/modelmapper.cpp +++ /dev/null @@ -1,158 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/signals/modelmapper.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/signals/modelmapper.h" -#include "mvvm/signals/callbackcontainer.h" - -using namespace ModelView; - -struct ModelMapper::ModelMapperImpl { - Signal<Callbacks::item_int_t> m_on_data_change; - Signal<Callbacks::item_tagrow_t> m_on_item_inserted; - Signal<Callbacks::item_tagrow_t> m_on_item_removed; - Signal<Callbacks::item_tagrow_t> m_on_item_about_removed; - Signal<Callbacks::model_t> m_on_model_destroyed; - Signal<Callbacks::model_t> m_on_model_about_reset; - Signal<Callbacks::model_t> m_on_model_reset; - - bool m_active{true}; - SessionModel* m_model{nullptr}; - - ModelMapperImpl(SessionModel* model) : m_model(model){}; - - void unsubscribe(Callbacks::slot_t client) - { - m_on_data_change.remove_client(client); - m_on_item_inserted.remove_client(client); - m_on_item_removed.remove_client(client); - m_on_item_about_removed.remove_client(client); - m_on_model_destroyed.remove_client(client); - m_on_model_about_reset.remove_client(client); - m_on_model_reset.remove_client(client); - } -}; - -ModelMapper::ModelMapper(SessionModel* model) : p_impl(std::make_unique<ModelMapperImpl>(model)) {} - -ModelMapper::~ModelMapper() = default; - -//! Sets callback to be notified on item's data change. The callback will be called -//! with (SessionItem*, data_role). - -void ModelMapper::setOnDataChange(Callbacks::item_int_t f, Callbacks::slot_t client) -{ - p_impl->m_on_data_change.connect(std::move(f), client); -} - -//! Sets callback to be notified on item insert. The callback will be called with -//! (SessionItem* parent, tagrow), where 'tagrow' denotes inserted child position. - -void ModelMapper::setOnItemInserted(Callbacks::item_tagrow_t f, Callbacks::slot_t client) -{ - p_impl->m_on_item_inserted.connect(std::move(f), client); -} - -//! Sets callback to be notified on item remove. The callback will be called with -//! (SessionItem* parent, tagrow), where 'tagrow' denotes child position before the removal. - -void ModelMapper::setOnItemRemoved(Callbacks::item_tagrow_t f, Callbacks::slot_t client) -{ - p_impl->m_on_item_removed.connect(std::move(f), client); -} - -//! Sets callback to be notified when the item is about to be removed. The callback will be called -//! with (SessionItem* parent, tagrow), where 'tagrow' denotes child position being removed. - -void ModelMapper::setOnAboutToRemoveItem(Callbacks::item_tagrow_t f, Callbacks::slot_t client) -{ - p_impl->m_on_item_about_removed.connect(std::move(f), client); -} - -//! Sets the callback for notifications on model destruction. - -void ModelMapper::setOnModelDestroyed(Callbacks::model_t f, Callbacks::slot_t client) -{ - p_impl->m_on_model_destroyed.connect(std::move(f), client); -} - -//! Sets the callback to be notified just before the reset of the root item. - -void ModelMapper::setOnModelAboutToBeReset(Callbacks::model_t f, Callbacks::slot_t client) -{ - p_impl->m_on_model_about_reset.connect(std::move(f), client); -} - -//! Sets the callback to be notified right after the root item recreation. - -void ModelMapper::setOnModelReset(Callbacks::model_t f, Callbacks::slot_t client) -{ - p_impl->m_on_model_reset.connect(std::move(f), client); -} - -//! Sets activity flag to given value. Will disable all callbacks if false. - -void ModelMapper::setActive(bool value) -{ - p_impl->m_active = value; -} - -//! Removes given client from all subscriptions. - -void ModelMapper::unsubscribe(Callbacks::slot_t client) -{ - p_impl->unsubscribe(client); -} - -//! Notifies all callbacks subscribed to "item data is changed" event. - -void ModelMapper::callOnDataChange(SessionItem* item, int role) -{ - if (p_impl->m_active) - p_impl->m_on_data_change(item, role); -} - -//! Notifies all callbacks subscribed to "item data is changed" event. - -void ModelMapper::callOnItemInserted(SessionItem* parent, const TagRow& tagrow) -{ - if (p_impl->m_active) - p_impl->m_on_item_inserted(parent, tagrow); -} - -void ModelMapper::callOnItemRemoved(SessionItem* parent, const TagRow& tagrow) -{ - if (p_impl->m_active) - p_impl->m_on_item_removed(parent, tagrow); -} - -void ModelMapper::callOnItemAboutToBeRemoved(SessionItem* parent, const TagRow& tagrow) -{ - if (p_impl->m_active) - p_impl->m_on_item_about_removed(parent, tagrow); -} - -void ModelMapper::callOnModelDestroyed() -{ - p_impl->m_on_model_destroyed(p_impl->m_model); -} - -void ModelMapper::callOnModelAboutToBeReset() -{ - p_impl->m_on_model_about_reset(p_impl->m_model); -} - -void ModelMapper::callOnModelReset() -{ - p_impl->m_on_model_reset(p_impl->m_model); -} diff --git a/mvvm/model/mvvm/signals/modelmapper.h b/mvvm/model/mvvm/signals/modelmapper.h deleted file mode 100644 index 7e84ad4169e5ad3f9b8a35a54aaf2f1105d94285..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/signals/modelmapper.h +++ /dev/null @@ -1,67 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/signals/modelmapper.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_SIGNALS_MODELMAPPER_H -#define BORNAGAIN_MVVM_MODEL_MVVM_SIGNALS_MODELMAPPER_H - -#include "mvvm/interfaces/modellistenerinterface.h" -#include <memory> - -namespace ModelView { - -class SessionItem; -class SessionModel; - -//! Provides notifications on various SessionModel changes. -//! Allows to subscribe to SessionModel's changes, and triggers notifications. - -class MVVM_MODEL_EXPORT ModelMapper : public ModelListenerInterface { -public: - ModelMapper(SessionModel* model); - ~ModelMapper(); - - ModelMapper(const ModelMapper& other) = delete; - ModelMapper& operator=(const ModelMapper& other) = delete; - - void setOnDataChange(Callbacks::item_int_t f, Callbacks::slot_t client) override; - void setOnItemInserted(Callbacks::item_tagrow_t f, Callbacks::slot_t client) override; - void setOnItemRemoved(Callbacks::item_tagrow_t f, Callbacks::slot_t client) override; - void setOnAboutToRemoveItem(Callbacks::item_tagrow_t f, Callbacks::slot_t client) override; - void setOnModelDestroyed(Callbacks::model_t f, Callbacks::slot_t client) override; - void setOnModelAboutToBeReset(Callbacks::model_t f, Callbacks::slot_t client) override; - void setOnModelReset(Callbacks::model_t f, Callbacks::slot_t client) override; - - void setActive(bool value); - - void unsubscribe(Callbacks::slot_t client) override; - -private: - friend class SessionModel; - friend class SessionItem; - - void callOnDataChange(SessionItem* item, int role); - void callOnItemInserted(SessionItem* parent, const TagRow& tagrow); - void callOnItemRemoved(SessionItem* parent, const TagRow& tagrow); - void callOnItemAboutToBeRemoved(SessionItem* parent, const TagRow& tagrow); - void callOnModelDestroyed(); - void callOnModelAboutToBeReset(); - void callOnModelReset(); - - struct ModelMapperImpl; - std::unique_ptr<ModelMapperImpl> p_impl; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_SIGNALS_MODELMAPPER_H diff --git a/mvvm/model/mvvm/standarditems/CMakeLists.txt b/mvvm/model/mvvm/standarditems/CMakeLists.txt deleted file mode 100644 index 69120e605740e832d87058eb36002d02c628d6f4..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/standarditems/CMakeLists.txt +++ /dev/null @@ -1,27 +0,0 @@ -target_sources(${library_name} PRIVATE - axisitems.cpp - axisitems.h - colormapitem.cpp - colormapitem.h - colormapviewportitem.cpp - colormapviewportitem.h - containeritem.cpp - containeritem.h - data1ditem.cpp - data1ditem.h - data2ditem.cpp - data2ditem.h - graphitem.cpp - graphitem.h - graphviewportitem.cpp - graphviewportitem.h - linkeditem.cpp - linkeditem.h - plottableitems.cpp - plottableitems.h - standarditemincludes.h - vectoritem.cpp - vectoritem.h - viewportitem.cpp - viewportitem.h -) diff --git a/mvvm/model/mvvm/standarditems/axisitems.cpp b/mvvm/model/mvvm/standarditems/axisitems.cpp deleted file mode 100644 index b06e9b6dbedd6a9ff7fda1907c79bb3d010b668a..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/standarditems/axisitems.cpp +++ /dev/null @@ -1,149 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/standarditems/axisitems.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/standarditems/axisitems.h" -#include "mvvm/standarditems/plottableitems.h" - -namespace { -const double default_axis_min = 0.0; -const double default_axis_max = 1.0; -} // namespace - -using namespace ModelView; - -BasicAxisItem::BasicAxisItem(const std::string& model_type) : CompoundItem(model_type) {} - -void BasicAxisItem::register_min_max() -{ - addProperty(P_MIN, default_axis_min)->setDisplayName("Min"); - addProperty(P_MAX, default_axis_max)->setDisplayName("Max"); -} - -// --- ViewportAxisItem ------------------------------------------------------ - -ViewportAxisItem::ViewportAxisItem(const std::string& model_type) : BasicAxisItem(model_type) -{ - addProperty<TextItem>(P_TITLE)->setDisplayName("Title"); - register_min_max(); - addProperty(P_IS_LOG, false)->setDisplayName("log10"); -} - -//! Returns pair of lower, upper axis range. - -std::pair<double, double> ViewportAxisItem::range() const -{ - return std::make_pair(property<double>(P_MIN), property<double>(P_MAX)); -} - -//! Sets lower, upper range of axis to given values. - -void ViewportAxisItem::set_range(double lower, double upper) -{ - setProperty(P_MIN, lower); - setProperty(P_MAX, upper); -} - -bool ViewportAxisItem::is_in_log() const -{ - return property<bool>(P_IS_LOG); -} - -// --- BinnedAxisItem ------------------------------------------------------ - -BinnedAxisItem::BinnedAxisItem(const std::string& model_type) : BasicAxisItem(model_type) {} - -// --- FixedBinAxisItem ------------------------------------------------------ - -FixedBinAxisItem::FixedBinAxisItem(const std::string& model_type) : BinnedAxisItem(model_type) -{ - addProperty(P_NBINS, 1)->setDisplayName("Nbins"); - register_min_max(); -} - -void FixedBinAxisItem::setParameters(int nbins, double xmin, double xmax) -{ - setProperty(P_NBINS, nbins); - setProperty(P_MIN, xmin); - setProperty(P_MAX, xmax); -} - -std::unique_ptr<FixedBinAxisItem> FixedBinAxisItem::create(int nbins, double xmin, double xmax) -{ - auto result = std::make_unique<FixedBinAxisItem>(); - result->setParameters(nbins, xmin, xmax); - return result; -} - -std::pair<double, double> FixedBinAxisItem::range() const -{ - return std::make_pair(property<double>(P_MIN), property<double>(P_MAX)); -} - -int FixedBinAxisItem::size() const -{ - return property<int>(P_NBINS); -} - -std::vector<double> FixedBinAxisItem::binCenters() const -{ - std::vector<double> result; - int nbins = property<int>(P_NBINS); - double start = property<double>(P_MIN); - double end = property<double>(P_MAX); - double step = (end - start) / nbins; - - result.resize(static_cast<size_t>(nbins), 0.0); - for (size_t i = 0; i < static_cast<size_t>(nbins); ++i) - result[i] = start + step * (i + 0.5); - - return result; -} - -// --- PointwiseAxisItem ------------------------------------------------------ - -PointwiseAxisItem::PointwiseAxisItem(const std::string& model_type) : BinnedAxisItem(model_type) -{ - // vector of points matching default xmin, xmax - setData(std::vector<double>{default_axis_min, default_axis_max}); - setEditable(false); // prevent editing in widgets, since there is no corresponding editor -} - -void PointwiseAxisItem::setParameters(const std::vector<double>& data) -{ - setData(data); -} - -std::unique_ptr<PointwiseAxisItem> PointwiseAxisItem::create(const std::vector<double>& data) -{ - auto result = std::make_unique<PointwiseAxisItem>(); - result->setParameters(data); - return result; -} - -std::pair<double, double> PointwiseAxisItem::range() const -{ - auto data = binCenters(); - return binCenters().empty() ? std::make_pair(default_axis_min, default_axis_max) - : std::make_pair(data.front(), data.back()); -} - -int PointwiseAxisItem::size() const -{ - return binCenters().size(); -} - -std::vector<double> PointwiseAxisItem::binCenters() const -{ - return data<std::vector<double>>(); -} diff --git a/mvvm/model/mvvm/standarditems/axisitems.h b/mvvm/model/mvvm/standarditems/axisitems.h deleted file mode 100644 index 3b65ca68a72776ebca695719972e402e42057a6b..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/standarditems/axisitems.h +++ /dev/null @@ -1,111 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/standarditems/axisitems.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_STANDARDITEMS_AXISITEMS_H -#define BORNAGAIN_MVVM_MODEL_MVVM_STANDARDITEMS_AXISITEMS_H - -//! @file mvvm/model/mvvm/standarditems/axisitems.h -//! Collection of axis items for 1D and 2D data/plotting support. - -#include "mvvm/model/compounditem.h" -#include <memory> -#include <vector> - -namespace ModelView { - -//! Base class for all axes items. Has min, max defined, but nothing else. - -class MVVM_MODEL_EXPORT BasicAxisItem : public CompoundItem { -public: - static inline const std::string P_MIN = "P_MIN"; - static inline const std::string P_MAX = "P_MAX"; - - explicit BasicAxisItem(const std::string& model_type); - -protected: - void register_min_max(); -}; - -//! Item to represent viewport axis. -//! Serves as a counterpart of QCPAxis from QCustomPlot. Intended to cary title, fonts etc. - -class MVVM_MODEL_EXPORT ViewportAxisItem : public BasicAxisItem { -public: - static inline const std::string P_TITLE = "P_TITLE"; - static inline const std::string P_IS_LOG = "P_IS_LOG"; - explicit ViewportAxisItem(const std::string& model_type = GUI::Constants::ViewportAxisItemType); - - std::pair<double, double> range() const; - - void set_range(double lower, double upper); - - bool is_in_log() const; -}; - -//! Item to represent an axis with arbitrary binning. -//! Base class to define an axis with specific binning (fixed, variable). Used in Data1DItem and -//! Data2Ditem to store 1d and 2d data. Doesn't carry any appearance info (e.g. axis title, label -//! size, etc) and thus not intended for direct plotting. - -class MVVM_MODEL_EXPORT BinnedAxisItem : public BasicAxisItem { -public: - explicit BinnedAxisItem(const std::string& model_type); - - virtual std::pair<double, double> range() const = 0; - - virtual int size() const = 0; - - virtual std::vector<double> binCenters() const = 0; -}; - -//! Item to represent fixed bin axis. -//! Defines an axis with equidistant binning. - -class MVVM_MODEL_EXPORT FixedBinAxisItem : public BinnedAxisItem { -public: - static inline const std::string P_NBINS = "P_NBINS"; - FixedBinAxisItem(const std::string& model_type = GUI::Constants::FixedBinAxisItemType); - - void setParameters(int nbins, double xmin, double xmax); - - static std::unique_ptr<FixedBinAxisItem> create(int nbins, double xmin, double xmax); - - std::pair<double, double> range() const override; - - int size() const override; - - std::vector<double> binCenters() const override; -}; - -//! Item to represent pointwise axis. -//! Defines an axis via array of points representing point coordinates. - -class MVVM_MODEL_EXPORT PointwiseAxisItem : public BinnedAxisItem { -public: - PointwiseAxisItem(const std::string& model_type = GUI::Constants::PointwiseAxisItemType); - - void setParameters(const std::vector<double>& data); - - static std::unique_ptr<PointwiseAxisItem> create(const std::vector<double>& data); - - std::pair<double, double> range() const override; - - int size() const override; - - std::vector<double> binCenters() const override; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_STANDARDITEMS_AXISITEMS_H diff --git a/mvvm/model/mvvm/standarditems/colormapitem.cpp b/mvvm/model/mvvm/standarditems/colormapitem.cpp deleted file mode 100644 index 583fd6df12732de864be1830a6728e54eb281b19..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/standarditems/colormapitem.cpp +++ /dev/null @@ -1,50 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/standarditems/colormapitem.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/standarditems/colormapitem.h" -#include "mvvm/model/comboproperty.h" -#include "mvvm/standarditems/data2ditem.h" -#include "mvvm/standarditems/linkeditem.h" -#include "mvvm/standarditems/plottableitems.h" - -using namespace ModelView; - -namespace { -const ComboProperty gradientCombo = - ComboProperty::createFrom({"Grayscale", "Hot", "Cold", "Night", "Candy", "Geography", "Ion", - "Thermal", "Polar", "Spectrum", "Jet", "Hues"}, - "Polar"); -} - -ColorMapItem::ColorMapItem() : CompoundItem(GUI::Constants::ColorMapItemType) -{ - addProperty<LinkedItem>(P_LINK)->setDisplayName("Link"); - addProperty<TextItem>(P_TITLE)->setDisplayName("Title"); - addProperty(P_GRADIENT, gradientCombo)->setDisplayName("Gradient"); - addProperty(P_INTERPOLATION, true)->setDisplayName("Interpolation"); -} - -//! Sets link to the data item. - -void ColorMapItem::setDataItem(const Data2DItem* data_item) -{ - item<LinkedItem>(P_LINK)->setLink(data_item); -} - -//! Returns data item linked to the given ColorMapItem. - -Data2DItem* ColorMapItem::dataItem() const -{ - return item<LinkedItem>(P_LINK)->get<Data2DItem>(); -} diff --git a/mvvm/model/mvvm/standarditems/colormapitem.h b/mvvm/model/mvvm/standarditems/colormapitem.h deleted file mode 100644 index 2fd8c8f87a0a3da99fc693f6509f1ea5e506a4c4..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/standarditems/colormapitem.h +++ /dev/null @@ -1,44 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/standarditems/colormapitem.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_STANDARDITEMS_COLORMAPITEM_H -#define BORNAGAIN_MVVM_MODEL_MVVM_STANDARDITEMS_COLORMAPITEM_H - -#include "mvvm/model/compounditem.h" - -namespace ModelView { - -class Data2DItem; - -//! Two-dimensional color map representation of Data2DItem. -//! Contains plot properties (i.e. color, gradient etc) and link to Data2DItem, which will provide -//! actual data to plot. ColorMapItem is intended for plotting only via ColorMapViewportItem. - -class MVVM_MODEL_EXPORT ColorMapItem : public CompoundItem { -public: - static inline const std::string P_LINK = "P_LINK"; - static inline const std::string P_TITLE = "P_TITLE"; - static inline const std::string P_GRADIENT = "P_GRADIENT"; - static inline const std::string P_INTERPOLATION = "P_INTERPOLATION"; - - ColorMapItem(); - - void setDataItem(const Data2DItem* item); - - Data2DItem* dataItem() const; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_STANDARDITEMS_COLORMAPITEM_H diff --git a/mvvm/model/mvvm/standarditems/colormapviewportitem.cpp b/mvvm/model/mvvm/standarditems/colormapviewportitem.cpp deleted file mode 100644 index 05b0abc0759af7d4d3a3924e65d499e8bfc25c74..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/standarditems/colormapviewportitem.cpp +++ /dev/null @@ -1,81 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/standarditems/colormapviewportitem.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/standarditems/colormapviewportitem.h" -#include "mvvm/standarditems/axisitems.h" -#include "mvvm/standarditems/colormapitem.h" -#include "mvvm/standarditems/data2ditem.h" -#include <algorithm> -#include <vector> - -namespace { -const std::pair<double, double> default_axis_range{0.0, 1.0}; -} - -using namespace ModelView; - -ColorMapViewportItem::ColorMapViewportItem() - : ViewportItem(GUI::Constants::ColorMapViewportItemType) -{ - register_xy_axes(); - addProperty<ViewportAxisItem>(P_ZAXIS)->setDisplayName("color-axis"); - // for the moment allow only one ColorMapItem - registerTag(TagInfo(T_ITEMS, 0, 1, {GUI::Constants::ColorMapItemType}), /*set_default*/ true); -} - -ViewportAxisItem* ColorMapViewportItem::zAxis() const -{ - return item<ViewportAxisItem>(P_ZAXIS); -} - -void ColorMapViewportItem::setViewportToContent() -{ - ViewportItem::setViewportToContent(); - update_data_range(); -} - -//! Returns range of x-axis as defined in underlying Data2DItem. - -std::pair<double, double> ColorMapViewportItem::data_xaxis_range() const -{ - auto dataItem = data_item(); - return dataItem && dataItem->xAxis() ? dataItem->xAxis()->range() : default_axis_range; -} - -//! Returns range of y-axis as defined in underlying Data2DItem. - -std::pair<double, double> ColorMapViewportItem::data_yaxis_range() const -{ - auto dataItem = data_item(); - return dataItem && dataItem->yAxis() ? dataItem->yAxis()->range() : default_axis_range; -} - -//! Returns Data2DItem if exists. - -Data2DItem* ColorMapViewportItem::data_item() const -{ - auto colormap_item = item<ColorMapItem>(T_ITEMS); - return colormap_item ? colormap_item->dataItem() : nullptr; -} - -//! Updates zAxis to lower, upper values over all data points. - -void ColorMapViewportItem::update_data_range() -{ - if (auto dataItem = data_item(); dataItem) { - auto values = dataItem->content(); - auto [lower, upper] = std::minmax_element(std::begin(values), std::end(values)); - zAxis()->set_range(*lower, *upper); - } -} diff --git a/mvvm/model/mvvm/standarditems/colormapviewportitem.h b/mvvm/model/mvvm/standarditems/colormapviewportitem.h deleted file mode 100644 index c99af201f816b803d598cf84becc9bbeaf924860..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/standarditems/colormapviewportitem.h +++ /dev/null @@ -1,48 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/standarditems/colormapviewportitem.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_STANDARDITEMS_COLORMAPVIEWPORTITEM_H -#define BORNAGAIN_MVVM_MODEL_MVVM_STANDARDITEMS_COLORMAPVIEWPORTITEM_H - -#include "mvvm/standarditems/viewportitem.h" - -namespace ModelView { - -class Data2DItem; - -//! Container with viewport and collection of ColorMapItem's to plot. - -class MVVM_MODEL_EXPORT ColorMapViewportItem : public ViewportItem { -public: - static inline const std::string P_ZAXIS = "P_ZAXIS"; - - ColorMapViewportItem(); - - ViewportAxisItem* zAxis() const; - - using ViewportItem::setViewportToContent; - void setViewportToContent() override; - -protected: - virtual std::pair<double, double> data_xaxis_range() const override; - virtual std::pair<double, double> data_yaxis_range() const override; - -private: - Data2DItem* data_item() const; - void update_data_range(); -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_STANDARDITEMS_COLORMAPVIEWPORTITEM_H diff --git a/mvvm/model/mvvm/standarditems/containeritem.cpp b/mvvm/model/mvvm/standarditems/containeritem.cpp deleted file mode 100644 index d8656f735c30506d0e8fe81a3052cd5d7a642160..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/standarditems/containeritem.cpp +++ /dev/null @@ -1,32 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/standarditems/containeritem.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/standarditems/containeritem.h" - -using namespace ModelView; - -ContainerItem::ContainerItem(const std::string& modelType) : CompoundItem(modelType) -{ - registerTag(ModelView::TagInfo::universalTag(T_ITEMS), /*set_as_default*/ true); -} - -bool ContainerItem::empty() const -{ - return childrenCount() == 0; -} - -size_t ContainerItem::size() const -{ - return static_cast<size_t>(childrenCount()); -} diff --git a/mvvm/model/mvvm/standarditems/containeritem.h b/mvvm/model/mvvm/standarditems/containeritem.h deleted file mode 100644 index 7efae8f79e79a4d3381f4f8a73ad6fe27bca6c32..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/standarditems/containeritem.h +++ /dev/null @@ -1,38 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/standarditems/containeritem.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_STANDARDITEMS_CONTAINERITEM_H -#define BORNAGAIN_MVVM_MODEL_MVVM_STANDARDITEMS_CONTAINERITEM_H - -#include "mvvm/model/compounditem.h" - -namespace ModelView { - -//! Simple container to store any type of children. -//! Used as convenience item to create branch with uniform children beneath. - -class MVVM_MODEL_EXPORT ContainerItem : public CompoundItem { -public: - static inline const std::string T_ITEMS = "T_ITEMS"; - - ContainerItem(const std::string& modelType = GUI::Constants::ContainerItemType); - - bool empty() const; - - size_t size() const; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_STANDARDITEMS_CONTAINERITEM_H diff --git a/mvvm/model/mvvm/standarditems/data1ditem.cpp b/mvvm/model/mvvm/standarditems/data1ditem.cpp deleted file mode 100644 index c89372dff25f487880bb5b8135d1762cd671b00a..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/standarditems/data1ditem.cpp +++ /dev/null @@ -1,97 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/standarditems/data1ditem.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/standarditems/data1ditem.h" -#include "mvvm/standarditems/axisitems.h" -#include <stdexcept> - -using namespace ModelView; - -namespace { -size_t total_bin_count(Data1DItem* item) -{ - auto axis = item->item<BinnedAxisItem>(Data1DItem::T_AXIS); - return axis ? static_cast<size_t>(axis->size()) : 0; -} -} // namespace - -Data1DItem::Data1DItem() : CompoundItem(GUI::Constants::Data1DItemType) -{ - // prevent editing in widgets, since there is no corresponding editor - addProperty(P_VALUES, std::vector<double>())->setDisplayName("Values")->setEditable(false); - - addProperty(P_ERRORS, std::vector<double>())->setDisplayName("Errors")->setEditable(false); - - registerTag( - TagInfo(T_AXIS, 0, 1, - {GUI::Constants::FixedBinAxisItemType, GUI::Constants::PointwiseAxisItemType}), - true); - setValues(std::vector<double>()); -} - -//! Sets axis. Bin content will be set to zero. - -// void Data1DItem::setAxis(std::unique_ptr<BinnedAxisItem> axis) -//{ -// // we disable possibility to re-create axis to facilitate undo/redo - -// if (getItem(T_AXIS, 0)) -// throw std::runtime_error("Axis was already set. Currently we do not support axis change"); - -// insertItem(axis.release(), {T_AXIS, 0}); -// setValues(std::vector<double>(total_bin_count(this), 0.0)); -//} - -//! Returns coordinates of bin centers. - -std::vector<double> Data1DItem::binCenters() const -{ - auto axis = item<BinnedAxisItem>(T_AXIS); - return axis ? axis->binCenters() : std::vector<double>{}; -} - -//! Sets internal data buffer to given data. If size of axis doesn't match the size of the data, -//! exception will be thrown. - -void Data1DItem::setValues(const std::vector<double>& data) -{ - if (total_bin_count(this) != data.size()) - throw std::runtime_error("Data1DItem::setValues() -> Data doesn't match size of axis"); - - setProperty(P_VALUES, data); -} - -//! Returns values stored in bins. - -std::vector<double> Data1DItem::binValues() const -{ - return property<std::vector<double>>(P_VALUES); -} - -//! Sets errors on values in bins. - -void Data1DItem::setErrors(const std::vector<double>& errors) -{ - if (total_bin_count(this) != errors.size()) - throw std::runtime_error("Data1DItem::setErrors() -> Data doesn't match size of axis"); - - setProperty(P_ERRORS, errors); -} - -//! Returns value errors stored in bins. - -std::vector<double> Data1DItem::binErrors() const -{ - return property<std::vector<double>>(P_ERRORS); -} diff --git a/mvvm/model/mvvm/standarditems/data1ditem.h b/mvvm/model/mvvm/standarditems/data1ditem.h deleted file mode 100644 index f18821a7dce632d0710000f0f9d6f62f8221c360..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/standarditems/data1ditem.h +++ /dev/null @@ -1,77 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/standarditems/data1ditem.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_STANDARDITEMS_DATA1DITEM_H -#define BORNAGAIN_MVVM_MODEL_MVVM_STANDARDITEMS_DATA1DITEM_H - -#include "mvvm/model/compounditem.h" -#include "mvvm/model/sessionmodel.h" -#include <vector> - -namespace ModelView { - -class BinnedAxisItem; - -//! Represents one-dimensional data (axis and values). -//! Values are stored in Data1DItem itself, axis is attached as a child. Corresponding plot -//! properties will be served by GraphItem. - -class MVVM_MODEL_EXPORT Data1DItem : public CompoundItem { -public: - static inline const std::string P_VALUES = "P_VALUES"; - static inline const std::string P_ERRORS = "P_ERRORS"; - static inline const std::string T_AXIS = "T_AXIS"; - - Data1DItem(); - - // void setAxis(std::unique_ptr<BinnedAxisItem> axis); - - std::vector<double> binCenters() const; - - void setValues(const std::vector<double>& data); - std::vector<double> binValues() const; - - void setErrors(const std::vector<double>& errors); - std::vector<double> binErrors() const; - - //! Inserts axis of given type. - template <typename T, typename... Args> T* setAxis(Args&&... args); -}; - -// FIXME Consider redesign of the method below. Should the axis exist from the beginning -// or added later? It is not clear how to create axis a) via Data1DItem::setAxis -// b) via model directly c) in constructor? - -template <typename T, typename... Args> T* Data1DItem::setAxis(Args&&... args) -{ - // we disable possibility to re-create axis to facilitate undo/redo - if (getItem(T_AXIS, 0)) - throw std::runtime_error("Axis was already set. Currently we do not support axis change"); - - T* result{nullptr}; - if (model()) { - // acting through the model to enable undo/redo - result = model()->insertItem<T>(this); - } else { - result = new T; - insertItem(result, {T_AXIS, 0}); - } - result->setParameters(std::forward<Args>(args)...); - setValues(std::vector<double>(result->size(), 0.0)); - return result; -} - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_STANDARDITEMS_DATA1DITEM_H diff --git a/mvvm/model/mvvm/standarditems/data2ditem.cpp b/mvvm/model/mvvm/standarditems/data2ditem.cpp deleted file mode 100644 index e9b5e2e9db0ca537280404bf0f05be40f79a3109..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/standarditems/data2ditem.cpp +++ /dev/null @@ -1,87 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/standarditems/data2ditem.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/standarditems/data2ditem.h" -#include "mvvm/standarditems/axisitems.h" -#include <stdexcept> - -using namespace ModelView; - -namespace { -size_t total_bin_count(Data2DItem* item) -{ - if (auto xaxis = item->xAxis(); xaxis) - if (auto yaxis = item->yAxis(); yaxis) - return static_cast<size_t>(xaxis->size() * yaxis->size()); - return 0; -} -} // namespace - -Data2DItem::Data2DItem() : CompoundItem(GUI::Constants::Data2DItemType) -{ - registerTag(TagInfo(T_XAXIS, 0, 1, {GUI::Constants::FixedBinAxisItemType})); - registerTag(TagInfo(T_YAXIS, 0, 1, {GUI::Constants::FixedBinAxisItemType})); - setContent(std::vector<double>()); // prevent editing in widgets, since there is no - // corresponding editor -} - -//! Sets axes and put data points to zero. - -void Data2DItem::setAxes(std::unique_ptr<BinnedAxisItem> x_axis, - std::unique_ptr<BinnedAxisItem> y_axis) -{ - insert_axis(std::move(x_axis), T_XAXIS); - insert_axis(std::move(y_axis), T_YAXIS); - setContent(std::vector<double>(total_bin_count(this), 0.0)); -} - -//! Returns x-axis (nullptr if it doesn't exist). - -BinnedAxisItem* Data2DItem::xAxis() const -{ - return item<BinnedAxisItem>(T_XAXIS); -} - -//! Returns y-axis (nullptr if it doesn't exist). - -BinnedAxisItem* Data2DItem::yAxis() const -{ - return item<BinnedAxisItem>(T_YAXIS); -} - -void Data2DItem::setContent(const std::vector<double>& data) -{ - if (total_bin_count(this) != data.size()) - throw std::runtime_error("Data1DItem::setContent() -> Data doesn't match size of axis"); - - setData(data); -} - -//! Returns 2d vector representing 2d data. - -std::vector<double> Data2DItem::content() const -{ - return data<std::vector<double>>(); -} - -//! Insert axis under given tag. Previous axis will be deleted and data points invalidated. - -void Data2DItem::insert_axis(std::unique_ptr<BinnedAxisItem> axis, const std::string& tag) -{ - // removing current axis - if (getItem(tag, 0)) - delete takeItem({tag, 0}); - - insertItem(axis.release(), {tag, 0}); -} diff --git a/mvvm/model/mvvm/standarditems/data2ditem.h b/mvvm/model/mvvm/standarditems/data2ditem.h deleted file mode 100644 index 749c67ea2e66035c1b84ee6066c84f596f6936c9..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/standarditems/data2ditem.h +++ /dev/null @@ -1,52 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/standarditems/data2ditem.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_STANDARDITEMS_DATA2DITEM_H -#define BORNAGAIN_MVVM_MODEL_MVVM_STANDARDITEMS_DATA2DITEM_H - -#include "mvvm/model/compounditem.h" -#include <vector> - -namespace ModelView { - -class BinnedAxisItem; - -//! Represents two-dimensional data (axes definition and 2d array of values). -//! Values are stored in Data2DItem itself, axes are attached as children. Corresponding plot -//! properties will be served by ColorMapItem. - -class MVVM_MODEL_EXPORT Data2DItem : public CompoundItem { -public: - static inline const std::string T_XAXIS = "T_XAXIS"; - static inline const std::string T_YAXIS = "T_YAXIS"; - - Data2DItem(); - - void setAxes(std::unique_ptr<BinnedAxisItem> x_axis, std::unique_ptr<BinnedAxisItem> y_axis); - - BinnedAxisItem* xAxis() const; - - BinnedAxisItem* yAxis() const; - - void setContent(const std::vector<double>& data); - - std::vector<double> content() const; - -private: - void insert_axis(std::unique_ptr<BinnedAxisItem> axis, const std::string& tag); -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_STANDARDITEMS_DATA2DITEM_H diff --git a/mvvm/model/mvvm/standarditems/graphitem.cpp b/mvvm/model/mvvm/standarditems/graphitem.cpp deleted file mode 100644 index bfaeea57a22bd966907b2d7e811f351d773dfb1f..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/standarditems/graphitem.cpp +++ /dev/null @@ -1,92 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/standarditems/graphitem.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/standarditems/graphitem.h" -#include "mvvm/model/comboproperty.h" -#include "mvvm/standarditems/data1ditem.h" -#include "mvvm/standarditems/linkeditem.h" -#include "mvvm/standarditems/plottableitems.h" -#include <QColor> - -using namespace ModelView; - -GraphItem::GraphItem(const std::string& model_type) : CompoundItem(model_type) -{ - addProperty<LinkedItem>(P_LINK)->setDisplayName("Link"); - addProperty<TextItem>(P_GRAPH_TITLE)->setDisplayName("Graph title"); - addProperty<PenItem>(P_PEN)->setDisplayName("Pen"); - addProperty(P_DISPLAYED, true)->setDisplayName("Displayed"); -} - -//! Sets link to the data item. - -void GraphItem::setDataItem(const Data1DItem* data_item) -{ - item<LinkedItem>(P_LINK)->setLink(data_item); -} - -//! Update item from the content of given graph. Link to the data will be set -//! as in given item, other properties copied. - -void GraphItem::setFromGraphItem(const GraphItem* graph_item) -{ - setDataItem(graph_item->dataItem()); - auto pen = item<PenItem>(P_PEN); - auto source_pen = graph_item->item<PenItem>(P_PEN); - pen->setProperty(PenItem::P_COLOR, source_pen->property<QColor>(PenItem::P_COLOR)); - pen->setProperty(PenItem::P_STYLE, source_pen->property<ComboProperty>(PenItem::P_STYLE)); - pen->setProperty(PenItem::P_WIDTH, source_pen->property<int>(PenItem::P_WIDTH)); -} - -//! Returns data item linked to the given GraphItem. - -Data1DItem* GraphItem::dataItem() const -{ - return item<LinkedItem>(P_LINK)->get<Data1DItem>(); -} - -std::vector<double> GraphItem::binCenters() const -{ - return dataItem() ? dataItem()->binCenters() : std::vector<double>(); -} - -std::vector<double> GraphItem::binValues() const -{ - return dataItem() ? dataItem()->binValues() : std::vector<double>(); -} - -std::vector<double> GraphItem::binErrors() const -{ - return dataItem() ? dataItem()->binErrors() : std::vector<double>(); -} - -//! Returns color name in #RRGGBB format. - -std::string GraphItem::colorName() const -{ - return penItem()->colorName(); -} - -//! Sets named color following schema from https://www.w3.org/TR/css-color-3/#svg-color. -//! e.g. "mediumaquamarine" - -void GraphItem::setNamedColor(const std::string& named_color) -{ - penItem()->setNamedColor(named_color); -} - -PenItem* GraphItem::penItem() const -{ - return item<PenItem>(P_PEN); -} diff --git a/mvvm/model/mvvm/standarditems/graphitem.h b/mvvm/model/mvvm/standarditems/graphitem.h deleted file mode 100644 index bf53941782edde056a2529aa66fddb267c3cd764..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/standarditems/graphitem.h +++ /dev/null @@ -1,58 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/standarditems/graphitem.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_STANDARDITEMS_GRAPHITEM_H -#define BORNAGAIN_MVVM_MODEL_MVVM_STANDARDITEMS_GRAPHITEM_H - -#include "mvvm/model/compounditem.h" - -namespace ModelView { - -class Data1DItem; -class PenItem; - -//! One-dimensional graph representation of Data1DItem. -//! Contains plot properties (i.e. color, line type etc) and link to Data1DItem, which will provide -//! actual data to plot. GraphItem is intended for plotting only via GraphViewportItem. - -class MVVM_MODEL_EXPORT GraphItem : public CompoundItem { -public: - static inline const std::string P_LINK = "P_LINK"; - static inline const std::string P_GRAPH_TITLE = "P_GRAPH_TITLE"; - static inline const std::string P_PEN = "P_PEN"; - static inline const std::string P_DISPLAYED = "P_DISPLAYED"; - - GraphItem(const std::string& model_type = GUI::Constants::GraphItemType); - - void setDataItem(const Data1DItem* item); - - void setFromGraphItem(const GraphItem* graph_item); - - Data1DItem* dataItem() const; - - std::vector<double> binCenters() const; - - std::vector<double> binValues() const; - - std::vector<double> binErrors() const; - - std::string colorName() const; - void setNamedColor(const std::string& named_color); - - PenItem* penItem() const; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_STANDARDITEMS_GRAPHITEM_H diff --git a/mvvm/model/mvvm/standarditems/graphviewportitem.cpp b/mvvm/model/mvvm/standarditems/graphviewportitem.cpp deleted file mode 100644 index 515d4d51d657e91d13463b50aad9ac7651204799..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/standarditems/graphviewportitem.cpp +++ /dev/null @@ -1,105 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/standarditems/graphviewportitem.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/standarditems/graphviewportitem.h" -#include "mvvm/standarditems/graphitem.h" -#include <algorithm> -#include <vector> - -using namespace ModelView; - -namespace { - -const double failback_min = 0.0; -const double failback_max = 1.0; - -//! Find min and max values along all data points in all graphs. -//! Function 'func' is used to run either through binCenters or binValues. - -template <typename T> auto get_min_max(const std::vector<GraphItem*>& graphs, T func) -{ - std::vector<double> values; - for (auto graph : graphs) { - const auto array = func(graph); - std::copy(std::begin(array), std::end(array), std::back_inserter(values)); - } - - auto [xmin, xmax] = std::minmax_element(std::begin(values), std::end(values)); - return xmin != xmax ? std::make_pair(*xmin, *xmax) : std::make_pair(failback_min, failback_max); -} - -} // namespace - -GraphViewportItem::GraphViewportItem(const std::string& model_type) : ViewportItem(model_type) -{ - register_xy_axes(); - registerTag(TagInfo::universalTag(T_ITEMS, {GUI::Constants::GraphItemType}), - /*set_default*/ true); -} - -//! Returns the selected graph items. - -std::vector<GraphItem*> GraphViewportItem::graphItems() const -{ - return items<GraphItem>(T_ITEMS); -} - -//! Returns the selected graph items. - -std::vector<GraphItem*> GraphViewportItem::visibleGraphItems() const -{ - std::vector<GraphItem*> all_items = items<GraphItem>(T_ITEMS); - std::vector<GraphItem*> visible_items; - std::copy_if(all_items.begin(), all_items.end(), std::back_inserter(visible_items), - [](const GraphItem* graph_item) { - return graph_item->property<bool>(GraphItem::P_DISPLAYED); - }); - return visible_items; -} - -//! Set the graph selection. - -void GraphViewportItem::setVisible(const std::vector<GraphItem*>& visible_graph_items) -{ - std::vector<GraphItem*> output; - for (auto graph_item : items<GraphItem>(T_ITEMS)) { - if (std::find(visible_graph_items.begin(), visible_graph_items.end(), graph_item) - != visible_graph_items.end()) - graph_item->setProperty(GraphItem::P_DISPLAYED, true); - else - graph_item->setProperty(GraphItem::P_DISPLAYED, false); - } -} - -//! Reset the graph selection. - -void GraphViewportItem::setAllVisible() -{ - for (auto graph_item : items<GraphItem>(T_ITEMS)) - graph_item->setProperty(GraphItem::P_DISPLAYED, true); -} - -//! Returns lower, upper range on x-axis occupied by all data points of all graphs. - -std::pair<double, double> GraphViewportItem::data_xaxis_range() const -{ - return get_min_max(visibleGraphItems(), [](GraphItem* graph) { return graph->binCenters(); }); -} - -//! Returns lower, upper range on y-axis occupied by all data points of all graphs. - -std::pair<double, double> GraphViewportItem::data_yaxis_range() const -{ - return get_min_max(visibleGraphItems(), [](GraphItem* graph) { return graph->binValues(); }); -} diff --git a/mvvm/model/mvvm/standarditems/graphviewportitem.h b/mvvm/model/mvvm/standarditems/graphviewportitem.h deleted file mode 100644 index a331f74b53b305f84b53dae6a4caff9afb0045f2..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/standarditems/graphviewportitem.h +++ /dev/null @@ -1,47 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/standarditems/graphviewportitem.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_STANDARDITEMS_GRAPHVIEWPORTITEM_H -#define BORNAGAIN_MVVM_MODEL_MVVM_STANDARDITEMS_GRAPHVIEWPORTITEM_H - -#include "mvvm/standarditems/viewportitem.h" - -namespace ModelView { - -class GraphItem; - -//! 2D viewport specialized for showing multiple GraphItem's. -//! Provides calculation of viewport's x-axis and y-axis range basing on GraphItem data. -//! Provides functionality to hide selected graphs. - -class MVVM_MODEL_EXPORT GraphViewportItem : public ViewportItem { -public: - GraphViewportItem(const std::string& model_type = GUI::Constants::GraphViewportItemType); - - std::vector<GraphItem*> graphItems() const; - - std::vector<GraphItem*> visibleGraphItems() const; - - void setVisible(const std::vector<GraphItem*>& visible_graph_items); - - void setAllVisible(); - -protected: - std::pair<double, double> data_xaxis_range() const override; - std::pair<double, double> data_yaxis_range() const override; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_STANDARDITEMS_GRAPHVIEWPORTITEM_H diff --git a/mvvm/model/mvvm/standarditems/linkeditem.cpp b/mvvm/model/mvvm/standarditems/linkeditem.cpp deleted file mode 100644 index 2d9e2b4379eb5ae7e4cfc1767884ba639463f1a5..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/standarditems/linkeditem.cpp +++ /dev/null @@ -1,35 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/standarditems/linkeditem.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/standarditems/linkeditem.h" -#include "mvvm/model/customvariants.h" - -using namespace ModelView; - -namespace { -const Variant empty_link = Variant::fromValue(""); -} - -LinkedItem::LinkedItem() : SessionItem(GUI::Constants::LinkedItemType) -{ - setData(empty_link); - setEditable(false); // prevent editing in widgets, link is set programmatically. -} - -//! Set link to given item. - -void LinkedItem::setLink(const SessionItem* item) -{ - setData(item ? Variant::fromValue(item->identifier()) : empty_link); -} diff --git a/mvvm/model/mvvm/standarditems/linkeditem.h b/mvvm/model/mvvm/standarditems/linkeditem.h deleted file mode 100644 index 47000f4c2c87e4d896e11605e6961228422a74f0..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/standarditems/linkeditem.h +++ /dev/null @@ -1,48 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/standarditems/linkeditem.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_STANDARDITEMS_LINKEDITEM_H -#define BORNAGAIN_MVVM_MODEL_MVVM_STANDARDITEMS_LINKEDITEM_H - -#include "mvvm/model/sessionitem.h" -#include "mvvm/model/sessionmodel.h" - -namespace ModelView { - -//! Item to store a persistent link to other arbitrary items. - -//! The identifier of the item intended for linking is stored as DataRole on board of LinkedItem -//! and can be used to find the corresponding item via SessionModel::findItem machinery. -//! Provided mechanism is persistent and outlive serialization. Can be used to find items in -//! different models. For that being the case, models should use same ItemPool. - -class MVVM_MODEL_EXPORT LinkedItem : public SessionItem { -public: - LinkedItem(); - - void setLink(const SessionItem* item); - - template <typename T = SessionItem> T* get() const; -}; - -//! Returns item linked to given item. Works only in model context. - -template <typename T> T* LinkedItem::get() const -{ - return model() ? dynamic_cast<T*>(model()->findItem(data<std::string>())) : nullptr; -} - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_STANDARDITEMS_LINKEDITEM_H diff --git a/mvvm/model/mvvm/standarditems/plottableitems.cpp b/mvvm/model/mvvm/standarditems/plottableitems.cpp deleted file mode 100644 index 6a7315d8e80b5041823f8bddee0a598c627d615c..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/standarditems/plottableitems.cpp +++ /dev/null @@ -1,78 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/standarditems/plottableitems.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/standarditems/plottableitems.h" -#include "mvvm/model/comboproperty.h" -#include <QColor> - -using namespace ModelView; - -namespace { -//! Following Qt styles. -const ComboProperty penStyleCombo = ComboProperty::createFrom( - {"NoPen", "SolidLine", "DashLine", "DotLine", "DashDotLine", "DashDotDotLine"}, "SolidLine"); -const int pen_default_width = 1; -const int pen_min_width = 0; -const int pen_max_width = 7; -const int penstyle_index_solid = 1; -const int penstyle_index_dashline = 2; - -// We do not want to depend from widgetutils.h to get App default font size. Let's stick to -// hardcoded value for the moment, even if on different systems it can be not-optimal. -const int default_title_size = 10; -const std::string default_title_family = "Noto Sans"; -} // namespace - -TextItem::TextItem() : CompoundItem(GUI::Constants::TextItemType) -{ - addProperty(P_TEXT, QString())->setDisplayName("Text"); - addProperty(P_FONT, default_title_family)->setDisplayName("Font"); - addProperty(P_SIZE, default_title_size)->setDisplayName("Size"); -} - -PenItem::PenItem() : CompoundItem(GUI::Constants::PenItemType) -{ - addProperty(P_COLOR, QColor(Qt::black))->setDisplayName("Color")->setToolTip("Pen color"); - addProperty(P_STYLE, penStyleCombo)->setDisplayName("Style")->setToolTip("Pen style"); - addProperty(P_WIDTH, pen_default_width) - ->setDisplayName("Width") - ->setLimits(RealLimits::limited(pen_min_width, pen_max_width)) - ->setToolTip("Pen width"); -} - -//! Sets style of the pen to represent selected object (dash line). - -void PenItem::setSelected(bool is_selected) -{ - auto combo = penStyleCombo; - combo.setCurrentIndex(is_selected ? penstyle_index_dashline : penstyle_index_solid); - setProperty(P_STYLE, combo); -} - -//! Returns color name in #RRGGBB format. -//! We do not want to expose QColor itself since it will be eventually removed. - -std::string PenItem::colorName() const -{ - return property<QColor>(P_COLOR).name().toStdString(); -} - -//! Sets named color following schema from https://www.w3.org/TR/css-color-3/#svg-color. -//! e.g. "mediumaquamarine" -//! We do not want to expose QColor itself since it will be eventually removed. - -void PenItem::setNamedColor(const std::string& named_color) -{ - setProperty(P_COLOR, QColor(QString::fromStdString(named_color))); -} diff --git a/mvvm/model/mvvm/standarditems/plottableitems.h b/mvvm/model/mvvm/standarditems/plottableitems.h deleted file mode 100644 index 5673cddd90491256240129590e020f0258d84dfe..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/standarditems/plottableitems.h +++ /dev/null @@ -1,54 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/standarditems/plottableitems.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_STANDARDITEMS_PLOTTABLEITEMS_H -#define BORNAGAIN_MVVM_MODEL_MVVM_STANDARDITEMS_PLOTTABLEITEMS_H - -//! @file mvvm/model/mvvm/standarditems/plottableitems.h -//! Collection of items to plot in QCustomPlot context. - -#include "mvvm/model/compounditem.h" - -namespace ModelView { - -//! Represent text item on plot. - -class MVVM_MODEL_EXPORT TextItem : public CompoundItem { -public: - static inline const std::string P_TEXT = "P_TEXT"; - static inline const std::string P_FONT = "P_FONT"; - static inline const std::string P_SIZE = "P_SIZE"; - - TextItem(); -}; - -//! Represents basics settings of QPen. - -class MVVM_MODEL_EXPORT PenItem : public CompoundItem { -public: - static inline const std::string P_COLOR = "P_COLOR"; - static inline const std::string P_STYLE = "P_STYLE"; - static inline const std::string P_WIDTH = "P_WIDTH"; - - PenItem(); - - void setSelected(bool is_selected); - - std::string colorName() const; - void setNamedColor(const std::string& named_color); -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_STANDARDITEMS_PLOTTABLEITEMS_H diff --git a/mvvm/model/mvvm/standarditems/standarditemincludes.h b/mvvm/model/mvvm/standarditems/standarditemincludes.h deleted file mode 100644 index cc7c39424a1f3334287dfc0e369d9e74206b4198..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/standarditems/standarditemincludes.h +++ /dev/null @@ -1,35 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/standarditems/standarditemincludes.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_STANDARDITEMS_STANDARDITEMINCLUDES_H -#define BORNAGAIN_MVVM_MODEL_MVVM_STANDARDITEMS_STANDARDITEMINCLUDES_H - -//! @file mvvm/model/mvvm/standarditems/standarditemincludes.h -//! Collection of all includes with items supported by the model out-of-the-box. - -#include "mvvm/model/compounditem.h" -#include "mvvm/model/propertyitem.h" -#include "mvvm/standarditems/axisitems.h" -#include "mvvm/standarditems/colormapitem.h" -#include "mvvm/standarditems/colormapviewportitem.h" -#include "mvvm/standarditems/containeritem.h" -#include "mvvm/standarditems/data1ditem.h" -#include "mvvm/standarditems/data2ditem.h" -#include "mvvm/standarditems/graphitem.h" -#include "mvvm/standarditems/graphviewportitem.h" -#include "mvvm/standarditems/linkeditem.h" -#include "mvvm/standarditems/plottableitems.h" -#include "mvvm/standarditems/vectoritem.h" - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_STANDARDITEMS_STANDARDITEMINCLUDES_H diff --git a/mvvm/model/mvvm/standarditems/vectoritem.cpp b/mvvm/model/mvvm/standarditems/vectoritem.cpp deleted file mode 100644 index 6127e5732da4ee2ab5f49fb59fc3866e276ebcf2..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/standarditems/vectoritem.cpp +++ /dev/null @@ -1,45 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/standarditems/vectoritem.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/standarditems/vectoritem.h" -#include "mvvm/model/customvariants.h" -#include "mvvm/signals/itemmapper.h" -#include <sstream> - -using namespace ModelView; - -VectorItem::VectorItem() : CompoundItem(GUI::Constants::VectorItemType) -{ - addProperty(P_X, 0.0)->setDisplayName("X"); - addProperty(P_Y, 0.0)->setDisplayName("Y"); - addProperty(P_Z, 0.0)->setDisplayName("Z"); - - setEditable(false); - - update_label(); -} - -void VectorItem::activate() -{ - auto on_property_change = [this](SessionItem*, const std::string&) { update_label(); }; - mapper()->setOnPropertyChange(on_property_change, this); -} - -void VectorItem::update_label() -{ - std::ostringstream ostr; - ostr << "(" << property<double>(P_X) << ", " << property<double>(P_Y) << ", " - << property<double>(P_Z) << ")"; - setData(Variant::fromValue(ostr.str()), ItemDataRole::DATA, /*direct*/ true); -} diff --git a/mvvm/model/mvvm/standarditems/vectoritem.h b/mvvm/model/mvvm/standarditems/vectoritem.h deleted file mode 100644 index dd7aa8923b6d305c8a499e294890fc45e177f3b8..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/standarditems/vectoritem.h +++ /dev/null @@ -1,40 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/standarditems/vectoritem.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_STANDARDITEMS_VECTORITEM_H -#define BORNAGAIN_MVVM_MODEL_MVVM_STANDARDITEMS_VECTORITEM_H - -#include "mvvm/model/compounditem.h" - -namespace ModelView { - -//! Vector item with three x,y,z property items. - -class MVVM_MODEL_EXPORT VectorItem : public CompoundItem { -public: - static inline const std::string P_X = "P_X"; - static inline const std::string P_Y = "P_Y"; - static inline const std::string P_Z = "P_Z"; - - VectorItem(); - - void activate() override; - -private: - void update_label(); -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_STANDARDITEMS_VECTORITEM_H diff --git a/mvvm/model/mvvm/standarditems/viewportitem.cpp b/mvvm/model/mvvm/standarditems/viewportitem.cpp deleted file mode 100644 index 29d5e7cdddb9d26e967acee257deca0cfd7146a1..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/standarditems/viewportitem.cpp +++ /dev/null @@ -1,67 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/standarditems/viewportitem.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/standarditems/viewportitem.h" -#include "mvvm/model/modelutils.h" -#include "mvvm/standarditems/axisitems.h" - -using namespace ModelView; - -ViewportItem::ViewportItem(const ModelView::model_type& model) : CompoundItem(model) {} - -ViewportAxisItem* ViewportItem::xAxis() const -{ - return item<ViewportAxisItem>(P_XAXIS); -} - -ViewportAxisItem* ViewportItem::yAxis() const -{ - return item<ViewportAxisItem>(P_YAXIS); -} - -//! Sets range of x,y window to show all data. -//! Allows adding an additional margin to automatically calculated axis range. Margins are -//! given in relative units wrt calculated axis range. -//! Example: setViewportToContent(0.0, 0.1, 0.0, 0.1) will set axes to show all graphs with 10% gap -//! above and below graph's max and min. - -void ViewportItem::setViewportToContent(double left, double top, double right, double bottom) -{ - Utils::BeginMacros(this, "setViewportToContent"); - auto [xmin, xmax] = data_xaxis_range(); - xAxis()->set_range(xmin - (xmax - xmin) * left, xmax + (xmax - xmin) * right); - - auto [ymin, ymax] = data_yaxis_range(); - yAxis()->set_range(ymin - (ymax - ymin) * bottom, ymax + (ymax - ymin) * top); - Utils::EndMacros(this); -} - -//! Sets range of x,y window to show all data. - -void ViewportItem::setViewportToContent() -{ - Utils::BeginMacros(this, "setViewportToContent"); - auto [xmin, xmax] = data_xaxis_range(); - xAxis()->set_range(xmin, xmax); - - auto [ymin, ymax] = data_yaxis_range(); - yAxis()->set_range(ymin, ymax); - Utils::EndMacros(this); -} - -void ViewportItem::register_xy_axes() -{ - addProperty<ViewportAxisItem>(P_XAXIS)->setDisplayName("X axis"); - addProperty<ViewportAxisItem>(P_YAXIS)->setDisplayName("Y axis"); -} diff --git a/mvvm/model/mvvm/standarditems/viewportitem.h b/mvvm/model/mvvm/standarditems/viewportitem.h deleted file mode 100644 index d5c8e7b9b06a1adbc9ee9612e939663019a3942a..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/standarditems/viewportitem.h +++ /dev/null @@ -1,53 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/standarditems/viewportitem.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_STANDARDITEMS_VIEWPORTITEM_H -#define BORNAGAIN_MVVM_MODEL_MVVM_STANDARDITEMS_VIEWPORTITEM_H - -#include "mvvm/model/compounditem.h" - -namespace ModelView { - -class ViewportAxisItem; - -//! Base class to represent 2D viewport. -//! Contains x,y axis, indended to display graphs or 2d colormaps. - -class MVVM_MODEL_EXPORT ViewportItem : public CompoundItem { -public: - static inline const std::string P_XAXIS = "P_XAXIS"; - static inline const std::string P_YAXIS = "P_YAXIS"; - static inline const std::string T_ITEMS = "T_ITEMS"; - - ViewportItem(const model_type& model); - - ViewportAxisItem* xAxis() const; - - ViewportAxisItem* yAxis() const; - - virtual void setViewportToContent(double left, double top, double right, double bottom); - - virtual void setViewportToContent(); - -protected: - void register_xy_axes(); - -protected: - virtual std::pair<double, double> data_xaxis_range() const = 0; - virtual std::pair<double, double> data_yaxis_range() const = 0; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_STANDARDITEMS_VIEWPORTITEM_H diff --git a/mvvm/model/mvvm/utils/CMakeLists.txt b/mvvm/model/mvvm/utils/CMakeLists.txt deleted file mode 100644 index 1fa0a17ffdda01c7fa0a0fe227d4940affbc2a84..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/utils/CMakeLists.txt +++ /dev/null @@ -1,19 +0,0 @@ -target_sources(${library_name} PRIVATE - binutils.cpp - binutils.h - containerutils.cpp - containerutils.h - fileutils.cpp - fileutils.h - ifactory.h - mathconstants.h - numericutils.cpp - numericutils.h - progresshandler.cpp - progresshandler.h - reallimits.cpp - reallimits.h - stringutils.cpp - stringutils.h - threadsafestack.h -) diff --git a/mvvm/model/mvvm/utils/binutils.cpp b/mvvm/model/mvvm/utils/binutils.cpp deleted file mode 100644 index ab9e8c7bcc085499156f7a65b291d3f977d9c246..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/utils/binutils.cpp +++ /dev/null @@ -1,92 +0,0 @@ -#include "mvvm/utils/binutils.h" -#include <fstream> -#include <iostream> - -namespace { -//! Returns buffer size -int get_buffer_size(const std::string& filename); - -//! Returns part of file content in a buffer -void get_buffer_data(const std::string& filename, int* buffer, int buffer_size); - -//! Returns true if the interger is control character as defined above -bool is_control_char(int ch); - -//! Returns true if there is two null bytes in the buffer -bool null_check(int* buffer, int buffer_size); -} // namespace - -namespace ModelView ::Utils { - -// length of buffer -#define BYTE_LENGTH 2048 - -// null character -#define NULL_CHR (0x00) - -// control characters -#define NUL 0 -#define BS 8 -#define CR 13 -#define SUB 26 - -bool is_binary(const std::string& filename) -{ - int buffer[BYTE_LENGTH]; - - // get buffer size - int buffer_size = get_buffer_size(filename); - if (buffer_size == 0) - return false; - - // buffer allocation - get_buffer_data(filename, buffer, buffer_size); - - // control character check - for (int count = 0; count < buffer_size; ++count) - if (is_control_char(buffer[count])) - return true; - - return null_check(buffer, buffer_size); -} - -bool is_text(const std::string& filename) -{ - - return (!is_binary(filename)); -} - -} // namespace ModelView::Utils - -namespace { - -int get_buffer_size(const std::string& filename) -{ - std::ifstream mySource; - mySource.open(filename, std::ios_base::binary); - mySource.seekg(0, std::ios_base::end); - int size = mySource.tellg(); - mySource.close(); - return (size > BYTE_LENGTH) ? BYTE_LENGTH : size; -} - -void get_buffer_data(const std::string& filename, int* buffer, int byte_length) -{ - std::ifstream fstr(filename, std::ios::in | std::ios::binary); - for (int i = 0; i < byte_length; i++) - buffer[i] = fstr.get(); -} - -bool is_control_char(int ch) -{ - return ((ch > NUL && ch < BS) || (ch > CR && ch < SUB)); -} - -bool null_check(int* buffer, int buffer_size) -{ - for (int i = 1; i < buffer_size; ++i) - if (buffer[i] == NULL_CHR && buffer[i - 1] == NULL_CHR) - return true; - return false; -} -} // namespace diff --git a/mvvm/model/mvvm/utils/binutils.h b/mvvm/model/mvvm/utils/binutils.h deleted file mode 100644 index 99c4e322a1866eeb5ba4f99a2b90515e8c6a67d0..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/utils/binutils.h +++ /dev/null @@ -1,31 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/utils/binutils.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_UTILS_BINUTILS_H -#define BORNAGAIN_MVVM_MODEL_MVVM_UTILS_BINUTILS_H - -#include "mvvm/model_export.h" -#include <string> - -namespace ModelView ::Utils { - -//! Returns true if file is binary -MVVM_MODEL_EXPORT bool is_binary(const std::string& filename); - -//! Returns true if file is text/ascii -MVVM_MODEL_EXPORT bool is_text(const std::string& filename); - -} // namespace ModelView::Utils - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_UTILS_BINUTILS_H diff --git a/mvvm/model/mvvm/utils/containerutils.cpp b/mvvm/model/mvvm/utils/containerutils.cpp deleted file mode 100644 index fbe52dc6b52062b8d89b5265d0679d493a83f456..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/utils/containerutils.cpp +++ /dev/null @@ -1,15 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/utils/containerutils.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "containerutils.h" diff --git a/mvvm/model/mvvm/utils/containerutils.h b/mvvm/model/mvvm/utils/containerutils.h deleted file mode 100644 index ca456d61261ec66769a41ae6b005d27c809e5420..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/utils/containerutils.h +++ /dev/null @@ -1,108 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/utils/containerutils.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_UTILS_CONTAINERUTILS_H -#define BORNAGAIN_MVVM_MODEL_MVVM_UTILS_CONTAINERUTILS_H - -#include "mvvm/model_export.h" -#include <algorithm> -#include <complex> -#include <iterator> -#include <memory> -#include <string> -#include <type_traits> -#include <unordered_set> -#include <vector> - -namespace ModelView::Utils { - -template <class T> struct is_unique_ptr : std::false_type { -}; - -template <class T, class D> struct is_unique_ptr<std::unique_ptr<T, D>> : std::true_type { -}; - -//! Returns index corresponding to the first occurance of the item in the container. -//! If item doesn't exist, will return -1. Works with containers containing unique_ptr. - -template <typename It, typename T> int IndexOfItem(It begin, It end, const T& item) -{ - It pos; - if constexpr (is_unique_ptr<typename std::iterator_traits<It>::value_type>::value) - pos = find_if(begin, end, [&item](const auto& x) { return x.get() == item; }); - else - pos = find_if(begin, end, [&item](const auto& x) { return x == item; }); - - return pos == end ? -1 : static_cast<int>(std::distance(begin, pos)); -} - -//! Returns index corresponding to the first occurance of the item in the container. -//! If item doesn't exist, will return -1. Works with containers containing unique_ptr. - -template <typename C, typename T> int IndexOfItem(const C& container, const T& item) -{ - return IndexOfItem(container.begin(), container.end(), item); -} - -//! Returns vector containing results of elemntwise unary function application. - -template <typename It, typename UnaryFunction> -std::vector<double> Apply(It begin, It end, UnaryFunction func) -{ - std::vector<double> result; - std::transform(begin, end, std::back_inserter(result), func); - return result; -} - -//! Returns vector with real part of complex numbers. - -template <typename C> std::vector<double> Real(const C& container) -{ - return Apply(std::begin(container), std::end(container), - [](const auto& x) { return std::real(x); }); -} - -//! Returns vector with imag part of complex numbers. - -template <typename C> std::vector<double> Imag(const C& container) -{ - return Apply(std::begin(container), std::end(container), - [](const auto& x) { return std::imag(x); }); -} - -//! Returns copy of container with all duplicated elements filtered our. The order is preserved. - -template <typename C> C UniqueWithOrder(const C& container) -{ - C result; - - using valueType = typename C::value_type; - std::unordered_set<valueType> unique; - - std::copy_if(container.begin(), container.end(), std::back_inserter(result), - [&unique](auto x) { return unique.insert(x).second; }); - - return result; -} - -//! Returns true if container contains a given element. - -template <typename A, typename B> bool Contains(const A& container, const B& element) -{ - return std::find(container.begin(), container.end(), element) != container.end(); -} - -} // namespace ModelView::Utils - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_UTILS_CONTAINERUTILS_H diff --git a/mvvm/model/mvvm/utils/fileutils.cpp b/mvvm/model/mvvm/utils/fileutils.cpp deleted file mode 100644 index 1a2c15e4fafb4fa7a228b84c2f3c587e408e2226..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/utils/fileutils.cpp +++ /dev/null @@ -1,135 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/utils/fileutils.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/utils/fileutils.h" -#include <QDir> -#include <QFile> -#include <QFileInfo> -#include <stdexcept> - -#ifdef ENABLE_FILESYSTEM -#include "mvvm/core/filesystem.h" -#endif - -using namespace ModelView; - -bool Utils::exists(const std::string& fileName) -{ -#ifdef ENABLE_FILESYSTEM - return std::filesystem::exists(fileName); -#else - QFileInfo info(QString::fromStdString(fileName)); - return info.exists(); -#endif -} - -std::string Utils::join(const std::string& part1, const std::string& part2) -{ -#ifdef ENABLE_FILESYSTEM - auto path = std::filesystem::path(part1) / std::filesystem::path(part2); - return path.string(); -#else - return part1 + std::string("/") + part2; -#endif -} - -bool Utils::create_directory(const std::string& path) -{ -#ifdef ENABLE_FILESYSTEM - return std::filesystem::create_directory(path); -#else - QDir dir(QString::fromStdString(path)); - return dir.mkpath("."); -#endif -} - -bool Utils::remove(const std::string& path) -{ -#ifdef ENABLE_FILESYSTEM - return std::filesystem::remove(path); -#else - QFile file(QString::fromStdString(path)); - return file.remove(); -#endif -} - -void Utils::remove_all(const std::string& path) -{ -#ifdef ENABLE_FILESYSTEM - std::filesystem::remove_all(path); -#else - QDir dir(QString::fromStdString(path)); - if (dir.exists()) - dir.removeRecursively(); -#endif -} - -std::string Utils::base_name(const std::string& path) -{ -#ifdef ENABLE_FILESYSTEM - return std::filesystem::path(path).stem().string(); -#else - return QFileInfo(QString::fromStdString(path)).completeBaseName().toStdString(); -#endif -} - -std::vector<std::string> Utils::FindFiles(const std::string& dirname, const std::string& ext) -{ -#ifdef ENABLE_FILESYSTEM - std::vector<std::string> result; - for (const auto& entry : std::filesystem::directory_iterator(dirname)) { - const auto filenameStr = entry.path().filename().string(); - if (entry.is_regular_file() && entry.path().extension() == ext) - result.push_back(entry.path().string()); - } - return result; -#else - std::vector<std::string> result; - QDir dir(QString::fromStdString(dirname)); - if (dir.exists()) { - QStringList filters = {QString::fromStdString("*" + ext)}; - for (auto entry : dir.entryList(filters)) { - auto name = dir.filePath(entry); - result.push_back(name.toStdString()); - } - } - return result; -#endif -} - -std::string Utils::parent_path(const std::string& path) -{ -#ifdef ENABLE_FILESYSTEM - return std::filesystem::path(path).parent_path().string(); -#else - QFileInfo info(QString::fromStdString(path)); - return info.dir().path().toStdString(); -#endif -} - -bool Utils::is_empty(const std::string& path) -{ -#ifdef ENABLE_FILESYSTEM - return std::filesystem::is_empty(path); -#else - QFileInfo info(QString::fromStdString(path)); - if (info.isDir()) { - QDir dir(QString::fromStdString(path)); - return dir.isEmpty(); - } else { - return info.size() == 0; - } - return false; -#endif -} diff --git a/mvvm/model/mvvm/utils/fileutils.h b/mvvm/model/mvvm/utils/fileutils.h deleted file mode 100644 index 267d305b73082f52698518c51847412dea5e438a..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/utils/fileutils.h +++ /dev/null @@ -1,55 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/utils/fileutils.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_UTILS_FILEUTILS_H -#define BORNAGAIN_MVVM_MODEL_MVVM_UTILS_FILEUTILS_H - -#include "mvvm/model_export.h" -#include <string> -#include <vector> - -namespace ModelView::Utils { - -//! Returns true if file exists. -MVVM_MODEL_EXPORT bool exists(const std::string& fileName); - -//! Joins two path elements into the path. -MVVM_MODEL_EXPORT std::string join(const std::string& part1, const std::string& part2); - -//! Create directory, parent directory must exist. If path resolves to existing directory, -//! no error reported. -MVVM_MODEL_EXPORT bool create_directory(const std::string& path); - -//! Removes file or empty directory. -MVVM_MODEL_EXPORT bool remove(const std::string& path); - -//! Removes directory with all its content. -MVVM_MODEL_EXPORT void remove_all(const std::string& path); - -//! Provide the filename of a file path. -MVVM_MODEL_EXPORT std::string base_name(const std::string& path); - -//! Returns list of files with given extention found in given directory. -MVVM_MODEL_EXPORT std::vector<std::string> FindFiles(const std::string& dirname, - const std::string& ext); - -//! Returns the path to the parent directory. -MVVM_MODEL_EXPORT std::string parent_path(const std::string& path); - -//! Returns true if the file indicated by 'path' refers to empty file or directory. -MVVM_MODEL_EXPORT bool is_empty(const std::string& path); - -} // namespace ModelView::Utils - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_UTILS_FILEUTILS_H diff --git a/mvvm/model/mvvm/utils/ifactory.h b/mvvm/model/mvvm/utils/ifactory.h deleted file mode 100644 index 8b29f88cf51a33f8f505ef8d24dec3c82787839b..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/utils/ifactory.h +++ /dev/null @@ -1,67 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/utils/ifactory.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_UTILS_IFACTORY_H -#define BORNAGAIN_MVVM_MODEL_MVVM_UTILS_IFACTORY_H - -#include <functional> -#include <map> -#include <memory> -#include <sstream> -#include <stdexcept> - -namespace ModelView { - -//! Base for factories. - -template <class Key, class Value> class IFactory { -public: - using function_t = std::function<std::unique_ptr<Value>()>; - using map_t = std::map<Key, function_t>; - - bool contains(const Key& item_key) const { return m_data.find(item_key) != m_data.end(); } - - std::unique_ptr<Value> create(const Key& item_key) const - { - auto it = m_data.find(item_key); - if (it == m_data.end()) { - std::ostringstream message; - message << "IFactory::createItem() -> Error. Unknown item key '" << item_key << "'"; - throw std::runtime_error(message.str()); - } - return it->second(); - } - - bool add(const Key& key, function_t func) - { - if (m_data.find(key) != m_data.end()) { - std::ostringstream message; - message << "IFactory::createItem() -> Already registered item key '" << key << "'"; - throw std::runtime_error(message.str()); - } - return m_data.insert(make_pair(key, func)).second; - } - - size_t size() const { return m_data.size(); } - - typename map_t::iterator begin() { return m_data.begin(); } - typename map_t::iterator end() { return m_data.end(); } - -private: - map_t m_data; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_UTILS_IFACTORY_H diff --git a/mvvm/model/mvvm/utils/mathconstants.h b/mvvm/model/mvvm/utils/mathconstants.h deleted file mode 100644 index c5fdb44751b07249560922b06049caee0de7cfc9..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/utils/mathconstants.h +++ /dev/null @@ -1,22 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/utils/mathconstants.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_UTILS_MATHCONSTANTS_H -#define BORNAGAIN_MVVM_MODEL_MVVM_UTILS_MATHCONSTANTS_H - -#ifndef M_PI -#define M_PI 3.14159265358979323846264338327950288 /* pi */ -#endif - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_UTILS_MATHCONSTANTS_H diff --git a/mvvm/model/mvvm/utils/numericutils.cpp b/mvvm/model/mvvm/utils/numericutils.cpp deleted file mode 100644 index 277691ad9f33740a6779bd4f2f07f67267bb5977..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/utils/numericutils.cpp +++ /dev/null @@ -1,44 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/utils/numericutils.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/utils/numericutils.h" -#include <algorithm> -#include <cmath> -#include <limits> -#include <random> - -using namespace ModelView; - -bool Utils::AreAlmostEqual(double a, double b, double tolerance) -{ - constexpr double eps = std::numeric_limits<double>::epsilon(); - return std::abs(a - b) - <= eps * std::max(tolerance * eps, std::max(1., tolerance) * std::abs(b)); -} - -int Utils::RandInt(int low, int high) -{ - std::random_device rd; - std::mt19937 gen(rd()); - std::uniform_int_distribution<int> uniform_int(low, high); - return uniform_int(gen); -} - -double Utils::RandDouble(double low, double high) -{ - std::random_device rd; - std::mt19937 gen(rd()); - std::uniform_real_distribution<> uniform_real(low, high); - return uniform_real(gen); -} diff --git a/mvvm/model/mvvm/utils/numericutils.h b/mvvm/model/mvvm/utils/numericutils.h deleted file mode 100644 index 3e37ea442365d1d2f0c275905a97fb9e0cdc7415..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/utils/numericutils.h +++ /dev/null @@ -1,33 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/utils/numericutils.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_UTILS_NUMERICUTILS_H -#define BORNAGAIN_MVVM_MODEL_MVVM_UTILS_NUMERICUTILS_H - -#include "mvvm/model_export.h" - -namespace ModelView::Utils { - -//! Returns true if two doubles agree within epsilon*tolerance. -MVVM_MODEL_EXPORT bool AreAlmostEqual(double a, double b, double tolerance_factor = 1.0); - -//! Produces random integer values uniformly distributed on the closed interval [low, high]. -MVVM_MODEL_EXPORT int RandInt(int low, int high); - -//! Produces random FLOAT values uniformly distributed on the interval [low, high). -MVVM_MODEL_EXPORT double RandDouble(double low, double high); - -} // namespace ModelView::Utils - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_UTILS_NUMERICUTILS_H diff --git a/mvvm/model/mvvm/utils/progresshandler.cpp b/mvvm/model/mvvm/utils/progresshandler.cpp deleted file mode 100644 index a213c01ee4d2fcbaef03785102fdcdfb973c0d7e..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/utils/progresshandler.cpp +++ /dev/null @@ -1,61 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/utils/progresshandler.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/utils/progresshandler.h" - -using namespace ModelView; - -ProgressHandler::ProgressHandler(ProgressHandler::callback_t callback, size_t max_ticks_count) - : runner_callback(std::move(callback)), max_ticks_count(max_ticks_count) -{ -} - -void ProgressHandler::subscribe(ProgressHandler::callback_t callback) -{ - runner_callback = std::move(callback); -} - -//! Sets expected ticks count, representing progress of a computation. - -void ProgressHandler::setMaxTicksCount(size_t value) -{ - reset(); - max_ticks_count = value; -} - -bool ProgressHandler::has_interrupt_request() const -{ - return interrupt_request; -} - -//! Increment number of completed computation steps. Performs callback to inform -//! subscriber about current progress (in percents) and retrieves interrupt request flag. - -void ProgressHandler::setCompletedTicks(size_t value) -{ - std::unique_lock<std::mutex> lock(mutex); - completed_ticks += value; - if (completed_ticks > max_ticks_count) - max_ticks_count = completed_ticks + 1; - int percentage_done = static_cast<int>(100.0 * completed_ticks / max_ticks_count); - interrupt_request = runner_callback ? runner_callback(percentage_done) : interrupt_request; -} - -//! Resets progress. - -void ProgressHandler::reset() -{ - interrupt_request = false; - completed_ticks = 0; -} diff --git a/mvvm/model/mvvm/utils/progresshandler.h b/mvvm/model/mvvm/utils/progresshandler.h deleted file mode 100644 index 087b3a7bb66110740b4c074387c9ec0147cd465e..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/utils/progresshandler.h +++ /dev/null @@ -1,57 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/utils/progresshandler.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_UTILS_PROGRESSHANDLER_H -#define BORNAGAIN_MVVM_MODEL_MVVM_UTILS_PROGRESSHANDLER_H - -#include "mvvm/model_export.h" -#include <functional> -#include <mutex> - -namespace ModelView { - -//! Maintain information about progress of a computation. -//! Initialized with callback function to report progress and retrieve interruption request status. - -class MVVM_MODEL_EXPORT ProgressHandler { -public: - using callback_t = std::function<bool(size_t)>; - - ProgressHandler() = default; - ProgressHandler(callback_t callback, size_t max_ticks_count); - - ProgressHandler(const ProgressHandler& other) = delete; - ProgressHandler& operator=(const ProgressHandler& other) = delete; - - void subscribe(callback_t callback); - - void setMaxTicksCount(size_t value); - - bool has_interrupt_request() const; - - void setCompletedTicks(size_t value); - - void reset(); - -private: - std::mutex mutex; - callback_t runner_callback; - size_t max_ticks_count{0}; - size_t completed_ticks{0}; - bool interrupt_request{false}; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_UTILS_PROGRESSHANDLER_H diff --git a/mvvm/model/mvvm/utils/reallimits.cpp b/mvvm/model/mvvm/utils/reallimits.cpp deleted file mode 100644 index cd37cec50c6841c8b9c8c9fe87390ed5c66d1bf0..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/utils/reallimits.cpp +++ /dev/null @@ -1,154 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/utils/reallimits.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/utils/reallimits.h" -#include "mvvm/utils/numericutils.h" -#include <limits> - -namespace { -const double lmin = std::numeric_limits<double>::lowest(); -const double lmax = std::numeric_limits<double>::max(); -const double poszero = std::numeric_limits<double>::min(); -} // namespace - -using namespace ModelView; - -RealLimits::RealLimits() - : m_has_lower_limit(false), m_has_upper_limit(false), m_lower_limit(lmin), m_upper_limit(lmax) -{ -} - -RealLimits::RealLimits(bool has_lower_limit, bool has_upper_limit, double lower_limit, - double upper_limit) - : m_has_lower_limit(has_lower_limit) - , m_has_upper_limit(has_upper_limit) - , m_lower_limit(lower_limit) - , m_upper_limit(upper_limit) -{ -} - -RealLimits RealLimits::lowerLimited(double bound_value) -{ - return RealLimits(true, false, bound_value, lmax); -} - -RealLimits RealLimits::positive() -{ - return lowerLimited(poszero); -} - -RealLimits RealLimits::nonnegative() -{ - return lowerLimited(0.); -} - -RealLimits RealLimits::upperLimited(double bound_value) -{ - return RealLimits(false, true, lmin, bound_value); -} - -RealLimits RealLimits::limited(double left_bound_value, double right_bound_value) -{ - return RealLimits(true, true, left_bound_value, right_bound_value); -} - -RealLimits RealLimits::limitless() -{ - return RealLimits(); -} - -bool RealLimits::hasLowerLimit() const -{ - return m_has_lower_limit; -} - -double RealLimits::lowerLimit() const -{ - return m_lower_limit; -} - -bool RealLimits::hasUpperLimit() const -{ - return m_has_upper_limit; -} - -double RealLimits::upperLimit() const -{ - return m_upper_limit; -} - -bool RealLimits::hasLowerAndUpperLimits() const -{ - return (m_has_lower_limit && m_has_upper_limit); -} - -bool RealLimits::isInRange(double value) const -{ - if (hasLowerLimit() && value < m_lower_limit) - return false; - if (hasUpperLimit() && value >= m_upper_limit) - return false; - return true; -} - -bool RealLimits::operator==(const RealLimits& other) const -{ - // Intenional 'unsafe' double comparison to have RealLimits::positive and - // RealLimits::nonnegative different. - // FIXME Is there better solution? Can we drop either positive or non-negative? - return (m_has_lower_limit == other.m_has_lower_limit) - && (m_has_upper_limit == other.m_has_upper_limit) && m_lower_limit == other.m_lower_limit - && m_upper_limit == other.m_upper_limit; -} - -bool RealLimits::operator!=(const RealLimits& other) const -{ - return !(*this == other); -} - -bool RealLimits::operator<(const RealLimits& other) const -{ - return m_lower_limit < other.m_lower_limit && m_upper_limit < other.m_upper_limit; -} - -bool RealLimits::isLimitless() const -{ - return !hasLowerLimit() && !hasUpperLimit(); -} - -bool RealLimits::isPositive() const -{ - // intenional 'unsafe' double comparison - return hasLowerLimit() && !hasUpperLimit() && lowerLimit() == poszero; -} - -bool RealLimits::isNonnegative() const -{ - return hasLowerLimit() && !hasUpperLimit() && lowerLimit() == 0.0; -} - -bool RealLimits::isLowerLimited() const -{ - return !isPositive() && !isNonnegative() && hasLowerLimit() && !hasUpperLimit(); -} - -bool RealLimits::isUpperLimited() const -{ - return !hasLowerLimit() && hasUpperLimit(); -} - -bool RealLimits::isLimited() const -{ - return hasLowerLimit() && hasUpperLimit(); -} diff --git a/mvvm/model/mvvm/utils/reallimits.h b/mvvm/model/mvvm/utils/reallimits.h deleted file mode 100644 index b082dad6a1d6c5d13cd9955284fd464a9711d6a6..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/utils/reallimits.h +++ /dev/null @@ -1,87 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/utils/reallimits.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_UTILS_REALLIMITS_H -#define BORNAGAIN_MVVM_MODEL_MVVM_UTILS_REALLIMITS_H - -#include "mvvm/model_export.h" - -namespace ModelView { - -//! Limits for double. -//! @ingroup fitting - -class MVVM_MODEL_EXPORT RealLimits { -public: - RealLimits(); - - //! Creates an object bounded from the left - static RealLimits lowerLimited(double bound_value); - - //! Creates an object which can have only positive values (>0., zero is not included) - static RealLimits positive(); - - //! Creates an object which can have only positive values with 0. included - static RealLimits nonnegative(); - - //! Creates an object bounded from the right - static RealLimits upperLimited(double bound_value); - - //! Creates an object bounded from the left and right - static RealLimits limited(double left_bound_value, double right_bound_value); - - //! Creates an object withoud bounds (default) - static RealLimits limitless(); - - //! if has lower limit - bool hasLowerLimit() const; - - //! Returns lower limit - double lowerLimit() const; - - //! if has upper limit - bool hasUpperLimit() const; - - //! Returns upper limit - double upperLimit() const; - - //! if has lower and upper limit - bool hasLowerAndUpperLimits() const; - - //! returns true if proposed value is in limits range - bool isInRange(double value) const; - - bool operator==(const RealLimits& other) const; - bool operator!=(const RealLimits& other) const; - bool operator<(const RealLimits& other) const; - - bool isLimitless() const; - bool isPositive() const; - bool isNonnegative() const; - bool isLowerLimited() const; - bool isUpperLimited() const; - bool isLimited() const; - -protected: - RealLimits(bool has_lower_limit, bool has_upper_limit, double lower_limit, double upper_limit); - - bool m_has_lower_limit; //! parameter has lower bound - bool m_has_upper_limit; //! parameter has upper bound - double m_lower_limit; //! minimum allowed value - double m_upper_limit; //! maximum allowed value -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_UTILS_REALLIMITS_H diff --git a/mvvm/model/mvvm/utils/stringutils.cpp b/mvvm/model/mvvm/utils/stringutils.cpp deleted file mode 100644 index 957ba350c3c9bfcb1e5ebb9d1be1a830e57c6f0e..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/utils/stringutils.cpp +++ /dev/null @@ -1,130 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/utils/stringutils.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/utils/stringutils.h" -#include <algorithm> -#include <cmath> -#include <iomanip> -#include <iterator> -#include <sstream> -#include <string_view> - -using namespace ModelView; - -std::string Utils::DoubleToString(double input, int precision) -{ - std::ostringstream inter; - inter << std::setprecision(precision); - if (std::abs(input) < std::numeric_limits<double>::epsilon()) { - inter << "0.0"; - return inter.str(); - } - inter << input; - if (inter.str().find('e') == std::string::npos && inter.str().find('.') == std::string::npos) - inter << ".0"; - return inter.str(); -} - -std::string Utils::ScientificDoubleToString(double input, int precision) -{ - std::ostringstream inter; - inter << std::scientific; - inter << std::setprecision(precision); - inter << input; - - std::string::size_type pos = inter.str().find('e'); - if (pos == std::string::npos) - return inter.str(); - - std::string part1 = inter.str().substr(0, pos); - std::string part2 = inter.str().substr(pos, std::string::npos); - - part1.erase(part1.find_last_not_of('0') + 1, std::string::npos); - if (part1.back() == '.') - part1 += "0"; - - return part1 + part2; -} - -std::string Utils::TrimWhitespace(const std::string& str) -{ - const char whitespace[]{" \t\n"}; - const size_t first = str.find_first_not_of(whitespace); - if (std::string::npos == first) - return {}; - const size_t last = str.find_last_not_of(whitespace); - return str.substr(first, (last - first + 1)); -} - -std::string Utils::RemoveRepeatedSpaces(std::string str) -{ - if (str.empty()) - return {}; - auto it = std::unique(str.begin(), str.end(), - [](auto x, auto y) { return x == y && std::isspace(x); }); - str.erase(it, str.end()); - return str; -} - -std::optional<double> Utils::StringToDouble(const std::string& str) -{ - std::istringstream iss(Utils::TrimWhitespace(str)); - iss.imbue(std::locale::classic()); - double value; - iss >> value; - return (!iss.fail() && iss.eof()) ? std::optional<double>(value) : std::optional<double>{}; -} - -std::optional<int> Utils::StringToInteger(const std::string& str) -{ - std::istringstream iss(Utils::TrimWhitespace(str)); - int value; - iss >> value; - return (!iss.fail() && iss.eof()) ? std::optional<int>(value) : std::optional<int>{}; -} - -std::vector<std::string> Utils::SplitString(const std::string& str, const std::string& delimeter) -{ - // splitting string following Python's str.split() - if (delimeter.empty()) - throw std::runtime_error("Empty delimeter"); - if (str.empty()) - return {}; - - std::vector<std::string> result; - std::string_view view(str); - size_t pos{0}; - - while ((pos = view.find(delimeter)) != std::string::npos) { - result.emplace_back(std::string(view.substr(0, pos))); - view.remove_prefix(pos + delimeter.length()); - } - result.emplace_back(std::string(view)); - return result; -} - -std::vector<double> Utils::ParseSpaceSeparatedDoubles(const std::string& str) -{ - std::vector<double> result; - ParseSpaceSeparatedDoubles(str, result); - return result; -} - -void Utils::ParseSpaceSeparatedDoubles(const std::string& str, std::vector<double>& result) -{ - std::istringstream iss(str); - iss.imbue(std::locale::classic()); - std::copy(std::istream_iterator<double>(iss), std::istream_iterator<double>(), - back_inserter(result)); -} diff --git a/mvvm/model/mvvm/utils/stringutils.h b/mvvm/model/mvvm/utils/stringutils.h deleted file mode 100644 index 80e059912e5027b7b66a18cfd16430249270c885..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/utils/stringutils.h +++ /dev/null @@ -1,64 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/utils/stringutils.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_UTILS_STRINGUTILS_H -#define BORNAGAIN_MVVM_MODEL_MVVM_UTILS_STRINGUTILS_H - -#include "mvvm/model_export.h" -#include <optional> -#include <string> -#include <vector> - -namespace ModelView ::Utils { - -//! Returns string representation of double with given precision. -//! Provides additional formatting on top of iomanip, so "double x{0}" becomes "0.0". -MVVM_MODEL_EXPORT std::string DoubleToString(double input, int precision = 12); - -//! Returns string representation of scientific double. -//! Provides additional formatting on top of iomanip, so "double x{1}" becomes "1.0e+00". -MVVM_MODEL_EXPORT std::string ScientificDoubleToString(double input, int precision = 6); - -//! Returns string after trimming whitespace surrounding, including tabs and carriage returns. -MVVM_MODEL_EXPORT std::string TrimWhitespace(const std::string& str); - -//! Removes repeating spaces for a string. -MVVM_MODEL_EXPORT std::string RemoveRepeatedSpaces(std::string str); - -//! Converts string to double value using classc locale and returns it in the form of optional. -//! Requires that string represents exactly one double and contains no other literals. Empty -//! spaces at the beginning and end of the string are still allowed. -MVVM_MODEL_EXPORT std::optional<double> StringToDouble(const std::string& str); - -//! Converts string to integer. Requires that string represents exactly one integer and -//! no extra symbols are defined. Empty spaces at the beginning and end of the string are still -//! allowed. -MVVM_MODEL_EXPORT std::optional<int> StringToInteger(const std::string& str); - -//! Split string on substring using given delimeter. Reproduces Python's str.split() behavior. -MVVM_MODEL_EXPORT std::vector<std::string> SplitString(const std::string& str, - const std::string& delimeter); - -//! Parses string for double values and returns result as a vector. -//! All non-numeric symbols are ingored. -MVVM_MODEL_EXPORT std::vector<double> ParseSpaceSeparatedDoubles(const std::string& str); - -//! Parses string for double values and stores result in a vector. -//! All non-numeric symbols are ingored. -MVVM_MODEL_EXPORT void ParseSpaceSeparatedDoubles(const std::string& str, - std::vector<double>& result); - -} // namespace ModelView::Utils - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_UTILS_STRINGUTILS_H diff --git a/mvvm/model/mvvm/utils/threadsafestack.h b/mvvm/model/mvvm/utils/threadsafestack.h deleted file mode 100644 index 1f1dec6ad458893cb79c277fc143c375c7fa494b..0000000000000000000000000000000000000000 --- a/mvvm/model/mvvm/utils/threadsafestack.h +++ /dev/null @@ -1,135 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/model/mvvm/utils/threadsafestack.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_MODEL_MVVM_UTILS_THREADSAFESTACK_H -#define BORNAGAIN_MVVM_MODEL_MVVM_UTILS_THREADSAFESTACK_H - -#include "mvvm/model_export.h" -#include <atomic> -#include <condition_variable> -#include <memory> -#include <mutex> -#include <stack> -#include <stdexcept> -#include <thread> - -//! @file mvvm/model/mvvm/utils/threadsafestack.h -//! @brief Thread-safe stack borrowed from Anthony Williams, C++ Concurrency in Action, Second -//! edition. - -namespace ModelView { - -struct empty_stack : public std::exception { - const char* what() const noexcept { return "Empty stack"; } -}; - -//! @class threadsafe_stack -//! @brief Thread-safe stack borrowed from Anthony Williams, C++ Concurrency in Action, Second -//! edition. - -template <typename T> class threadsafe_stack { -private: - std::stack<T> data; - mutable std::mutex m; - std::condition_variable data_condition; - std::atomic<bool> in_waiting_state{true}; - -public: - threadsafe_stack() {} - ~threadsafe_stack() { stop(); } - threadsafe_stack(const threadsafe_stack& other) - { - std::lock_guard<std::mutex> lock(m); - data = other.data; - } - threadsafe_stack& operator=(const threadsafe_stack& other) = delete; - - void push(T new_value) - { - std::lock_guard<std::mutex> lock(m); - data.push(std::move(new_value)); - data_condition.notify_one(); - } - - //! Updates top value in a stack. - - void update_top(T new_value) - { - std::lock_guard<std::mutex> lock(m); - if (!data.empty()) - data.pop(); - data.push(std::move(new_value)); - data_condition.notify_one(); - } - - void wait_and_pop(T& value) - { - std::unique_lock<std::mutex> lock(m); - data_condition.wait(lock, [this] { return !data.empty() || !in_waiting_state; }); - if (data.empty()) - throw empty_stack(); - value = std::move(data.top()); - data.pop(); - } - - std::shared_ptr<T> wait_and_pop() - { - std::unique_lock<std::mutex> lock(m); - data_condition.wait(lock, [this] { return !data.empty() || !in_waiting_state; }); - if (data.empty()) - throw empty_stack(); - std::shared_ptr<T> const res(std::make_shared<T>(std::move(data.top()))); - data.pop(); - return res; - } - - bool try_pop(T& value) - { - std::lock_guard<std::mutex> lock(m); - if (data.empty()) - return false; - value = std::move(data.top()); - data.pop(); - return true; - } - - std::shared_ptr<T> try_pop() - { - std::lock_guard<std::mutex> lock(m); - if (data.empty()) - return std::shared_ptr<T>(); - std::shared_ptr<T> res(std::make_shared<T>(std::move(data.top()))); - data.pop(); - return res; - } - - bool empty() const - { - std::lock_guard<std::mutex> lock(m); - return data.empty(); - } - - //! Terminates waiting in wait_and_pop methods. - - void stop() - { - std::lock_guard<std::mutex> lock(m); - in_waiting_state = false; - data_condition.notify_all(); - } -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_MODEL_MVVM_UTILS_THREADSAFESTACK_H diff --git a/mvvm/tests/CMakeLists.txt b/mvvm/tests/CMakeLists.txt deleted file mode 100644 index cbe849feb945a17e3949d3e2cadc2e3b3e3d0ef5..0000000000000000000000000000000000000000 --- a/mvvm/tests/CMakeLists.txt +++ /dev/null @@ -1,12 +0,0 @@ -include(GoogleTest) - -if(WIN32) - add_definitions(-DGTEST_LINKED_AS_SHARED_LIBRARY) -endif() - -add_subdirectory(libtestmachinery) -add_subdirectory(testintegration) -add_subdirectory(testmodel) -add_subdirectory(testview) -add_subdirectory(testviewmodel) - diff --git a/mvvm/tests/README.md b/mvvm/tests/README.md deleted file mode 100644 index 09e3c346866cec83bafecfa08bdc7dad1f840b9a..0000000000000000000000000000000000000000 --- a/mvvm/tests/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# Unit tests for qt-mvvm. - -- `data` collection of files used for testing -- `libtestmachinery` static library with supporting test utils and mock items -- `testmodel` collection of unit tests for `libmvvm_model` -- `testviewmodel` collection of unit tests for `libmvvm_viewmodel` -- `testview` collection of unit tests for `libmvvm_view` -- `testintegration` collection of tests with various integration scenarios - diff --git a/mvvm/tests/data/c++_exec b/mvvm/tests/data/c++_exec deleted file mode 100755 index e40e4d16327eb69e2b9359d213c72c38521259d4..0000000000000000000000000000000000000000 Binary files a/mvvm/tests/data/c++_exec and /dev/null differ diff --git a/mvvm/tests/data/mandelbrot.ppm b/mvvm/tests/data/mandelbrot.ppm deleted file mode 100644 index 1fef16f813f392f8f59af4f07bd3bea99c62099d..0000000000000000000000000000000000000000 Binary files a/mvvm/tests/data/mandelbrot.ppm and /dev/null differ diff --git a/mvvm/tests/data/pdf_file b/mvvm/tests/data/pdf_file deleted file mode 100644 index d287cfd1b87afc9041d0799e28d37725079dc8bf..0000000000000000000000000000000000000000 Binary files a/mvvm/tests/data/pdf_file and /dev/null differ diff --git a/mvvm/tests/data/png_file.png b/mvvm/tests/data/png_file.png deleted file mode 100644 index 997edcbec596fb84fcec83b3d2ccda23ecc9ac29..0000000000000000000000000000000000000000 Binary files a/mvvm/tests/data/png_file.png and /dev/null differ diff --git a/mvvm/tests/data/text_UTF-8-BOM.txt b/mvvm/tests/data/text_UTF-8-BOM.txt deleted file mode 100644 index 64a7a02dc46e5c85021449bd5027e476a1c6f9e2..0000000000000000000000000000000000000000 --- a/mvvm/tests/data/text_UTF-8-BOM.txt +++ /dev/null @@ -1,2 +0,0 @@ -simple text and -some characters like 🌂, 💖, ä, ð„ž, € and ∰ diff --git a/mvvm/tests/data/text_UTF-8.txt b/mvvm/tests/data/text_UTF-8.txt deleted file mode 100644 index 26168a37cbd50a695cc98d4382d62c225fbc64f2..0000000000000000000000000000000000000000 --- a/mvvm/tests/data/text_UTF-8.txt +++ /dev/null @@ -1,2 +0,0 @@ -simple text and -some characters like 🌂, 💖, ä, ð„ž, € and ∰ diff --git a/mvvm/tests/data/word_file b/mvvm/tests/data/word_file deleted file mode 100644 index 6174820fddb1ead4ab4a5399319bc6bb465178e8..0000000000000000000000000000000000000000 Binary files a/mvvm/tests/data/word_file and /dev/null differ diff --git a/mvvm/tests/libtestmachinery/CMakeLists.txt b/mvvm/tests/libtestmachinery/CMakeLists.txt deleted file mode 100644 index bbb90e51a78d1216b66bba916587bab97c5cc5b0..0000000000000000000000000000000000000000 --- a/mvvm/tests/libtestmachinery/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ -set(library_name testmachinery) - -file(GLOB source_files "*.cpp") -file(GLOB include_files "*.h") - -find_package(Qt5 COMPONENTS Widgets Core Test REQUIRED) - -if(WIN32) - add_definitions(-DGTEST_LINKED_AS_SHARED_LIBRARY) -endif() - -add_library(${library_name} STATIC ${source_files} ${include_files}) -target_link_libraries(${library_name} gtest gmock Qt5::Core Qt5::Test mvvm_model) -target_include_directories(${library_name} PUBLIC - $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}> $<BUILD_INTERFACE:${MVVM_AUTOGEN_DIR}>) - -target_compile_features(${library_name} PUBLIC cxx_std_17) diff --git a/mvvm/tests/libtestmachinery/folderbasedtest.cpp b/mvvm/tests/libtestmachinery/folderbasedtest.cpp deleted file mode 100644 index d3919650217ed9b470c40ba73e58c1d61c6172d4..0000000000000000000000000000000000000000 --- a/mvvm/tests/libtestmachinery/folderbasedtest.cpp +++ /dev/null @@ -1,47 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/libtestmachinery/folderbasedtest.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "folderbasedtest.h" -#include "mvvm/utils/fileutils.h" -#include "test_utils.h" - -FolderBasedTest::FolderBasedTest(const std::string& test_dir) : m_test_dir(test_dir) -{ - TestUtils::CreateTestDirectory(m_test_dir); -} - -std::string FolderBasedTest::testDir() const -{ - return m_test_dir; -} - -//! Return full path to the test folder. Located in CMAKE_BINARY_DIR/test_output/<m_test_dir>. - -std::string FolderBasedTest::testPath() const -{ - return TestUtils::TestDirectoryPath(m_test_dir); -} - -//! Creates an empty directory in main test folder. -//! Remove recursively previous one with the same name, if exist. - -std::string FolderBasedTest::createEmptyDir(const std::string& subdir) const -{ - auto path = ModelView::Utils::join(testPath(), subdir); - ModelView::Utils::remove_all(path); - ModelView::Utils::create_directory(path); - return path; -} - -FolderBasedTest::~FolderBasedTest() = default; diff --git a/mvvm/tests/libtestmachinery/folderbasedtest.h b/mvvm/tests/libtestmachinery/folderbasedtest.h deleted file mode 100644 index 25e5b957c3b77636171d1a95701492d5d47605c0..0000000000000000000000000000000000000000 --- a/mvvm/tests/libtestmachinery/folderbasedtest.h +++ /dev/null @@ -1,38 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/libtestmachinery/folderbasedtest.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_TESTS_LIBTESTMACHINERY_FOLDERBASEDTEST_H -#define BORNAGAIN_MVVM_TESTS_LIBTESTMACHINERY_FOLDERBASEDTEST_H - -#include <gtest/gtest.h> -#include <string> - -//! Convenience class which creates a directory on disk for test content. - -class FolderBasedTest : public ::testing::Test { -public: - FolderBasedTest(const std::string& test_dir); - ~FolderBasedTest(); - - std::string testDir() const; - - std::string testPath() const; - - std::string createEmptyDir(const std::string& subdir) const; - -protected: - std::string m_test_dir; //! main directory of given test -}; - -#endif // BORNAGAIN_MVVM_TESTS_LIBTESTMACHINERY_FOLDERBASEDTEST_H diff --git a/mvvm/tests/libtestmachinery/google_test.h b/mvvm/tests/libtestmachinery/google_test.h deleted file mode 100644 index ca8abc21b692e84bda20c787da37ddffb95071cd..0000000000000000000000000000000000000000 --- a/mvvm/tests/libtestmachinery/google_test.h +++ /dev/null @@ -1,22 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/libtestmachinery/google_test.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_TESTS_LIBTESTMACHINERY_GOOGLE_TEST_H -#define BORNAGAIN_MVVM_TESTS_LIBTESTMACHINERY_GOOGLE_TEST_H - -#include "mvvm/model/comparators.h" -#include "mvvm/model/customvariants.h" -#include <gtest/gtest.h> - -#endif // BORNAGAIN_MVVM_TESTS_LIBTESTMACHINERY_GOOGLE_TEST_H diff --git a/mvvm/tests/libtestmachinery/mockinterfaces.h b/mvvm/tests/libtestmachinery/mockinterfaces.h deleted file mode 100644 index 35bd8e7150a63ec28c55444c9dccada2e2f1cc18..0000000000000000000000000000000000000000 --- a/mvvm/tests/libtestmachinery/mockinterfaces.h +++ /dev/null @@ -1,56 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/libtestmachinery/mockinterfaces.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_TESTS_LIBTESTMACHINERY_MOCKINTERFACES_H -#define BORNAGAIN_MVVM_TESTS_LIBTESTMACHINERY_MOCKINTERFACES_H - -#include "mvvm/model/tagrow.h" -#include <string> - -//! Various common utils for unit tests. - -namespace ModelView { -class SessionItem; -class SessionModel; -} // namespace ModelView - -//! Interface for testing callbacks comming from SessionItem within gmock framework. - -class ItemTestWidgetInterface { -public: - virtual ~ItemTestWidgetInterface() = default; - - virtual void onItemDestroy(ModelView::SessionItem* item) = 0; - virtual void onDataChange(ModelView::SessionItem* item, int role) = 0; - virtual void onPropertyChange(ModelView::SessionItem* item, std::string name) = 0; - virtual void onItemInserted(ModelView::SessionItem* item, ModelView::TagRow) = 0; - virtual void onAboutToRemoveItem(ModelView::SessionItem* item, ModelView::TagRow) = 0; -}; - -//! Interface for testing callbacks comming from SessionModel within gmock framework. - -class ModelTestWidgetInterface { -public: - virtual ~ModelTestWidgetInterface() = default; - - virtual void onModelDestroyed(ModelView::SessionModel*) = 0; - virtual void onModelAboutToBeReset(ModelView::SessionModel*) = 0; - virtual void onModelReset(ModelView::SessionModel*) = 0; - virtual void onDataChange(ModelView::SessionItem*, int) = 0; - virtual void onItemInserted(ModelView::SessionItem*, ModelView::TagRow) = 0; - virtual void onItemRemoved(ModelView::SessionItem*, ModelView::TagRow) = 0; - virtual void onAboutToRemoveItem(ModelView::SessionItem*, ModelView::TagRow) = 0; -}; - -#endif // BORNAGAIN_MVVM_TESTS_LIBTESTMACHINERY_MOCKINTERFACES_H diff --git a/mvvm/tests/libtestmachinery/mockwidgets.cpp b/mvvm/tests/libtestmachinery/mockwidgets.cpp deleted file mode 100644 index c6969b16dd3a5afe36eba5798bcb7f727dc9951a..0000000000000000000000000000000000000000 --- a/mvvm/tests/libtestmachinery/mockwidgets.cpp +++ /dev/null @@ -1,144 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/libtestmachinery/mockwidgets.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mockwidgets.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/model/tagrow.h" -#include "mvvm/signals/itemmapper.h" -#include "mvvm/signals/modelmapper.h" - -// ---------------------------------------------------------------------------- - -MockWidgetForItem::MockWidgetForItem(ModelView::SessionItem* item) : m_item(nullptr) -{ - setItem(item); -} - -MockWidgetForItem::~MockWidgetForItem() -{ - if (m_item) - m_item->mapper()->unsubscribe(this); -} - -void MockWidgetForItem::setItem(ModelView::SessionItem* item) -{ - if (m_item == item) - return; - - if (m_item) - m_item->mapper()->unsubscribe(this); - - m_item = item; - - if (!m_item) - return; - - auto on_item_destroy = [this](ModelView::SessionItem* item) { - m_item = nullptr; - onItemDestroy(item); - }; - m_item->mapper()->setOnItemDestroy(on_item_destroy, this); - - auto on_data_change = [this](ModelView::SessionItem* item, int role) { - onDataChange(item, role); - }; - m_item->mapper()->setOnDataChange(on_data_change, this); - - auto on_property_change = [this](ModelView::SessionItem* item, std::string name) { - onPropertyChange(item, name); - }; - m_item->mapper()->setOnPropertyChange(on_property_change, this); - - auto on_child_property_change = [this](ModelView::SessionItem* item, std::string name) { - onChildPropertyChange(item, name); - }; - m_item->mapper()->setOnChildPropertyChange(on_child_property_change, this); - - auto on_item_inserted = [this](ModelView::SessionItem* item, ModelView::TagRow tagrow) { - onItemInserted(item, tagrow); - }; - m_item->mapper()->setOnItemInserted(on_item_inserted, this); - - auto on_item_removed = [this](ModelView::SessionItem* item, ModelView::TagRow tagrow) { - onItemRemoved(item, tagrow); - }; - m_item->mapper()->setOnItemRemoved(on_item_removed, this); - - auto on_about_to_remove_item = [this](ModelView::SessionItem* item, ModelView::TagRow tagrow) { - onAboutToRemoveItem(item, tagrow); - }; - m_item->mapper()->setOnAboutToRemoveItem(on_about_to_remove_item, this); -} - -// ---------------------------------------------------------------------------- - -MockWidgetForModel::MockWidgetForModel(ModelView::SessionModel* model) : m_model(nullptr) -{ - setModel(model); -} - -MockWidgetForModel::~MockWidgetForModel() -{ - if (m_model) - m_model->mapper()->unsubscribe(this); -} - -void MockWidgetForModel::setModel(ModelView::SessionModel* model) -{ - if (m_model == model) - return; - - if (m_model) - m_model->mapper()->unsubscribe(this); - - m_model = model; - - if (!m_model) - return; - - auto on_data_change = [this](ModelView::SessionItem* item, int role) { - onDataChange(item, role); - }; - m_model->mapper()->setOnDataChange(on_data_change, this); - - auto on_item_inserted = [this](ModelView::SessionItem* item, ModelView::TagRow tagrow) { - onItemInserted(item, tagrow); - }; - m_model->mapper()->setOnItemInserted(on_item_inserted, this); - - auto on_item_removed = [this](ModelView::SessionItem* item, ModelView::TagRow tagrow) { - onItemRemoved(item, tagrow); - }; - m_model->mapper()->setOnItemRemoved(on_item_removed, this); - - auto on_about_to_remove_item = [this](ModelView::SessionItem* item, ModelView::TagRow tagrow) { - onAboutToRemoveItem(item, tagrow); - }; - m_model->mapper()->setOnAboutToRemoveItem(on_about_to_remove_item, this); - - auto on_model_destroyed = [this](ModelView::SessionModel* model) { - m_model = nullptr; - onModelDestroyed(model); - }; - m_model->mapper()->setOnModelDestroyed(on_model_destroyed, this); - - auto on_model_about_reset = [this](ModelView::SessionModel* model) { - onModelAboutToBeReset(model); - }; - m_model->mapper()->setOnModelAboutToBeReset(on_model_about_reset, this); - - auto on_model_reset = [this](ModelView::SessionModel* model) { onModelReset(model); }; - m_model->mapper()->setOnModelReset(on_model_reset, this); -} diff --git a/mvvm/tests/libtestmachinery/mockwidgets.h b/mvvm/tests/libtestmachinery/mockwidgets.h deleted file mode 100644 index 49a680be00e9c3fe6674e5bdd6c0db3110134c48..0000000000000000000000000000000000000000 --- a/mvvm/tests/libtestmachinery/mockwidgets.h +++ /dev/null @@ -1,76 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/libtestmachinery/mockwidgets.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_TESTS_LIBTESTMACHINERY_MOCKWIDGETS_H -#define BORNAGAIN_MVVM_TESTS_LIBTESTMACHINERY_MOCKWIDGETS_H - -#include "mockinterfaces.h" -#include <gmock/gmock.h> - -namespace ModelView { -class SessionItem; -class SessionModel; -} // namespace ModelView - -//! Mock class for CallbackContainer. - -class CallbackMockWidget { -public: - MOCK_METHOD1(onItemDestroy, void(ModelView::SessionItem* item)); - MOCK_METHOD2(onDataChange, void(ModelView::SessionItem* item, int role)); -}; - -//! Mock widget to test ItemMapper functionality. - -class MockWidgetForItem : public ItemTestWidgetInterface { -public: - MockWidgetForItem(ModelView::SessionItem* item); - ~MockWidgetForItem(); - - void setItem(ModelView::SessionItem* item); - - MOCK_METHOD1(onItemDestroy, void(ModelView::SessionItem* item)); - MOCK_METHOD2(onDataChange, void(ModelView::SessionItem* item, int role)); - MOCK_METHOD2(onPropertyChange, void(ModelView::SessionItem* item, std::string name)); - MOCK_METHOD2(onChildPropertyChange, void(ModelView::SessionItem* item, std::string name)); - MOCK_METHOD2(onItemInserted, void(ModelView::SessionItem* item, ModelView::TagRow tagrow)); - MOCK_METHOD2(onItemRemoved, void(ModelView::SessionItem* item, ModelView::TagRow tagrow)); - MOCK_METHOD2(onAboutToRemoveItem, void(ModelView::SessionItem* item, ModelView::TagRow tagrow)); - -private: - ModelView::SessionItem* m_item; -}; - -//! Mock class to test ModelMapper functionality. - -class MockWidgetForModel : public ModelTestWidgetInterface { -public: - MockWidgetForModel(ModelView::SessionModel* model); - ~MockWidgetForModel(); - - void setModel(ModelView::SessionModel* model); - - MOCK_METHOD1(onModelDestroyed, void(ModelView::SessionModel* model)); - MOCK_METHOD1(onModelAboutToBeReset, void(ModelView::SessionModel* model)); - MOCK_METHOD1(onModelReset, void(ModelView::SessionModel* model)); - MOCK_METHOD2(onDataChange, void(ModelView::SessionItem* item, int role)); - MOCK_METHOD2(onItemInserted, void(ModelView::SessionItem* item, ModelView::TagRow tagrow)); - MOCK_METHOD2(onItemRemoved, void(ModelView::SessionItem* item, ModelView::TagRow tagrow)); - MOCK_METHOD2(onAboutToRemoveItem, void(ModelView::SessionItem* item, ModelView::TagRow tagrow)); - -private: - ModelView::SessionModel* m_model; -}; - -#endif // BORNAGAIN_MVVM_TESTS_LIBTESTMACHINERY_MOCKWIDGETS_H diff --git a/mvvm/tests/libtestmachinery/test_utils.cpp b/mvvm/tests/libtestmachinery/test_utils.cpp deleted file mode 100644 index c007883d22fbae28decb405d37a6fda5ec749521..0000000000000000000000000000000000000000 --- a/mvvm/tests/libtestmachinery/test_utils.cpp +++ /dev/null @@ -1,130 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/libtestmachinery/test_utils.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "test_utils.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/serialization/jsonconverterinterfaces.h" -#include "mvvm/serialization/jsonutils.h" -#include "mvvm/utils/fileutils.h" -#include "testconfig.h" // this file is auto generated by the build system in build directory -#include <QFile> -#include <QJsonDocument> -#include <QJsonObject> -#include <QString> -#include <QTextStream> -#include <stdexcept> -#include <string> - -using namespace ModelView; - -namespace { -void SaveDocument(const QJsonDocument& document, const std::string& fileName); -} - -std::string TestUtils::TestOutputDir() -{ - return TestConfig::TestOutputDir(); // defined in auto-generated testconfig.h -} - -std::string TestUtils::CreateTestDirectory(const std::string& test_sub_dir) -{ - std::string result = TestDirectoryPath(test_sub_dir); - Utils::create_directory(result); - return result; -} - -std::string TestUtils::TestDirectoryPath(const std::string& test_sub_dir) -{ - return TestOutputDir() + std::string("/") + test_sub_dir; -} - -std::string TestUtils::TestFileName(const std::string& test_sub_dir, const std::string& file_name) -{ - - return TestDirectoryPath(test_sub_dir) + std::string("/") + file_name; -} - -void TestUtils::SaveJson(const QJsonObject& object, const std::string& fileName) -{ - QJsonDocument document(object); - SaveDocument(document, fileName); -} - -void TestUtils::SaveJson(const QJsonArray& object, const std::string& fileName) -{ - QJsonDocument document(object); - SaveDocument(document, fileName); -} - -QString TestUtils::JsonToString(const QJsonObject& object) -{ - QJsonDocument document(object); - return QString(document.toJson(QJsonDocument::Compact)); -} - -QString TestUtils::ModelToJsonString(SessionModel& model) -{ - return QString::fromStdString(JsonUtils::ModelToJsonString(model)); -} - -QJsonDocument TestUtils::LoadJson(const std::string& fileName) -{ - QFile jsonFile(QString::fromStdString(fileName)); - - if (!jsonFile.open(QIODevice::ReadOnly)) - throw std::runtime_error("TestUtils::LoadJson() -> Can't read file"); - - return QJsonDocument().fromJson(jsonFile.readAll()); -} - -std::string TestUtils::CreateTestFile(const std::string& dirname, const std::string& fileName) -{ - std::string filename = dirname.empty() ? fileName : dirname + "/" + fileName; - - QFile file(QString::fromStdString(filename)); - if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) - throw std::runtime_error("TestFileUtils::createTestFile() -> Error. " - "Can't create file"); - - QTextStream out(&file); - out << "Test file " << 42 << "\n"; - file.close(); - - return filename; -} - -std::string TestUtils::CreateEmptyFile(const std::string& dirname, const std::string& fileName) -{ - std::string filename = dirname.empty() ? fileName : dirname + "/" + fileName; - - QFile file(QString::fromStdString(filename)); - if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) - throw std::runtime_error("TestFileUtils::createTestFile() -> Error. " - "Can't create file"); - return filename; -} - -namespace { - -void SaveDocument(const QJsonDocument& document, const std::string& fileName) -{ - QFile saveFile(QString::fromStdString(fileName)); - - if (!saveFile.open(QIODevice::WriteOnly)) - throw std::runtime_error("TestUtils::SaveDocument() -> Can't save file"); - - saveFile.write(document.toJson()); -} - -} // namespace diff --git a/mvvm/tests/libtestmachinery/test_utils.h b/mvvm/tests/libtestmachinery/test_utils.h deleted file mode 100644 index b743ca07c2053b63f6fd7bbee52d7952a58dd478..0000000000000000000000000000000000000000 --- a/mvvm/tests/libtestmachinery/test_utils.h +++ /dev/null @@ -1,109 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/libtestmachinery/test_utils.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_TESTS_LIBTESTMACHINERY_TEST_UTILS_H -#define BORNAGAIN_MVVM_TESTS_LIBTESTMACHINERY_TEST_UTILS_H - -#include "mvvm/model/customvariants.h" -#include <QString> -#include <memory> - -//! @file mvvm/tests/libtestmachinery/test_utils.h -//! @brief Collection of utility functions for various unit tests. - -class QJsonObject; -class QJsonArray; - -namespace ModelView { -class SessionModel; -} - -//! Various common utils for unit tests. - -namespace TestUtils { - -//! Returns full path to the main test folder, as defined by CMake at compile time. -//! Shoud point to CMAKE_BINARY_DIR/test_output -std::string TestOutputDir(); - -//! Creates test directory in main test folder and returns full path. -//! If directory exists, will do nothing. -std::string CreateTestDirectory(const std::string& test_sub_dir); - -//! Returns full path to the main test folder in CMAKE_BINARY_DIR. -std::string TestDirectoryPath(const std::string& test_sub_dir); - -//! Returns full path to the file in test directory. -std::string TestFileName(const std::string& test_sub_dir, const std::string& file_name); - -void SaveJson(const QJsonObject& object, const std::string& fileName); - -void SaveJson(const QJsonArray& object, const std::string& fileName); - -QString JsonToString(const QJsonObject& object); - -//! Returns string representing serialized json content of the model. -QString ModelToJsonString(ModelView::SessionModel& model); - -QJsonDocument LoadJson(const std::string& fileName); - -//! Helper function to create test file in a given directory (directory should exist). -//! Returns full path of the file. -std::string CreateTestFile(const std::string& dirname, const std::string& fileName); - -//! Helper function to create empty file in a given directory (directory should exist). -//! Returns full path of the file. -std::string CreateEmptyFile(const std::string& dirname, const std::string& fileName); - -//! Deletes items in the container and cleans container afterwards. - -template <typename T> void clean_items(T& items) -{ - for (auto item : items) - delete item; - items.clear(); -} - -//! Creates vector of unique_ptr of given type. - -template <typename B, typename D> auto create_row(int ncolumns) -{ - std::vector<std::unique_ptr<B>> result; - for (int i = 0; i < ncolumns; ++i) - result.emplace_back(std::make_unique<D>()); - return result; -} - -//! Creates vector of pointers from vector of unique_ptr. - -template <typename T> auto create_pointers(const std::vector<std::unique_ptr<T>>& vec) -{ - std::vector<T*> result; - std::transform(vec.begin(), vec.end(), std::back_inserter(result), - [](auto& x) { return x.get(); }); - return result; -} - -//! Creates vector of T from argument list. Used in EXPECT_EQ macros for convenience. - -template <typename T, typename... Args> std::vector<T> toVector(Args&&... args) -{ - std::vector<T> v; - (v.push_back(T(args)), ...); - return v; -} - -} // namespace TestUtils - -#endif // BORNAGAIN_MVVM_TESTS_LIBTESTMACHINERY_TEST_UTILS_H diff --git a/mvvm/tests/libtestmachinery/toyitems.cpp b/mvvm/tests/libtestmachinery/toyitems.cpp deleted file mode 100644 index 2ef891ccbe460d0ab9f4eebe8fa7f8369a64f314..0000000000000000000000000000000000000000 --- a/mvvm/tests/libtestmachinery/toyitems.cpp +++ /dev/null @@ -1,106 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/libtestmachinery/toyitems.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "toyitems.h" -#include "mvvm/model/comboproperty.h" -#include "mvvm/model/taginfo.h" -#include "mvvm/signals/itemmapper.h" -#include "mvvm/standarditems/vectoritem.h" -#include <QColor> -#include <stdexcept> - -using namespace ToyItems; - -MultiLayerItem::MultiLayerItem() : CompoundItem(GUI::Constants::MultiLayerItemType) -{ - registerTag(ModelView::TagInfo::universalTag(T_LAYERS, {GUI::Constants::LayerItemType}), - /*set_as_default*/ true); -} - -LayerItem::LayerItem() : CompoundItem(GUI::Constants::LayerItemType) -{ - addProperty(P_THICKNESS, 42.0); - addProperty(P_COLOR, QColor(Qt::green)); - registerTag(ModelView::TagInfo::universalTag(T_PARTICLES, {GUI::Constants::ParticleItemType}), - /*set_as_default*/ true); -} - -// ---------------------------------------------------------------------------- - -ParticleItem::ParticleItem() : CompoundItem(GUI::Constants::ParticleItemType) -{ - addProperty<ModelView::VectorItem>(P_POSITION); - addProperty<ShapeGroupItem>(P_SHAPES); -} - -// ---------------------------------------------------------------------------- - -LatticeItem::LatticeItem() : CompoundItem(GUI::Constants::LatticeItemType) -{ - addProperty(P_ROTATION_ANLE, 90.0); - addProperty(P_INTEGRATION, true); - - auto combo = ModelView::ComboProperty::createFrom({"Default", "Square", "Hexagonal"}); - addProperty(P_LATTICE_TYPE, combo); - - update_appearance(); -} - -void LatticeItem::activate() -{ - auto onIntegrationFlagChange = [this](SessionItem*, std::string property) { - if (property == P_INTEGRATION) - update_appearance(); - }; - mapper()->setOnPropertyChange(onIntegrationFlagChange, this); -} - -void LatticeItem::update_appearance() -{ - auto angle_item = getItem(P_ROTATION_ANLE); - angle_item->setEnabled(!property<bool>(P_INTEGRATION)); -} - -// ---------------------------------------------------------------------------- - -CylinderItem::CylinderItem() : CompoundItem(GUI::Constants::CylinderItemType) -{ - addProperty(P_RADIUS, 8.0); - addProperty(P_HEIGHT, 10.0); -} - -// ---------------------------------------------------------------------------- - -SphereItem::SphereItem() : CompoundItem(GUI::Constants::SphereItemType) -{ - addProperty(P_RADIUS, 8.0); -} - -// ---------------------------------------------------------------------------- - -AnysoPyramidItem::AnysoPyramidItem() : CompoundItem(GUI::Constants::AnysoPyramidItemType) -{ - addProperty(P_LENGTH, 8.0); - addProperty(P_WIDTH, 8.0); - addProperty(P_HEIGHT, 8.0); - addProperty(P_ALPHA, 8.0); -} - -ShapeGroupItem::ShapeGroupItem() : GroupItem(GUI::Constants::ShapeGroupItemType) -{ - registerItem<CylinderItem>("Cylinder"); - registerItem<SphereItem>("Full sphere", /*make_selected*/ true); - registerItem<AnysoPyramidItem>("Anysotropical pyramid"); - init_group(); -} diff --git a/mvvm/tests/libtestmachinery/toyitems.h b/mvvm/tests/libtestmachinery/toyitems.h deleted file mode 100644 index a9dec15cf9f6720c40de2be58feb74de42a1e74a..0000000000000000000000000000000000000000 --- a/mvvm/tests/libtestmachinery/toyitems.h +++ /dev/null @@ -1,124 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/libtestmachinery/toyitems.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_TESTS_LIBTESTMACHINERY_TOYITEMS_H -#define BORNAGAIN_MVVM_TESTS_LIBTESTMACHINERY_TOYITEMS_H - -#include "mvvm/model/compounditem.h" -#include "mvvm/model/groupitem.h" -#include "mvvm/model/itempool.h" -#include "mvvm/model/sessionmodel.h" -#include <string> - -//! Collection of toy items and models for testing purposes. - -namespace ToyItems::Constants { - -const ModelView::model_type MultiLayerItemType = "MultiLayer"; -const ModelView::model_type LayerItemType = "Layer"; -const ModelView::model_type ParticleItemType = "Particle"; -const ModelView::model_type LatticeItemType = "Lattice"; - -const ModelView::model_type CylinderItemType = "Cylinder"; -const ModelView::model_type SphereItemType = "Sphere"; -const ModelView::model_type AnysoPyramidItemType = "AnysoPyramid"; - -const ModelView::model_type ShapeGroupItemType = "ShapeGroup"; -} // namespace Constants - -//! Represents multilayer with collection of layers. - -class MultiLayerItem : public ModelView::CompoundItem { -public: - static inline const std::string T_LAYERS = "T_LAYERS"; - MultiLayerItem(); -}; - -//! Represents a layer, with thickness and color, and possibly populated with particles. - -class LayerItem : public ModelView::CompoundItem { -public: - static inline const std::string P_THICKNESS = "Thickness"; - static inline const std::string P_COLOR = "Color"; - static inline const std::string T_PARTICLES = "Particles"; - LayerItem(); -}; - -//! Represents a particle, with a position, and a selection of possible shapes. - -class ParticleItem : public ModelView::CompoundItem { -public: - static inline const std::string P_POSITION = "Position"; - static inline const std::string P_SHAPES = "Shapes"; - - ParticleItem(); -}; - -//! Represents a lattice. - -class LatticeItem : public ModelView::CompoundItem { -public: - static inline const std::string P_ROTATION_ANLE = "Rotation"; - static inline const std::string P_INTEGRATION = "Integration"; - static inline const std::string P_LATTICE_TYPE = "Lattice type"; - - LatticeItem(); - - void activate() override; - -private: - void update_appearance(); -}; - -//! Represents a cylindrical shape. - -class CylinderItem : public ModelView::CompoundItem { -public: - static inline const std::string P_RADIUS = "Radius"; - static inline const std::string P_HEIGHT = "Height"; - - CylinderItem(); -}; - -//! Represents a shpere. - -class SphereItem : public ModelView::CompoundItem { -public: - static inline const std::string P_RADIUS = "Radius"; - - SphereItem(); -}; - -//! Represents an anysotropical pyramid. - -class AnysoPyramidItem : public ModelView::CompoundItem { -public: - static inline const std::string P_LENGTH = "Length"; - static inline const std::string P_WIDTH = "Width"; - static inline const std::string P_HEIGHT = "Height"; - static inline const std::string P_ALPHA = "Alpha"; - - AnysoPyramidItem(); -}; - -//! Represents a group item holding a collection of shapes. - -class ShapeGroupItem : public ModelView::GroupItem { -public: - ShapeGroupItem(); -}; - -} // namespace ToyItems - -#endif // BORNAGAIN_MVVM_TESTS_LIBTESTMACHINERY_TOYITEMS_H diff --git a/mvvm/tests/libtestmachinery/toymodel.cpp b/mvvm/tests/libtestmachinery/toymodel.cpp deleted file mode 100644 index 5d028d3a24189c5b8fc75d9a6549d82a6bf41ef3..0000000000000000000000000000000000000000 --- a/mvvm/tests/libtestmachinery/toymodel.cpp +++ /dev/null @@ -1,44 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/libtestmachinery/toymodel.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "toymodel.h" -#include "mvvm/model/itemcatalogue.h" -#include "toyitems.h" - -namespace { -std::unique_ptr<ModelView::ItemCatalogue> CreateItemCatalogue() -{ - auto result = std::make_unique<ModelView::ItemCatalogue>(); - result->registerItem<ToyItems::MultiLayerItem>(); - result->registerItem<ToyItems::LayerItem>(); - result->registerItem<ToyItems::ParticleItem>(); - result->registerItem<ToyItems::LatticeItem>(); - result->registerItem<ToyItems::SphereItem>(); - result->registerItem<ToyItems::CylinderItem>(); - result->registerItem<ToyItems::AnysoPyramidItem>(); - result->registerItem<ToyItems::ShapeGroupItem>(); - return result; -} -} // namespace - -ToyItems::SampleModel::SampleModel() : SessionModel("ToyModel") -{ - setItemCatalogue(CreateItemCatalogue()); -} - -ToyItems::SampleModel::SampleModel(std::shared_ptr<ModelView::ItemPool> pool) - : SessionModel("ToyModel", pool) -{ - setItemCatalogue(CreateItemCatalogue()); -} diff --git a/mvvm/tests/libtestmachinery/toymodel.h b/mvvm/tests/libtestmachinery/toymodel.h deleted file mode 100644 index c41b6e8ad0f4db1e4cfe13c4a5864143a30ad8b3..0000000000000000000000000000000000000000 --- a/mvvm/tests/libtestmachinery/toymodel.h +++ /dev/null @@ -1,33 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/libtestmachinery/toymodel.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_TESTS_LIBTESTMACHINERY_TOYMODEL_H -#define BORNAGAIN_MVVM_TESTS_LIBTESTMACHINERY_TOYMODEL_H - -#include "mvvm/model/itempool.h" -#include "mvvm/model/sessionmodel.h" - -//! Collection of toy items and models for testing purposes. - -namespace ToyItems { - -class SampleModel : public ModelView::SessionModel { -public: - SampleModel(); - SampleModel(std::shared_ptr<ModelView::ItemPool> pool); -}; - -} // namespace ToyItems - -#endif // BORNAGAIN_MVVM_TESTS_LIBTESTMACHINERY_TOYMODEL_H diff --git a/mvvm/tests/libtestmachinery/widgetbasedtest.cpp b/mvvm/tests/libtestmachinery/widgetbasedtest.cpp deleted file mode 100644 index 39f62d5eac8e982f2aba3a129beb4ffed4250ad2..0000000000000000000000000000000000000000 --- a/mvvm/tests/libtestmachinery/widgetbasedtest.cpp +++ /dev/null @@ -1,38 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/libtestmachinery/widgetbasedtest.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "widgetbasedtest.h" -#include <QApplication> - -QApplication* WidgetBasedTest::m_app = nullptr; - -namespace { -// faking argc and argv -char progname[] = "testview"; -char* argv[] = {&progname[0], nullptr}; -int argc = 1; -} // namespace - -WidgetBasedTest::WidgetBasedTest() {} - -void WidgetBasedTest::SetUpTestSuite() -{ - m_app = new QApplication(argc, argv); -} - -void WidgetBasedTest::TearDownTestSuite() -{ - delete m_app; - m_app = 0; -} diff --git a/mvvm/tests/libtestmachinery/widgetbasedtest.h b/mvvm/tests/libtestmachinery/widgetbasedtest.h deleted file mode 100644 index cb92e31183c3096d72fa7f9264b7305c3be442ab..0000000000000000000000000000000000000000 --- a/mvvm/tests/libtestmachinery/widgetbasedtest.h +++ /dev/null @@ -1,36 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/libtestmachinery/widgetbasedtest.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_TESTS_LIBTESTMACHINERY_WIDGETBASEDTEST_H -#define BORNAGAIN_MVVM_TESTS_LIBTESTMACHINERY_WIDGETBASEDTEST_H - -#include <gtest/gtest.h> - -class QApplication; - -//! Convenience class to setup QApplication for tests involving QWidget creation. - -class WidgetBasedTest : public ::testing::Test { -public: - WidgetBasedTest(); - - static void SetUpTestSuite(); - - static void TearDownTestSuite(); - -protected: - static QApplication* m_app; -}; - -#endif // BORNAGAIN_MVVM_TESTS_LIBTESTMACHINERY_WIDGETBASEDTEST_H diff --git a/mvvm/tests/testintegration/CMakeLists.txt b/mvvm/tests/testintegration/CMakeLists.txt deleted file mode 100644 index 8471dad8f4b4b1ad2e63968517c9a221d66b5a2a..0000000000000000000000000000000000000000 --- a/mvvm/tests/testintegration/CMakeLists.txt +++ /dev/null @@ -1,20 +0,0 @@ -set(test testintegration) - -file(GLOB source_files "*.cpp") -file(GLOB include_files "*.h") - -find_package(Qt5Core REQUIRED) -find_package(Qt5Test REQUIRED) - -# necessary for Qt creator and clang code model -include_directories(${gtest_SOURCE_DIR}/include ${gtest_SOURCE_DIR}) - -set(CMAKE_AUTOMOC ON) -add_executable(${test} ${source_files} ${include_files}) -target_link_libraries(${test} gtest gmock Qt5::Core Qt5::Test mvvm_view testmachinery qcustomplot) - -if (MVVM_DISCOVER_TESTS) - gtest_discover_tests(${test}) -else() - add_custom_target(${test}_run ALL DEPENDS ${test} COMMAND ${test}) -endif() diff --git a/mvvm/tests/testintegration/TestAll.cpp b/mvvm/tests/testintegration/TestAll.cpp deleted file mode 100644 index e1ca7ebad8e6fe8ed42af97eef2a29daeb249360..0000000000000000000000000000000000000000 --- a/mvvm/tests/testintegration/TestAll.cpp +++ /dev/null @@ -1,30 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testintegration/TestAll.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "qcustomplot.h" -#include <QApplication> -#include <QStandardItem> - -int main(int argc, char** argv) -{ - ::testing::InitGoogleTest(&argc, argv); - - ModelView::Comparators::registerComparators(); - - QApplication app(argc, argv); - Q_UNUSED(app) - - return RUN_ALL_TESTS(); -} diff --git a/mvvm/tests/testintegration/standarditemserialization.test.cpp b/mvvm/tests/testintegration/standarditemserialization.test.cpp deleted file mode 100644 index bed05bcb370a3342f61d68fa76437b1db92796ca..0000000000000000000000000000000000000000 --- a/mvvm/tests/testintegration/standarditemserialization.test.cpp +++ /dev/null @@ -1,125 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testintegration/standarditemserialization.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/model/modelutils.h" -#include "mvvm/serialization/jsonmodelconverter.h" -#include "mvvm/standarditems/standarditemincludes.h" -#include <QDebug> -#include <QJsonObject> - -using namespace ModelView; - -//! Testing serialization of ToyItems using json converters. - -class StandardItemsSerializationTest : public ::testing::Test { -public: - ~StandardItemsSerializationTest(); -}; - -StandardItemsSerializationTest::~StandardItemsSerializationTest() = default; - -//! Checking that serialization works (not crashing) for all defined standard items. - -TEST_F(StandardItemsSerializationTest, allItems) -{ - SessionModel model; - model.insertItem<ColorMapItem>(); - model.insertItem<ColorMapViewportItem>(); - model.insertItem<CompoundItem>(); - model.insertItem<ContainerItem>(); - model.insertItem<Data1DItem>(); - model.insertItem<Data2DItem>(); - model.insertItem<FixedBinAxisItem>(); - model.insertItem<GraphItem>(); - model.insertItem<GraphViewportItem>(); - model.insertItem<LinkedItem>(); - model.insertItem<PenItem>(); - model.insertItem<PointwiseAxisItem>(); - model.insertItem<PropertyItem>(); - model.insertItem<SessionItem>(); - model.insertItem<TextItem>(); - model.insertItem<VectorItem>(); - model.insertItem<ViewportAxisItem>(); - - auto modelCopy = Utils::CreateCopy(model); - EXPECT_EQ(model.rootItem()->childrenCount(), modelCopy->rootItem()->childrenCount()); -} - -//! Creating graph with data. It has to be identical after serialization. - -TEST_F(StandardItemsSerializationTest, GraphItemAndDataSerialization) -{ - // preparing model, data item and graph pointing to it - SessionModel model; - auto graph_item = model.insertItem<GraphItem>(); - auto data_item = model.insertItem<Data1DItem>(); - const std::vector<double> expected_values = {1.0, 2.0, 3.0}; - const std::vector<double> expected_centers = {0.5, 1.5, 2.5}; - data_item->setAxis<FixedBinAxisItem>(3, 0.0, 3.0); - data_item->setValues(expected_values); - graph_item->setDataItem(data_item); - - // accessing copied items - auto modelClone = Utils::CreateClone(model); - EXPECT_EQ(model.rootItem()->childrenCount(), modelClone->rootItem()->childrenCount()); - - auto graphClone = modelClone->topItem<GraphItem>(); - auto dataClone = modelClone->topItem<Data1DItem>(); - - // analyzing copies - EXPECT_EQ(graphClone->dataItem(), dataClone); - EXPECT_EQ(dataClone->binCenters(), expected_centers); - EXPECT_EQ(dataClone->binValues(), expected_values); -} - -//! Creating viewport with one graph. Serializing and restoring the model. - -TEST_F(StandardItemsSerializationTest, graphViewPortItemSerialization) -{ - SessionModel model; - auto viewport_item = model.insertItem<GraphViewportItem>(); - auto graph_item = model.insertItem<GraphItem>(viewport_item); - auto data_item = model.insertItem<Data1DItem>(); - - const std::vector<double> expected_values = {1.0, 2.0, 3.0}; - const std::vector<double> expected_centers = {0.5, 1.5, 2.5}; - data_item->setAxis<FixedBinAxisItem>(3, 0.0, 3.0); - data_item->setValues(expected_values); - - graph_item->setDataItem(data_item); - EXPECT_EQ(viewport_item->graphItems().size(), 1); - - // updating viewport to graph - viewport_item->setViewportToContent(); - - // accessing cloned items - auto modelClone = Utils::CreateClone(model); - EXPECT_EQ(model.rootItem()->childrenCount(), modelClone->rootItem()->childrenCount()); - auto viewportCopy = modelClone->topItem<GraphViewportItem>(); - ASSERT_EQ(viewportCopy->graphItems().size(), 1); - auto graphClone = viewportCopy->graphItems().at(0); - auto dataClone = modelClone->topItem<Data1DItem>(); - - // analyzing clones - EXPECT_EQ(graphClone->dataItem(), dataClone); - EXPECT_EQ(graphClone->dataItem(), dataClone); - EXPECT_EQ(dataClone->binCenters(), expected_centers); - EXPECT_EQ(dataClone->binValues(), expected_values); - - EXPECT_DOUBLE_EQ(viewportCopy->xAxis()->property<double>(ViewportAxisItem::P_MIN), - expected_centers[0]); - EXPECT_DOUBLE_EQ(viewportCopy->xAxis()->property<double>(ViewportAxisItem::P_MAX), - expected_centers[2]); -} diff --git a/mvvm/tests/testintegration/toyitemslattice.test.cpp b/mvvm/tests/testintegration/toyitemslattice.test.cpp deleted file mode 100644 index 90c7c67d3fedee0eef2eb71f969cdc3bf214fae2..0000000000000000000000000000000000000000 --- a/mvvm/tests/testintegration/toyitemslattice.test.cpp +++ /dev/null @@ -1,45 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testintegration/toyitemslattice.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "toyitems.h" -#include "toymodel.h" - -using namespace ModelView; -using namespace ToyItems; - -//! Test toy LatticeItem. - -class ToyItemsLatticeTest : public ::testing::Test { -public: - ~ToyItemsLatticeTest(); -}; - -ToyItemsLatticeTest::~ToyItemsLatticeTest() = default; - -//! Business logice (enabled/disabled). - -TEST_F(ToyItemsLatticeTest, ToyItemsLatticeTest) -{ - ToyItems::SampleModel model; - auto lattice = model.insertItem<LatticeItem>(); - - // by default integration flag is ON, rotation angle is disabled - EXPECT_TRUE(lattice->property<bool>(LatticeItem::P_INTEGRATION)); - EXPECT_FALSE(lattice->getItem(LatticeItem::P_ROTATION_ANLE)->isEnabled()); - - // switching integration OFF, checking that rotation is enabled - lattice->setProperty(LatticeItem::P_INTEGRATION, false); - EXPECT_TRUE(lattice->getItem(LatticeItem::P_ROTATION_ANLE)->isEnabled()); -} diff --git a/mvvm/tests/testintegration/toyitemsserialization.test.cpp b/mvvm/tests/testintegration/toyitemsserialization.test.cpp deleted file mode 100644 index 4ba387e02235f148aae1db2c6e42ffdf677ad1da..0000000000000000000000000000000000000000 --- a/mvvm/tests/testintegration/toyitemsserialization.test.cpp +++ /dev/null @@ -1,94 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testintegration/toyitemsserialization.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/model/modelutils.h" -#include "mvvm/serialization/jsonmodelconverter.h" -#include "toyitems.h" -#include "toymodel.h" -#include <QJsonObject> - -using namespace ModelView; -using namespace ToyItems; - -//! Testing serialization of ToyItems using json converters. - -class ToyItemsSerializationTest : public ::testing::Test { -public: - ~ToyItemsSerializationTest(); -}; - -ToyItemsSerializationTest::~ToyItemsSerializationTest() = default; - -//! Checking ShapeGroupItem in a model. -//! Serialization/deserelization should give an item identical to original. - -TEST_F(ToyItemsSerializationTest, defaultShapeGroupItemInModel) -{ - // model with single group item - SampleModel model; - auto group = model.insertItem<ShapeGroupItem>(); - - // copy of model - auto modelCopy = Utils::CreateCopy(model); - auto groupCopy = modelCopy->topItem<ShapeGroupItem>(); - - // basic properties in copied item should be the same - EXPECT_EQ(group->currentIndex(), groupCopy->currentIndex()); - EXPECT_EQ(group->currentItem()->modelType(), groupCopy->currentItem()->modelType()); -} - -//! Checking ShapeGroupItem in a model. -//! Serialization/deserelization should give an item identical to original. - -TEST_F(ToyItemsSerializationTest, modifiedShapeGroupItemInModel) -{ - SampleModel model; - auto group = model.insertItem<ShapeGroupItem>(); - - // modifying group item - group->setCurrentType(ToyItems::GUI::Constants::AnysoPyramidItemType); - group->children().at(0)->setProperty(CylinderItem::P_RADIUS, 42.0); - group->children().at(1)->setProperty(SphereItem::P_RADIUS, 43.0); - group->children().at(2)->setProperty(AnysoPyramidItem::P_LENGTH, 44.0); - - // creating copy - auto modelCopy = Utils::CreateCopy(model); - auto groupCopy = modelCopy->topItem<ShapeGroupItem>(); - - // checking properties of - EXPECT_EQ(groupCopy->currentIndex(), group->currentIndex()); - EXPECT_EQ(groupCopy->currentItem()->modelType(), group->currentItem()->modelType()); - EXPECT_EQ(groupCopy->children().at(0)->property<double>(CylinderItem::P_RADIUS), 42.0); - EXPECT_EQ(groupCopy->children().at(1)->property<double>(SphereItem::P_RADIUS), 43.0); - EXPECT_EQ(groupCopy->children().at(2)->property<double>(AnysoPyramidItem::P_LENGTH), 44.0); -} - -//! Insert all supported items in a model and check that after serialization - -TEST_F(ToyItemsSerializationTest, allItemsInAModel) -{ - SampleModel model; - model.insertItem<ToyItems::MultiLayerItem>(); - model.insertItem<ToyItems::LayerItem>(); - model.insertItem<ToyItems::ParticleItem>(); - model.insertItem<ToyItems::LatticeItem>(); - model.insertItem<ToyItems::SphereItem>(); - model.insertItem<ToyItems::CylinderItem>(); - model.insertItem<ToyItems::AnysoPyramidItem>(); - model.insertItem<ToyItems::ShapeGroupItem>(); - - auto modelCopy = Utils::CreateCopy(model); - EXPECT_EQ(model.rootItem()->childrenCount(), modelCopy->rootItem()->childrenCount()); -} diff --git a/mvvm/tests/testintegration/toyitemsshapegroup.test.cpp b/mvvm/tests/testintegration/toyitemsshapegroup.test.cpp deleted file mode 100644 index af4a51275aa175fdf986883c1000c5fccf75cb0c..0000000000000000000000000000000000000000 --- a/mvvm/tests/testintegration/toyitemsshapegroup.test.cpp +++ /dev/null @@ -1,288 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testintegration/toyitemsshapegroup.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/model/comboproperty.h" -#include "mvvm/viewmodel/defaultviewmodel.h" -#include "mvvm/viewmodel/propertyviewmodel.h" -#include "mvvm/viewmodel/standardviewitems.h" -#include "toyitems.h" -#include "toymodel.h" -#include <QSignalSpy> - -using namespace ModelView; - -//! Tests of toy ShapeGroup in the context of model and viewmodel. - -class ToyItemsShapeGroupTest : public ::testing::Test { -public: - ~ToyItemsShapeGroupTest(); -}; - -ToyItemsShapeGroupTest::~ToyItemsShapeGroupTest() = default; - -//! Toy multilayer as produced bo toy SampleModel. - -TEST_F(ToyItemsShapeGroupTest, initialState) -{ - ToyItems::ShapeGroupItem item; - - EXPECT_EQ(item.currentIndex(), 1); - ASSERT_TRUE(item.currentItem() != nullptr); - EXPECT_TRUE(item.data<QVariant>().isValid()); - EXPECT_EQ(item.currentType(), item.currentItem()->modelType()); - EXPECT_EQ(item.currentType(), ToyItems::GUI::Constants::SphereItemType); - ASSERT_EQ(item.children().size(), 3); - - // parent child relationship - EXPECT_EQ(item.children().at(0)->parent(), &item); - EXPECT_EQ(item.children().at(1)->parent(), &item); - EXPECT_EQ(item.children().at(2)->parent(), &item); - - // expected value in combo - ComboProperty combo = item.data<ComboProperty>(); - EXPECT_EQ(combo.currentIndex(), 1); - EXPECT_EQ(combo.values(), - std::vector<std::string>({"Cylinder", "Full sphere", "Anysotropical pyramid"})); -} - -TEST_F(ToyItemsShapeGroupTest, setCurrentType) -{ - ToyItems::ShapeGroupItem item; - item.setCurrentType(ToyItems::GUI::Constants::CylinderItemType); - - EXPECT_EQ(item.currentIndex(), 0); - ASSERT_TRUE(item.currentItem() != nullptr); - EXPECT_EQ(item.currentType(), item.currentItem()->modelType()); - EXPECT_EQ(item.currentItem()->modelType(), ToyItems::GUI::Constants::CylinderItemType); - EXPECT_TRUE(item.data<QVariant>().isValid()); - EXPECT_EQ(item.children().size(), 3); - - // expected value in combo - ComboProperty combo = item.data<ComboProperty>(); - EXPECT_EQ(combo.currentIndex(), 0); - EXPECT_EQ(combo.values(), - std::vector<std::string>({"Cylinder", "Full sphere", "Anysotropical pyramid"})); -} - -TEST_F(ToyItemsShapeGroupTest, currentItemNoConst) -{ - ToyItems::ShapeGroupItem item; - item.currentItem()->setProperty(ToyItems::SphereItem::P_RADIUS, 42.0); - EXPECT_EQ(item.currentItem()->property<double>(ToyItems::SphereItem::P_RADIUS), 42.0); -} - -TEST_F(ToyItemsShapeGroupTest, inModelContext) -{ - ToyItems::SampleModel model; - auto item = model.insertItem<ToyItems::ShapeGroupItem>(); - ASSERT_TRUE(item != nullptr); - - EXPECT_EQ(item->currentIndex(), 1); - ASSERT_TRUE(item->currentItem() != nullptr); - EXPECT_TRUE(item->data<QVariant>().isValid()); - EXPECT_EQ(item->currentType(), item->currentItem()->modelType()); - EXPECT_EQ(item->children().size(), 3); - - // parent child relationship - EXPECT_EQ(item->children().at(0)->parent(), item); - EXPECT_EQ(item->children().at(1)->parent(), item); - EXPECT_EQ(item->children().at(2)->parent(), item); - - // model relationship - EXPECT_EQ(item->children().at(0)->model(), &model); - EXPECT_EQ(item->children().at(1)->model(), &model); - EXPECT_EQ(item->children().at(2)->model(), &model); -} - -TEST_F(ToyItemsShapeGroupTest, setDataInModelContext) -{ - ToyItems::SampleModel model; - auto item = model.insertItem<ToyItems::ShapeGroupItem>(); - ASSERT_TRUE(item != nullptr); - - // initial status - EXPECT_EQ(item->currentIndex(), 1); - EXPECT_EQ(item->currentType(), ToyItems::GUI::Constants::SphereItemType); - ComboProperty combo = model.data(item, ItemDataRole::DATA).value<ComboProperty>(); - EXPECT_EQ(combo.currentIndex(), 1); - - // setting through combo - combo.setCurrentIndex(0); - model.setData(item, QVariant::fromValue(combo), ItemDataRole::DATA); - - EXPECT_EQ(item->currentIndex(), 0); - EXPECT_EQ(item->currentType(), ToyItems::GUI::Constants::CylinderItemType); -} - -//! ViewLabelItem and ViewDataItem from ShapeItem. - -TEST_F(ToyItemsShapeGroupTest, viewItemsFromShapeGroup) -{ - ToyItems::SampleModel model; - - auto groupItem = model.insertItem<ToyItems::ShapeGroupItem>(); - - ViewLabelItem labelItem(groupItem); - EXPECT_EQ(labelItem.data(Qt::DisplayRole).toString().toStdString(), - ToyItems::GUI::Constants::ShapeGroupItemType); - - ViewDataItem dataItem(groupItem); - EXPECT_EQ(dataItem.data(Qt::DisplayRole).value<ComboProperty>().currentIndex(), 1); -} - -//! ShapeGroup item in DefaultViewModel. - -TEST_F(ToyItemsShapeGroupTest, inDefaultViewModelContext) -{ - ToyItems::SampleModel model; - auto groupItem = model.insertItem<ToyItems::ShapeGroupItem>(); - - // constructing viewModel from sample model - DefaultViewModel viewModel(&model); - - // root item should have one child, item looking at our groupItem - EXPECT_EQ(viewModel.rowCount(), 1); - EXPECT_EQ(viewModel.columnCount(), 2); - - // accessing to viewItem representing groupItem - QModelIndex groupIndex = viewModel.index(0, 0); - EXPECT_EQ(viewModel.sessionItemFromIndex(groupIndex), groupItem); - EXPECT_EQ(viewModel.columnCount(groupIndex), 2); - EXPECT_EQ(viewModel.rowCount(groupIndex), 3); // Cylinder, Sphere, Anysopyramid - - // setting up signal spy - QSignalSpy spyRemove(&viewModel, &DefaultViewModel::rowsRemoved); - QSignalSpy spyInsert(&viewModel, &DefaultViewModel::rowsInserted); - QSignalSpy spyData(&viewModel, &DefaultViewModel::dataChanged); - - // changing the data - ComboProperty combo = model.data(groupItem, ItemDataRole::DATA).value<ComboProperty>(); - combo.setCurrentIndex(0); - model.setData(groupItem, QVariant::fromValue(combo), ItemDataRole::DATA); - - // expectances - EXPECT_EQ(spyRemove.count(), 0); - EXPECT_EQ(spyInsert.count(), 0); - EXPECT_EQ(spyData.count(), 1); - - // what signal reports - QList<QVariant> arguments = spyData.takeFirst(); - QModelIndex dataIndex = viewModel.index(0, 1); - EXPECT_EQ(arguments.size(), 3); // QModelIndex left, QModelIndex right, QVector<int> roles - EXPECT_EQ(arguments.at(0).value<QModelIndex>(), dataIndex); - EXPECT_EQ(arguments.at(1).value<QModelIndex>(), dataIndex); - QVector<int> expectedRoles = {Qt::DisplayRole, Qt::EditRole}; - EXPECT_EQ(arguments.at(2).value<QVector<int>>(), expectedRoles); - - // same layout - groupIndex = viewModel.index(0, 0); - EXPECT_EQ(viewModel.sessionItemFromIndex(groupIndex), groupItem); - EXPECT_EQ(viewModel.columnCount(groupIndex), 2); - EXPECT_EQ(viewModel.rowCount(groupIndex), 3); // Cylinder, Sphere, Anysopyramid -} - -//! ShapeGroup item in PropertyViewModel. - -TEST_F(ToyItemsShapeGroupTest, inPropertyViewModelContext) -{ - ToyItems::SampleModel model; - auto parent = model.insertItem<SessionItem>(); - parent->registerTag( - TagInfo::propertyTag("property_tag", ToyItems::GUI::Constants::ShapeGroupItemType)); - - auto groupItem = model.insertItem<ToyItems::ShapeGroupItem>(parent, "property_tag"); - ASSERT_TRUE(groupItem != nullptr); - - // constructing viewModel from sample model - PropertyViewModel viewModel(&model); - viewModel.setRootSessionItem(parent); - - // root item should have one child, item looking at our groupItem - EXPECT_EQ(viewModel.rowCount(), 1); - EXPECT_EQ(viewModel.columnCount(), 2); - - // accessing to viewItem representing groupItem - QModelIndex groupIndex = viewModel.index(0, 0); - EXPECT_EQ(viewModel.sessionItemFromIndex(groupIndex), groupItem); - - // There is only one row under groupItem, representing radius of Sphere - EXPECT_EQ(viewModel.columnCount(groupIndex), 2); - EXPECT_EQ(viewModel.rowCount(groupIndex), 1); // Radius of sphere - - // ViewLabelItem and ViewDataItem should look at propertyItem corresponding to sphere - { - QModelIndex radiusLabelIndex = viewModel.index(0, 0, groupIndex); - QModelIndex radiusValueIndex = viewModel.index(0, 1, groupIndex); - auto radiusLabelItem = - dynamic_cast<ViewLabelItem*>(viewModel.itemFromIndex(radiusLabelIndex)); - ASSERT_TRUE(radiusLabelItem != nullptr); - auto radiusPropertyItem = groupItem->currentItem()->getItem(ToyItems::SphereItem::P_RADIUS); - EXPECT_EQ(radiusLabelItem->item(), radiusPropertyItem); - auto radiusValueItem = - dynamic_cast<ViewDataItem*>(viewModel.itemFromIndex(radiusValueIndex)); - ASSERT_TRUE(radiusValueItem != nullptr); - EXPECT_EQ(radiusValueItem->item(), radiusPropertyItem); - } - - // setting up signal spy - QSignalSpy spyRemove(&viewModel, &DefaultViewModel::rowsRemoved); - QSignalSpy spyInsert(&viewModel, &DefaultViewModel::rowsInserted); - QSignalSpy spyData(&viewModel, &DefaultViewModel::dataChanged); - - // changing the data (now GroupItem's current item changed from Sphere to Cylinder - ComboProperty combo = model.data(groupItem, ItemDataRole::DATA).value<ComboProperty>(); - combo.setCurrentIndex(0); - model.setData(groupItem, QVariant::fromValue(combo), ItemDataRole::DATA); - - EXPECT_EQ(viewModel.columnCount(groupIndex), 2); - EXPECT_EQ(viewModel.rowCount(groupIndex), 2); // Radius and Height of cylinder - - // Checking ViewLabelItem and ViewDataItem corresponding to Cylinder's radius - { - QModelIndex radiusLabelIndex = viewModel.index(0, 0, groupIndex); - QModelIndex radiusValueIndex = viewModel.index(0, 1, groupIndex); - auto radiusLabelItem = - dynamic_cast<ViewLabelItem*>(viewModel.itemFromIndex(radiusLabelIndex)); - ASSERT_TRUE(radiusLabelItem != nullptr); - auto radiusPropertyItem = - groupItem->currentItem()->getItem(ToyItems::CylinderItem::P_RADIUS); - EXPECT_EQ(radiusLabelItem->item(), radiusPropertyItem); - auto radiusValueItem = - dynamic_cast<ViewDataItem*>(viewModel.itemFromIndex(radiusValueIndex)); - ASSERT_TRUE(radiusValueItem != nullptr); - EXPECT_EQ(radiusValueItem->item(), radiusPropertyItem); - } - - // Checking ViewLabelItem and ViewDataItem corresponding to Cylinder's height - { - QModelIndex heightLabelIndex = viewModel.index(1, 0, groupIndex); - QModelIndex heightValueIndex = viewModel.index(1, 1, groupIndex); - auto heightLabelItem = - dynamic_cast<ViewLabelItem*>(viewModel.itemFromIndex(heightLabelIndex)); - ASSERT_TRUE(heightLabelItem != nullptr); - auto heightPropertyItem = - groupItem->currentItem()->getItem(ToyItems::CylinderItem::P_HEIGHT); - EXPECT_EQ(heightLabelItem->item(), heightPropertyItem); - auto heightValueItem = - dynamic_cast<ViewDataItem*>(viewModel.itemFromIndex(heightValueIndex)); - ASSERT_TRUE(heightPropertyItem != nullptr); - EXPECT_EQ(heightValueItem->item(), heightPropertyItem); - } - - // expectances - EXPECT_EQ(spyRemove.count(), 1); - EXPECT_EQ(spyInsert.count(), 2); - EXPECT_EQ(spyData.count(), 1); -} diff --git a/mvvm/tests/testintegration/undoscenario.test.cpp b/mvvm/tests/testintegration/undoscenario.test.cpp deleted file mode 100644 index c32bec991c9d31051f5a3993f8230ac240ea11b3..0000000000000000000000000000000000000000 --- a/mvvm/tests/testintegration/undoscenario.test.cpp +++ /dev/null @@ -1,85 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testintegration/undoscenario.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/interfaces/undostackinterface.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/plotting/viewportaxisplotcontroller.h" -#include "mvvm/standarditems/axisitems.h" -#include "qcustomplot.h" - -using namespace ModelView; - -//! Testing various undo/redo scenario. - -class UndoScenarioTest : public ::testing::Test { -public: - ~UndoScenarioTest(); -}; - -UndoScenarioTest::~UndoScenarioTest() = default; - -//! Check undo/redo of ViewportAxisItem range, when it is listened by the controller. -//! Real-life bug. - -TEST_F(UndoScenarioTest, undoViewportSetRange) -{ - // initialzing model, custom plot and controller - SessionModel model; - auto axisItem = model.insertItem<ViewportAxisItem>(); - axisItem->setProperty(ViewportAxisItem::P_MIN, 1.0); - axisItem->setProperty(ViewportAxisItem::P_MAX, 2.0); - QCustomPlot custom_plot; - ViewportAxisPlotController controller(custom_plot.xAxis); - controller.setItem(axisItem); - - // initial axis state - EXPECT_EQ(custom_plot.xAxis->range().lower, 1.0); - EXPECT_EQ(custom_plot.xAxis->range().upper, 2.0); - - // enabling undo/redo, and its initial state - model.setUndoRedoEnabled(true); - auto stack = model.undoStack(); - EXPECT_FALSE(stack->canRedo()); - EXPECT_FALSE(stack->canUndo()); - EXPECT_EQ(stack->index(), 0); - EXPECT_EQ(stack->count(), 0); - - // changing axis - axisItem->setProperty(ViewportAxisItem::P_MAX, 20.0); - EXPECT_FALSE(stack->canRedo()); - EXPECT_TRUE(stack->canUndo()); - EXPECT_EQ(stack->index(), 1); - EXPECT_EQ(stack->count(), 1); - EXPECT_EQ(custom_plot.xAxis->range().lower, 1.0); - EXPECT_EQ(custom_plot.xAxis->range().upper, 20.0); - - // undoing - stack->undo(); - EXPECT_TRUE(stack->canRedo()); - EXPECT_FALSE(stack->canUndo()); - EXPECT_EQ(stack->index(), 0); - EXPECT_EQ(stack->count(), 1); - EXPECT_EQ(custom_plot.xAxis->range().lower, 1.0); - EXPECT_EQ(custom_plot.xAxis->range().upper, 2.0); - - // redoing - stack->redo(); - EXPECT_FALSE(stack->canRedo()); - EXPECT_TRUE(stack->canUndo()); - EXPECT_EQ(stack->index(), 1); - EXPECT_EQ(stack->count(), 1); - EXPECT_EQ(custom_plot.xAxis->range().lower, 1.0); - EXPECT_EQ(custom_plot.xAxis->range().upper, 20.0); -} diff --git a/mvvm/tests/testmodel/CMakeLists.txt b/mvvm/tests/testmodel/CMakeLists.txt deleted file mode 100644 index dbf904932c8170a4247723e70705007e24cb67b3..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/CMakeLists.txt +++ /dev/null @@ -1,20 +0,0 @@ -set(test testmodel) - -file(GLOB source_files "*.cpp") -file(GLOB include_files "*.h") - -find_package(Qt5Core REQUIRED) -find_package(Qt5Test REQUIRED) - -# necessary for Qt creator and clang code model -include_directories(${gtest_SOURCE_DIR}/include ${gtest_SOURCE_DIR}) - -set(CMAKE_AUTOMOC ON) -add_executable(${test} ${source_files} ${include_files}) -target_link_libraries(${test} gtest gmock Qt5::Core Qt5::Test mvvm_model testmachinery) - -if (MVVM_DISCOVER_TESTS) - gtest_discover_tests(${test}) -else() - add_custom_target(${test}_run ALL DEPENDS ${test} COMMAND ${test}) -endif() diff --git a/mvvm/tests/testmodel/TestAll.cpp b/mvvm/tests/testmodel/TestAll.cpp deleted file mode 100644 index a18379681c4ae34c4a654e70818c9c1d61263793..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/TestAll.cpp +++ /dev/null @@ -1,27 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/TestAll.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include <gmock/gmock.h> - -int main(int argc, char** argv) -{ - ::testing::InitGoogleTest(&argc, argv); - ::testing::InitGoogleMock(&argc, argv); - - ModelView::Comparators::registerComparators(); - - // run all google tests - return RUN_ALL_TESTS(); -} diff --git a/mvvm/tests/testmodel/axisitems.test.cpp b/mvvm/tests/testmodel/axisitems.test.cpp deleted file mode 100644 index b170adef4dc48842e91df552b8f17d946d942d14..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/axisitems.test.cpp +++ /dev/null @@ -1,135 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/axisitems.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/standarditems/axisitems.h" - -using namespace ModelView; - -//! Testing AxisItems. - -class AxisItemsTest : public ::testing::Test { -public: - ~AxisItemsTest(); -}; - -AxisItemsTest::~AxisItemsTest() = default; - -//! Initial state - -TEST_F(AxisItemsTest, viewportAxisInitialState) -{ - ViewportAxisItem axis; - EXPECT_EQ(axis.property<double>(ViewportAxisItem::P_MIN), 0.0); - EXPECT_EQ(axis.property<double>(ViewportAxisItem::P_MAX), 1.0); - EXPECT_FALSE(axis.property<bool>(ViewportAxisItem::P_IS_LOG)); -} - -//! ViewportAxisItem::setRange - -TEST_F(AxisItemsTest, viewportAxisSetRange) -{ - ViewportAxisItem axis; - - // default range - auto [lower, upper] = axis.range(); - EXPECT_EQ(lower, 0.0); - EXPECT_EQ(upper, 1.0); - - axis.set_range(1.0, 2.0); - EXPECT_EQ(axis.property<double>(ViewportAxisItem::P_MIN), 1.0); - EXPECT_EQ(axis.property<double>(ViewportAxisItem::P_MAX), 2.0); -} - -//! Factory method for FixedBinAxisItem. - -TEST_F(AxisItemsTest, fixedBinAxisInitialState) -{ - FixedBinAxisItem axis; - EXPECT_EQ(axis.property<double>(FixedBinAxisItem::P_MIN), 0.0); - EXPECT_EQ(axis.property<double>(FixedBinAxisItem::P_MAX), 1.0); - EXPECT_EQ(axis.property<int>(FixedBinAxisItem::P_NBINS), 1); - EXPECT_EQ(axis.binCenters(), std::vector<double>{0.5}); - EXPECT_EQ(axis.size(), 1); - auto [lower, upper] = axis.range(); - EXPECT_EQ(lower, 0.0); - EXPECT_EQ(upper, 1.0); -} - -//! Factory method for FixedBinAxisItem. - -TEST_F(AxisItemsTest, fixedBinAxisSetParameters) -{ - FixedBinAxisItem axis; - axis.setParameters(3, 1.0, 4.0); - - EXPECT_EQ(axis.property<int>(FixedBinAxisItem::P_NBINS), 3); - EXPECT_EQ(axis.property<double>(FixedBinAxisItem::P_MIN), 1.0); - EXPECT_EQ(axis.property<double>(FixedBinAxisItem::P_MAX), 4.0); - - std::vector<double> expected{1.5, 2.5, 3.5}; - EXPECT_EQ(axis.binCenters(), expected); - EXPECT_EQ(axis.size(), 3); -} - -//! Factory method for FixedBinAxisItem. - -TEST_F(AxisItemsTest, fixedBinAxisFactory) -{ - auto axis = FixedBinAxisItem::create(3, 1.0, 4.0); - - EXPECT_EQ(axis->property<int>(FixedBinAxisItem::P_NBINS), 3); - EXPECT_EQ(axis->property<double>(FixedBinAxisItem::P_MIN), 1.0); - EXPECT_EQ(axis->property<double>(FixedBinAxisItem::P_MAX), 4.0); - - std::vector<double> expected{1.5, 2.5, 3.5}; - EXPECT_EQ(axis->binCenters(), expected); - EXPECT_EQ(axis->size(), 3); -} - -//! Range method. - -TEST_F(AxisItemsTest, fixedBinAxisRange) -{ - auto axis = FixedBinAxisItem::create(3, 1.0, 4.0); - - auto [lower, upper] = axis->range(); - EXPECT_EQ(lower, 1.0); - EXPECT_EQ(upper, 4.0); -} - -TEST_F(AxisItemsTest, PointwiseAxisInitialState) -{ - PointwiseAxisItem axis; - std::vector<double> expected_centers = {0.0, 1.0}; - EXPECT_EQ(axis.binCenters(), expected_centers); - EXPECT_EQ(axis.size(), 2); -} - -TEST_F(AxisItemsTest, PointwiseAxisSetParameters) -{ - std::vector<double> expected_centers{1.0, 2.0, 3.0}; - PointwiseAxisItem axis; - axis.setParameters(expected_centers); - EXPECT_EQ(axis.binCenters(), expected_centers); - EXPECT_EQ(axis.size(), 3); -} - -TEST_F(AxisItemsTest, PointwiseAxisCreate) -{ - std::vector<double> expected_centers{1.0, 2.0, 3.0}; - auto axis = PointwiseAxisItem::create(expected_centers); - EXPECT_EQ(axis->binCenters(), expected_centers); - EXPECT_EQ(axis->size(), 3); -} diff --git a/mvvm/tests/testmodel/binutils.test.cpp b/mvvm/tests/testmodel/binutils.test.cpp deleted file mode 100644 index 7d78d6eb41fe645f52f3265e50f8d268a07ad564..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/binutils.test.cpp +++ /dev/null @@ -1,69 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/binutils.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/utils/binutils.h" -#include <testconfig.h> - -using namespace ModelView; - -//! Testing BinUtils - -class BinUtilsTest : public ::testing::Test { -public: - ~BinUtilsTest(); -}; - -BinUtilsTest::~BinUtilsTest() = default; - -//! Testing Binary Files - -TEST_F(BinUtilsTest, testBinaryFiles) -{ - std::string root_path = TestConfig::TestData(); - - std::string binary_file1 = root_path + std::string("/") + "pdf_file"; - std::string binary_file2 = root_path + std::string("/") + "png_file.png"; - std::string binary_file3 = root_path + std::string("/") + "word_file"; - std::string binary_file4 = root_path + std::string("/") + "mandelbrot.ppm"; - std::string binary_file5 = root_path + std::string("/") + "c++_exec"; - - EXPECT_TRUE(Utils::is_binary(binary_file1)); - EXPECT_TRUE(Utils::is_binary(binary_file2)); - EXPECT_TRUE(Utils::is_binary(binary_file3)); - EXPECT_TRUE(Utils::is_binary(binary_file4)); - EXPECT_TRUE(Utils::is_binary(binary_file5)); - - EXPECT_FALSE(Utils::is_text(binary_file1)); - EXPECT_FALSE(Utils::is_text(binary_file2)); - EXPECT_FALSE(Utils::is_text(binary_file3)); - EXPECT_FALSE(Utils::is_text(binary_file4)); - EXPECT_FALSE(Utils::is_text(binary_file5)); -} - -//! Testing text files - -TEST_F(BinUtilsTest, testTextFiles) -{ - std::string root_path = TestConfig::TestData(); - - std::string text_file1 = root_path + std::string("/") + "text_UTF-8.txt"; - std::string text_file2 = root_path + std::string("/") + "text_UTF-8-BOM.txt"; - - EXPECT_TRUE(Utils::is_text(text_file1)); - EXPECT_TRUE(Utils::is_text(text_file2)); - - EXPECT_FALSE(Utils::is_binary(text_file1)); - EXPECT_FALSE(Utils::is_binary(text_file2)); -} \ No newline at end of file diff --git a/mvvm/tests/testmodel/callbackcontainer.test.cpp b/mvvm/tests/testmodel/callbackcontainer.test.cpp deleted file mode 100644 index 1b29372e8ef5559dc52cc66f51f112042a396c2b..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/callbackcontainer.test.cpp +++ /dev/null @@ -1,114 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/callbackcontainer.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mockwidgets.h" -#include "mvvm/model/mvvm_types.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/signals/callbackcontainer.h" -#include <memory> - -using namespace ModelView; -using ::testing::_; - -//! Testing CallbackContainer class. - -class CallbackContainerTest : public ::testing::Test { -public: - ~CallbackContainerTest(); -}; - -CallbackContainerTest::~CallbackContainerTest() = default; - -//! Callback container notifies single widget. Check if removal of widget disables notifications. - -TEST_F(CallbackContainerTest, singleWidget) -{ - CallbackMockWidget widget; - Signal<Callbacks::item_t> signal; - - signal.connect(std::bind(&CallbackMockWidget::onItemDestroy, &widget, std::placeholders::_1), - &widget); - - std::unique_ptr<SessionItem> item(new SessionItem); - EXPECT_CALL(widget, onItemDestroy(item.get())).Times(1); - - // perform action - signal(item.get()); - - // removing client - signal.remove_client(&widget); - EXPECT_CALL(widget, onItemDestroy(_)).Times(0); - - // perform action - signal(item.get()); -} - -//! Callback container notifies two widgets. Check if one widget is removed, -//! the second is still notified. - -TEST_F(CallbackContainerTest, twoWidgets) -{ - CallbackMockWidget widget1, widget2; - Signal<Callbacks::item_t> signal; - - signal.connect([&](SessionItem* item) { widget1.onItemDestroy(item); }, &widget1); - - signal.connect([&](SessionItem* item) { widget2.onItemDestroy(item); }, &widget2); - - std::unique_ptr<SessionItem> item(new SessionItem); - EXPECT_CALL(widget1, onItemDestroy(item.get())).Times(1); - EXPECT_CALL(widget2, onItemDestroy(item.get())).Times(1); - - // perform action - signal(item.get()); - - // removing one of client - signal.remove_client(&widget1); - EXPECT_CALL(widget1, onItemDestroy(_)).Times(0); - EXPECT_CALL(widget2, onItemDestroy(item.get())).Times(1); - - // perform action - signal(item.get()); -} - -//! Callback function with two parameters. - -TEST_F(CallbackContainerTest, twoParameters) -{ - CallbackMockWidget widget1, widget2; - Signal<Callbacks::item_int_t> signal; - - signal.connect([&](SessionItem* item, int role) { widget1.onDataChange(item, role); }, - &widget1); - - signal.connect([&](SessionItem* item, int role) { widget2.onDataChange(item, role); }, - &widget2); - - int expected_role = 42; - std::unique_ptr<SessionItem> item(new SessionItem); - EXPECT_CALL(widget1, onDataChange(item.get(), expected_role)).Times(1); - EXPECT_CALL(widget2, onDataChange(item.get(), expected_role)).Times(1); - - // perform action - signal(item.get(), expected_role); - - // removing one of client - signal.remove_client(&widget1); - EXPECT_CALL(widget1, onDataChange(_, _)).Times(0); - EXPECT_CALL(widget2, onDataChange(item.get(), expected_role)).Times(1); - - // perform action - signal(item.get(), expected_role); -} diff --git a/mvvm/tests/testmodel/colormapitem.test.cpp b/mvvm/tests/testmodel/colormapitem.test.cpp deleted file mode 100644 index c56ae41346416966b16c9e332ae5f86394f4c136..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/colormapitem.test.cpp +++ /dev/null @@ -1,77 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/colormapitem.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mockwidgets.h" -#include "mvvm/model/comboproperty.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/standarditems/axisitems.h" -#include "mvvm/standarditems/colormapitem.h" -#include "mvvm/standarditems/data2ditem.h" -#include "mvvm/standarditems/linkeditem.h" - -using namespace ModelView; -using ::testing::_; - -//! Testing ColorMapItem. - -class ColorMapItemTest : public ::testing::Test { -public: - ~ColorMapItemTest(); -}; - -ColorMapItemTest::~ColorMapItemTest() = default; - -//! Initial state. - -TEST_F(ColorMapItemTest, initialState) -{ - ColorMapItem item; - EXPECT_TRUE(item.dataItem() == nullptr); - EXPECT_TRUE(item.property<bool>(ColorMapItem::P_INTERPOLATION)); - EXPECT_EQ(item.property<ComboProperty>(ColorMapItem::P_GRADIENT).value(), "Polar"); -} - -//! Setting dataItem in model context. - -TEST_F(ColorMapItemTest, setDataItem) -{ - SessionModel model; - auto data_item = model.insertItem<Data2DItem>(); - auto colormap_item = model.insertItem<ColorMapItem>(); - - colormap_item->setDataItem(data_item); - - EXPECT_EQ(colormap_item->dataItem(), data_item); -} - -//! Check signaling on set data item. - -TEST_F(ColorMapItemTest, onSetDataItem) -{ - SessionModel model; - auto data_item = model.insertItem<Data2DItem>(); - auto colormap_item = model.insertItem<ColorMapItem>(); - - MockWidgetForItem widget(colormap_item); - - EXPECT_CALL(widget, onDataChange(_, _)).Times(0); - EXPECT_CALL(widget, onPropertyChange(colormap_item, ColorMapItem::P_LINK)).Times(1); - EXPECT_CALL(widget, onChildPropertyChange(_, _)).Times(0); - EXPECT_CALL(widget, onItemInserted(_, _)).Times(0); - EXPECT_CALL(widget, onAboutToRemoveItem(_, _)).Times(0); - - // performing action - colormap_item->setDataItem(data_item); -} diff --git a/mvvm/tests/testmodel/colormapviewportitem.test.cpp b/mvvm/tests/testmodel/colormapviewportitem.test.cpp deleted file mode 100644 index ae0a6c6c13d220558c0b3bc55cd9e5592126bfb4..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/colormapviewportitem.test.cpp +++ /dev/null @@ -1,157 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/colormapviewportitem.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mockwidgets.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/standarditems/axisitems.h" -#include "mvvm/standarditems/colormapitem.h" -#include "mvvm/standarditems/colormapviewportitem.h" -#include "mvvm/standarditems/data2ditem.h" - -using namespace ModelView; -using ::testing::_; - -//! Testing ColorMapViewportItem. - -class ColorMapViewportItemTest : public ::testing::Test { -public: - ~ColorMapViewportItemTest(); -}; - -ColorMapViewportItemTest::~ColorMapViewportItemTest() = default; - -//! Initial state. - -TEST_F(ColorMapViewportItemTest, initialState) -{ - ColorMapViewportItem viewport; - EXPECT_EQ(viewport.xAxis()->modelType(), GUI::Constants::ViewportAxisItemType); - EXPECT_EQ(viewport.yAxis()->modelType(), GUI::Constants::ViewportAxisItemType); - EXPECT_EQ(viewport.zAxis()->modelType(), GUI::Constants::ViewportAxisItemType); - EXPECT_EQ(viewport.items<ColorMapItem>(ColorMapViewportItem::T_ITEMS).size(), 0); -} - -//! Update on unitialized viewport. - -TEST_F(ColorMapViewportItemTest, uninitializedViewportUpdate) -{ - SessionModel model; - - auto viewport_item = model.insertItem<ColorMapViewportItem>(); - - viewport_item->setViewportToContent(); - - // x-axis of viewport should be set Data2DItem - auto [xmin, xmax] = viewport_item->xAxis()->range(); - EXPECT_DOUBLE_EQ(xmin, 0.0); - EXPECT_DOUBLE_EQ(xmax, 1.0); - - // y-axis of viewport should be set Data2DItem - auto [ymin, ymax] = viewport_item->yAxis()->range(); - EXPECT_DOUBLE_EQ(ymin, 0.0); - EXPECT_DOUBLE_EQ(ymax, 1.0); - - // z-axis of viewport should be set to min/max content - auto [zmin, zmax] = viewport_item->zAxis()->range(); - EXPECT_DOUBLE_EQ(zmin, 0.0); - EXPECT_DOUBLE_EQ(zmax, 1.0); -} - -//! Add graph to viewport. - -TEST_F(ColorMapViewportItemTest, addItem) -{ - SessionModel model; - - auto viewport_item = model.insertItem<ColorMapViewportItem>(); - auto colormap_item = model.insertItem<ColorMapItem>(viewport_item); - auto data_item = model.insertItem<Data2DItem>(); - - data_item->setAxes(FixedBinAxisItem::create(2, 0.0, 2.0), - FixedBinAxisItem::create(3, 0.0, 3.0)); - const std::vector<double> expected_content = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0}; - data_item->setContent(expected_content); - - colormap_item->setDataItem(data_item); - EXPECT_EQ(viewport_item->items<ColorMapItem>(ColorMapViewportItem::T_ITEMS).size(), 1); - - // updating viewport to graph - viewport_item->setViewportToContent(); - - // x-axis of viewport should be set Data2DItem - auto [xmin, xmax] = viewport_item->xAxis()->range(); - EXPECT_DOUBLE_EQ(xmin, 0.0); - EXPECT_DOUBLE_EQ(xmax, 2.0); - - // y-axis of viewport should be set Data2DItem - auto [ymin, ymax] = viewport_item->yAxis()->range(); - EXPECT_DOUBLE_EQ(ymin, 0.0); - EXPECT_DOUBLE_EQ(ymax, 3.0); - - // z-axis of viewport should be set to min/max content - auto [zmin, zmax] = viewport_item->zAxis()->range(); - EXPECT_DOUBLE_EQ(zmin, 1.0); - EXPECT_DOUBLE_EQ(zmax, 6.0); -} - -//! Check signaling on set data item. - -TEST_F(ColorMapViewportItemTest, onAddItem) -{ - SessionModel model; - auto viewport_item = model.insertItem<ColorMapViewportItem>(); - - MockWidgetForItem widget(viewport_item); - - const TagRow expected_tagrow{ViewportItem::T_ITEMS, 0}; - EXPECT_CALL(widget, onDataChange(_, _)).Times(0); - EXPECT_CALL(widget, onPropertyChange(_, _)).Times(0); - EXPECT_CALL(widget, onChildPropertyChange(_, _)).Times(0); - EXPECT_CALL(widget, onItemInserted(viewport_item, expected_tagrow)).Times(1); - EXPECT_CALL(widget, onAboutToRemoveItem(_, _)).Times(0); - - // triggering action - model.insertItem<ColorMapItem>(viewport_item); -} - -//! Check signaling on set data item. - -TEST_F(ColorMapViewportItemTest, onSetDataItem) -{ - SessionModel model; - auto viewport_item = model.insertItem<ColorMapViewportItem>(); - - // setting upda tata item - auto data_item = model.insertItem<Data2DItem>(); - - data_item->setAxes(FixedBinAxisItem::create(2, 0.0, 2.0), - FixedBinAxisItem::create(3, 0.0, 3.0)); - const std::vector<double> expected_content = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0}; - data_item->setContent(expected_content); - - // inserting graph item - auto colormap_item = model.insertItem<ColorMapItem>(viewport_item); - - MockWidgetForItem widget(viewport_item); - - EXPECT_CALL(widget, onDataChange(_, _)).Times(0); - EXPECT_CALL(widget, onPropertyChange(_, _)).Times(0); - EXPECT_CALL(widget, onChildPropertyChange(colormap_item, ColorMapItem::P_LINK)).Times(1); - EXPECT_CALL(widget, onItemInserted(_, _)).Times(0); - EXPECT_CALL(widget, onAboutToRemoveItem(_, _)).Times(0); - - // triggering action - colormap_item->setDataItem(data_item); -} diff --git a/mvvm/tests/testmodel/comboproperty.test.cpp b/mvvm/tests/testmodel/comboproperty.test.cpp deleted file mode 100644 index 5f8bffdf5821f13edb70c8cad462cb45ed0fd911..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/comboproperty.test.cpp +++ /dev/null @@ -1,422 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/comboproperty.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/model/comboproperty.h" -#include "mvvm/model/comparators.h" -#include <stdexcept> - -using namespace ModelView; - -class ComboPropertyTest : public ::testing::Test { -public: - ~ComboPropertyTest(); -}; - -ComboPropertyTest::~ComboPropertyTest() = default; - -TEST_F(ComboPropertyTest, initialState) -{ - ComboProperty combo; - EXPECT_EQ(combo.value(), ""); - EXPECT_EQ(combo.values(), std::vector<std::string>()); - EXPECT_EQ(combo.toolTips(), std::vector<std::string>()); - EXPECT_EQ(combo.currentIndex(), -1); - EXPECT_EQ(combo.stringOfValues(), ""); - EXPECT_EQ(combo.selectedIndices(), std::vector<int>()); - EXPECT_EQ(combo.label(), "None"); -} - -TEST_F(ComboPropertyTest, createFrom) -{ - // from vector of values, first item should be selected - std::vector<std::string> expected{"a1", "a2"}; - ComboProperty combo = ComboProperty::createFrom(expected); - EXPECT_EQ(combo.values(), expected); - EXPECT_EQ(combo.currentIndex(), 0); - EXPECT_EQ(combo.value(), "a1"); - EXPECT_EQ(combo.selectedIndices(), std::vector<int>({0})); - - // from vector of values, selection provided - expected = {"b1", "b2", "b3"}; - combo = ComboProperty::createFrom(expected, "b2"); - EXPECT_EQ(combo.values(), expected); - EXPECT_EQ(combo.currentIndex(), 1); - EXPECT_EQ(combo.value(), "b2"); - EXPECT_EQ(combo.selectedIndices(), std::vector<int>({1})); -} - -TEST_F(ComboPropertyTest, setValue) -{ - std::vector<std::string> expected{"a1", "a2"}; - ComboProperty combo = ComboProperty::createFrom(expected); - - // setting second value - combo.setValue("a2"); - EXPECT_EQ(combo.values(), expected); - EXPECT_EQ(combo.currentIndex(), 1); - EXPECT_EQ(combo.value(), "a2"); - EXPECT_EQ(combo.selectedIndices(), std::vector<int>({1})); - - // setting non-existing value - EXPECT_THROW(combo.setValue("c0"), std::runtime_error); - EXPECT_EQ(combo.values(), expected); - EXPECT_EQ(combo.currentIndex(), 1); - EXPECT_EQ(combo.value(), "a2"); - EXPECT_EQ(combo.selectedIndices(), std::vector<int>({1})); -} - -TEST_F(ComboPropertyTest, setCurrentIndex) -{ - std::vector<std::string> expected{"c1", "c2", "c3"}; - ComboProperty combo = ComboProperty::createFrom(expected); - - EXPECT_EQ(combo.currentIndex(), 0); - EXPECT_EQ(combo.selectedIndices(), std::vector<int>({0})); - EXPECT_EQ(combo.values(), expected); - - combo.setCurrentIndex(1); - EXPECT_EQ(combo.value(), std::string("c2")); - EXPECT_EQ(combo.selectedIndices(), std::vector<int>({1})); - - // setting unexpected index - EXPECT_THROW(combo.setCurrentIndex(3), std::runtime_error); - EXPECT_EQ(combo.value(), std::string("c2")); - EXPECT_EQ(combo.selectedIndices(), std::vector<int>({1})); -} - -TEST_F(ComboPropertyTest, setValues) -{ - // seting values through stream - std::vector<std::string> expectedValues{"a1", "a2"}; - ComboProperty combo = ComboProperty::createFrom(expectedValues); - - EXPECT_EQ(combo.values(), expectedValues); - EXPECT_EQ(combo.value(), std::string("a1")); - EXPECT_EQ(combo.currentIndex(), 0); - EXPECT_EQ(combo.selectedIndices(), std::vector<int>({0})); - - // setting values from setter, old values have to be overriden - std::vector<std::string> newValues{"b1", "b2", "b3"}; - combo.setValues(newValues); - EXPECT_EQ(combo.value(), std::string("b1")); - EXPECT_EQ(combo.values(), newValues); - EXPECT_EQ(combo.currentIndex(), 0); - EXPECT_EQ(combo.selectedIndices(), std::vector<int>({0})); - - // setting new/old values through setter, old value should be preserved - newValues = {"c1", "b1", "c2"}; - combo.setValues(newValues); - EXPECT_EQ(combo.value(), std::string("b1")); - EXPECT_EQ(combo.values(), newValues); - EXPECT_EQ(combo.currentIndex(), 1); - EXPECT_EQ(combo.selectedIndices(), std::vector<int>({1})); - - // setting empty list shouldn't change anything - std::vector<std::string> empty; - combo.setValues(empty); - EXPECT_EQ(combo.value(), std::string("b1")); - EXPECT_EQ(combo.values(), newValues); - EXPECT_EQ(combo.currentIndex(), 1); - EXPECT_EQ(combo.selectedIndices(), std::vector<int>({1})); -} - -TEST_F(ComboPropertyTest, setSelected) -{ - std::vector<std::string> expectedValues = {"a1", "a2", "a3"}; - ComboProperty combo = ComboProperty::createFrom(expectedValues); - - EXPECT_EQ(combo.currentIndex(), 0); - EXPECT_EQ(combo.value(), "a1"); - EXPECT_EQ(combo.values(), expectedValues); - EXPECT_EQ(combo.selectedIndices(), std::vector<int>({0})); - EXPECT_EQ(combo.selectedValues(), std::vector<std::string>({"a1"})); - - // selecting already selected element, nothing should change - combo.setSelected(0); - EXPECT_EQ(combo.currentIndex(), 0); - EXPECT_EQ(combo.value(), "a1"); - EXPECT_EQ(combo.values(), expectedValues); - EXPECT_EQ(combo.selectedIndices(), std::vector<int>({0})); - EXPECT_EQ(combo.selectedValues(), std::vector<std::string>({"a1"})); - - // deselecting index - combo.setSelected(0, false); - EXPECT_EQ(combo.currentIndex(), -1); - EXPECT_EQ(combo.value(), ""); - EXPECT_EQ(combo.values(), expectedValues); - EXPECT_EQ(combo.selectedIndices(), std::vector<int>()); - EXPECT_EQ(combo.selectedValues(), std::vector<std::string>()); - - // selecting two indeces - combo.setSelected(1, true); - combo.setSelected(2, true); - EXPECT_EQ(combo.currentIndex(), 1); - EXPECT_EQ(combo.value(), "a2"); - EXPECT_EQ(combo.values(), expectedValues); - EXPECT_EQ(combo.selectedIndices(), std::vector<int>({1, 2})); - EXPECT_EQ(combo.selectedValues(), std::vector<std::string>({"a2", "a3"})); - - // selecting by name - combo.setSelected("a2", false); - combo.setSelected("a1", true); - EXPECT_EQ(combo.currentIndex(), 0); - EXPECT_EQ(combo.value(), "a1"); - EXPECT_EQ(combo.values(), expectedValues); - EXPECT_EQ(combo.selectedIndices(), std::vector<int>({0, 2})); - EXPECT_EQ(combo.selectedValues(), std::vector<std::string>({"a1", "a3"})); - - // setting current index invalidates selection - combo.setCurrentIndex(1); - EXPECT_EQ(combo.currentIndex(), 1); - EXPECT_EQ(combo.value(), "a2"); - EXPECT_EQ(combo.values(), expectedValues); - EXPECT_EQ(combo.selectedIndices(), std::vector<int>({1})); - EXPECT_EQ(combo.selectedValues(), std::vector<std::string>({"a2"})); -} - -TEST_F(ComboPropertyTest, fromStream) -{ - ComboProperty combo = ComboProperty() << "a1" - << "a2"; - std::vector<std::string> expected{"a1", "a2"}; - EXPECT_EQ(combo.values(), expected); - EXPECT_EQ(combo.currentIndex(), 0); - EXPECT_EQ(combo.value(), "a1"); - EXPECT_EQ(combo.selectedIndices(), std::vector<int>({0})); - - // adding more - combo << "c0"; - expected = {"a1", "a2", "c0"}; - EXPECT_EQ(combo.values(), expected); - EXPECT_EQ(combo.currentIndex(), 0); - EXPECT_EQ(combo.value(), "a1"); - EXPECT_EQ(combo.selectedIndices(), std::vector<int>({0})); - - // setting another index, adding more, state should be preserved - combo.setCurrentIndex(1); - combo.setSelected(2, true); - EXPECT_EQ(combo.values(), expected); - EXPECT_EQ(combo.currentIndex(), 1); - EXPECT_EQ(combo.value(), "a2"); - EXPECT_EQ(combo.selectedIndices(), std::vector<int>({1, 2})); - combo << "c1"; - expected = {"a1", "a2", "c0", "c1"}; - EXPECT_EQ(combo.values(), expected); - EXPECT_EQ(combo.currentIndex(), 1); -} - -TEST_F(ComboPropertyTest, fromVectorStream) -{ - std::vector<std::string> expected{"a1", "a2"}; - ComboProperty combo = ComboProperty::createFrom(expected); - combo.setSelected(0, true); - combo.setSelected(1, true); - - EXPECT_EQ(combo.values(), expected); - EXPECT_EQ(combo.currentIndex(), 0); - EXPECT_EQ(combo.value(), "a1"); - EXPECT_EQ(combo.selectedIndices(), std::vector<int>({0, 1})); - - // adding from vector stream, old selection state should be preserved - std::vector<std::string> more{"c1", "c2"}; - combo << more; - expected = {"a1", "a2", "c1", "c2"}; - EXPECT_EQ(combo.values(), expected); - EXPECT_EQ(combo.currentIndex(), 0); - EXPECT_EQ(combo.value(), "a1"); - EXPECT_EQ(combo.selectedIndices(), std::vector<int>({0, 1})); -} - -TEST_F(ComboPropertyTest, setSringOfValues) -{ - std::vector<std::string> expectedValues = {"a1", "a2"}; - ComboProperty combo = ComboProperty::createFrom(expectedValues); - - EXPECT_EQ(combo.stringOfValues(), std::string("a1;a2")); - EXPECT_EQ(combo.value(), std::string("a1")); - EXPECT_EQ(combo.currentIndex(), 0); - EXPECT_EQ(combo.selectedIndices(), std::vector<int>({0})); - - // setting string of values, current value should change - std::string stringOfValues("b1;b2;b3"); - combo.setStringOfValues(stringOfValues); - EXPECT_EQ(combo.stringOfValues(), stringOfValues); - EXPECT_EQ(combo.value(), std::string("b1")); - EXPECT_EQ(combo.values(), std::vector<std::string>({"b1", "b2", "b3"})); - EXPECT_EQ(combo.currentIndex(), 0); - EXPECT_EQ(combo.selectedIndices(), std::vector<int>({0})); - - // setting new string of values, containing current value. Current values should remain. - stringOfValues = std::string("c1;b1;c3"); - combo.setStringOfValues(stringOfValues); - EXPECT_EQ(combo.stringOfValues(), stringOfValues); - EXPECT_EQ(combo.value(), std::string("b1")); - EXPECT_EQ(combo.currentIndex(), 1); - EXPECT_EQ(combo.selectedIndices(), std::vector<int>({1})); -} - -TEST_F(ComboPropertyTest, setStringOfSelections) -{ - ComboProperty combo; - EXPECT_EQ(combo.stringOfSelections(), ""); - - // checking the content of stringOfSelections - combo.setValues(std::vector<std::string>({"a1", "a2", "a3"})); - EXPECT_EQ(combo.selectedIndices(), std::vector<int>({0})); - EXPECT_EQ(combo.currentIndex(), 0); - EXPECT_EQ(combo.stringOfSelections(), "0"); - - combo.setSelected(2, true); - EXPECT_EQ(combo.selectedIndices(), std::vector<int>({0, 2})); - EXPECT_EQ(combo.currentIndex(), 0); - EXPECT_EQ(combo.stringOfSelections(), "0,2"); - - // setting string of selections - combo.setStringOfSelections(""); - EXPECT_EQ(combo.selectedIndices(), std::vector<int>({})); - EXPECT_EQ(combo.currentIndex(), -1); - EXPECT_EQ(combo.stringOfSelections(), ""); - - combo.setStringOfSelections("1,2"); - EXPECT_EQ(combo.selectedIndices(), std::vector<int>({1, 2})); - EXPECT_EQ(combo.currentIndex(), 1); - EXPECT_EQ(combo.stringOfSelections(), "1,2"); - - combo.setStringOfSelections("0,42"); - EXPECT_EQ(combo.selectedIndices(), std::vector<int>({0})); - EXPECT_EQ(combo.currentIndex(), 0); - EXPECT_EQ(combo.stringOfSelections(), "0"); -} - -TEST_F(ComboPropertyTest, comboEqualityDiffIndex) -{ - ComboProperty c1 = ComboProperty::createFrom({"a1", "a2"}); - ComboProperty c2 = ComboProperty::createFrom({"a1", "a2"}); - - c1.setValue("a1"); - c2.setValue("a2"); - EXPECT_TRUE(c1 != c2); - - c2.setValue("a1"); - EXPECT_TRUE(c1 == c2); -} - -TEST_F(ComboPropertyTest, comboEqualityDiffList) -{ - ComboProperty c1; - ComboProperty c2; - EXPECT_TRUE(c1 == c2); - - c1 << "a1" - << "a2"; - c2 << "a1" - << "a2"; - EXPECT_TRUE(c1 == c2); - EXPECT_FALSE(c1 != c2); - - c2 << "a3"; - EXPECT_TRUE(c1 != c2); - EXPECT_FALSE(c1 == c2); - c2.setValue("a2"); - EXPECT_TRUE(c1 != c2); - EXPECT_FALSE(c1 == c2); - - c1 << "a3"; - c1.setValue("a2"); - EXPECT_TRUE(c1 == c2); - EXPECT_FALSE(c1 != c2); - - // with selection indices - c1 = ComboProperty() << "a1" - << "a2" - << "a3"; - c2 = ComboProperty() << "a1" - << "a2" - << "a3"; - EXPECT_TRUE(c1 == c2); - - c2.setSelected(0, false); - c2.setSelected(2, true); - EXPECT_TRUE(c1 != c2); - - c1.setStringOfSelections("2"); - c2.setStringOfSelections("2"); - EXPECT_TRUE(c1 == c2); -} - -//! Check equality of ComboProperty's variants. -//! If comparators are not registered, the behavior is undefined. - -TEST_F(ComboPropertyTest, variantEqualityDiffLists) -{ - if (ModelView::Comparators::registered()) { - ComboProperty c1 = ComboProperty() << "a1" - << "a2"; - ComboProperty c2 = ComboProperty() << "a1" - << "a2"; - - EXPECT_TRUE(QVariant::fromValue(c1) == QVariant::fromValue(c2)); - - c2 << "a3"; - c2.setValue("a2"); - - EXPECT_TRUE(QVariant::fromValue(c1) != QVariant::fromValue(c2)); - EXPECT_FALSE(QVariant::fromValue(c1) == QVariant::fromValue(c2)); - - c1 << "a3"; - c1.setValue("a2"); - - EXPECT_TRUE(QVariant::fromValue(c1) == QVariant::fromValue(c2)); - EXPECT_FALSE(QVariant::fromValue(c1) != QVariant::fromValue(c2)); - - c1.setStringOfSelections("0"); - c2.setStringOfSelections("1"); - EXPECT_TRUE(QVariant::fromValue(c1) != QVariant::fromValue(c2)); - EXPECT_FALSE(QVariant::fromValue(c1) == QVariant::fromValue(c2)); - } -} - -//! Check equality of ComboProperty's variants when only selected item differs. - -TEST_F(ComboPropertyTest, variantEqualityDiffIndex) -{ - if (ModelView::Comparators::registered()) { - ComboProperty c1 = ComboProperty::createFrom({"a1", "a2"}); - ComboProperty c2 = ComboProperty::createFrom({"a1", "a2"}); - - c1.setValue("a1"); - c2.setValue("a2"); - - EXPECT_FALSE(QVariant::fromValue(c1) == QVariant::fromValue(c2)); - EXPECT_TRUE(QVariant::fromValue(c1) != QVariant::fromValue(c2)); - - c2.setValue("a1"); - EXPECT_TRUE(QVariant::fromValue(c1) == QVariant::fromValue(c2)); - EXPECT_FALSE(QVariant::fromValue(c1) != QVariant::fromValue(c2)); - } - - if (ModelView::Comparators::registered()) { - ComboProperty c1 = ComboProperty::createFrom({"a1", "a2"}); - ComboProperty c2 = ComboProperty::createFrom({"a1", "a2"}); - - c1.setValue("a1"); - c2.setValue("a2"); - - std::vector<QVariant> variants = {QVariant::fromValue(c1), QVariant::fromValue(c2)}; - - EXPECT_FALSE(variants[0] == variants[1]); - EXPECT_TRUE(variants[0] != variants[1]); - } -} diff --git a/mvvm/tests/testmodel/compatibilityutils.test.cpp b/mvvm/tests/testmodel/compatibilityutils.test.cpp deleted file mode 100644 index d52f0bef80d1c524debc7f348e24ac1315e18cc9..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/compatibilityutils.test.cpp +++ /dev/null @@ -1,74 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/compatibilityutils.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/model/groupitem.h" -#include "mvvm/model/mvvm_types.h" -#include "mvvm/model/propertyitem.h" -#include "mvvm/model/sessionitemcontainer.h" -#include "mvvm/model/sessionitemdata.h" -#include "mvvm/serialization/compatibilityutils.h" - -using namespace ModelView; - -//! Test of CompatibilityUtilsTest. - -class CompatibilityUtilsTest : public ::testing::Test { -public: - ~CompatibilityUtilsTest(); -}; - -CompatibilityUtilsTest::~CompatibilityUtilsTest() = default; - -//! Testing IsCompatibleSingleProperty. - -TEST_F(CompatibilityUtilsTest, IsCompatibleSinglePropertyTag) -{ - TagInfo tag = TagInfo::propertyTag("thickness", GUI::Constants::PropertyType); - SessionItemContainer container(tag); - - // to be compatible, container should have PropertyItem in it already - EXPECT_FALSE(Compatibility::IsCompatibleSinglePropertyTag(container, tag)); - - EXPECT_TRUE(container.insertItem(new PropertyItem, 0)); - EXPECT_TRUE(Compatibility::IsCompatibleSinglePropertyTag(container, tag)); -} - -//! Testing IsCompatibleSingleProperty. - -TEST_F(CompatibilityUtilsTest, IsCompatibleUniversalTag) -{ - TagInfo tag = TagInfo::universalTag("layers"); - SessionItemContainer container(tag); - - // to be compatible, container should be empty - EXPECT_TRUE(Compatibility::IsCompatibleUniversalTag(container, tag)); - - EXPECT_TRUE(container.insertItem(new PropertyItem, 0)); - EXPECT_FALSE(Compatibility::IsCompatibleUniversalTag(container, tag)); -} - -//! Testing IsCompatibleSingleProperty. - -TEST_F(CompatibilityUtilsTest, IsCompatibleGroupTag) -{ - TagInfo tag = TagInfo::universalTag(GroupItem::T_GROUP_ITEMS); - SessionItemContainer container(tag); - - // to be compatible, container should be non-empty - EXPECT_FALSE(Compatibility::IsCompatibleGroupTag(container, tag)); - - EXPECT_TRUE(container.insertItem(new PropertyItem, 0)); - EXPECT_TRUE(Compatibility::IsCompatibleGroupTag(container, tag)); -} diff --git a/mvvm/tests/testmodel/compounditem.test.cpp b/mvvm/tests/testmodel/compounditem.test.cpp deleted file mode 100644 index 45a95ffc23386c341d286dbc940df6afba5a9ad8..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/compounditem.test.cpp +++ /dev/null @@ -1,253 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/compounditem.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/model/compounditem.h" -#include "mvvm/model/customvariants.h" -#include "mvvm/model/itemutils.h" -#include "mvvm/model/sessionmodel.h" -#include "test_utils.h" -#include <memory> -#include <stdexcept> - -using namespace ModelView; - -namespace { -const std::string property_name("name"); -} - -//! Test of CompountItem machinery (property children etc). - -class CompoundItemTest : public ::testing::Test { -}; - -TEST_F(CompoundItemTest, initialState) -{ - CompoundItem item; - EXPECT_EQ(item.childrenCount(), 0); -} - -TEST_F(CompoundItemTest, addIntProperty) -{ - CompoundItem item; - - const int expected = 42; - auto propertyItem = item.addProperty(property_name, expected); - EXPECT_TRUE(Utils::HasTag(item, "name")); - - EXPECT_EQ(propertyItem->modelType(), GUI::Constants::PropertyType); - EXPECT_TRUE(Utils::IsIntVariant(propertyItem->data<QVariant>())); - EXPECT_EQ(propertyItem->displayName(), property_name); - EXPECT_EQ(propertyItem->data<int>(), expected); - - EXPECT_FALSE(propertyItem->data<QVariant>(ItemDataRole::LIMITS).isValid()); -} - -TEST_F(CompoundItemTest, setIntProperty) -{ - CompoundItem item; - auto propertyItem = item.addProperty(property_name, 41); - - const int expected = 42; - item.setProperty(property_name, expected); - - EXPECT_EQ(item.property<int>(property_name), expected); - EXPECT_EQ(propertyItem->data<int>(), expected); -} - -TEST_F(CompoundItemTest, addDoubleProperty) -{ - CompoundItem item; - - const double expected = 42.1; - auto propertyItem = item.addProperty(property_name, expected); - EXPECT_TRUE(Utils::HasTag(item, property_name)); - - EXPECT_EQ(propertyItem->modelType(), GUI::Constants::PropertyType); - EXPECT_TRUE(Utils::IsDoubleVariant(propertyItem->data<QVariant>())); - EXPECT_EQ(propertyItem->displayName(), property_name); - EXPECT_EQ(propertyItem->data<double>(), expected); - - EXPECT_TRUE(propertyItem->data<QVariant>(ItemDataRole::LIMITS).isValid()); - - // limits should be "negative 'unlimited' by default - auto limits = propertyItem->data<RealLimits>(ItemDataRole::LIMITS); - EXPECT_FALSE(limits.hasLowerLimit()); - EXPECT_FALSE(limits.hasUpperLimit()); -} - -TEST_F(CompoundItemTest, setDoubleProperty) -{ - CompoundItem item; - auto propertyItem = item.addProperty(property_name, 41.11); - - const double expected = 42.0; - item.setProperty(property_name, expected); - - EXPECT_EQ(item.property<double>(property_name), expected); - EXPECT_EQ(propertyItem->data<double>(), expected); -} - -TEST_F(CompoundItemTest, addCharProperty) -{ - CompoundItem item; - - auto propertyItem = item.addProperty(property_name, "abc"); - EXPECT_TRUE(Utils::HasTag(item, property_name)); - - EXPECT_EQ(propertyItem->modelType(), GUI::Constants::PropertyType); - EXPECT_TRUE(Utils::IsStdStringVariant(propertyItem->data<QVariant>())); - EXPECT_EQ(propertyItem->data<std::string>(), std::string("abc")); - - EXPECT_FALSE(propertyItem->data<QVariant>(ItemDataRole::LIMITS).isValid()); -} - -TEST_F(CompoundItemTest, setCharProperty) -{ - CompoundItem item; - auto propertyItem = item.addProperty(property_name, "aaa"); - - const char* expected{"bbb"}; - item.setProperty(property_name, expected); - - EXPECT_EQ(item.property<std::string>(property_name), std::string(expected)); - EXPECT_EQ(propertyItem->data<std::string>(), std::string(expected)); -} - -TEST_F(CompoundItemTest, addStringProperty) -{ - CompoundItem item; - - auto propertyItem = item.addProperty(property_name, std::string("abc")); - EXPECT_TRUE(Utils::HasTag(item, property_name)); - - EXPECT_EQ(propertyItem->modelType(), GUI::Constants::PropertyType); - EXPECT_TRUE(Utils::IsStdStringVariant(propertyItem->data<QVariant>())); - EXPECT_EQ(propertyItem->data<std::string>(), std::string("abc")); - - EXPECT_FALSE(propertyItem->data<QVariant>(ItemDataRole::LIMITS).isValid()); -} - -TEST_F(CompoundItemTest, setStringProperty) -{ - CompoundItem item; - auto propertyItem = item.addProperty(property_name, std::string("aaa")); - - const std::string expected{"bbb"}; - item.setProperty(property_name, expected); - - EXPECT_EQ(item.property<std::string>(property_name), expected); - EXPECT_EQ(propertyItem->data<std::string>(), expected); -} - -TEST_F(CompoundItemTest, addBoolProperty) -{ - CompoundItem item; - - const bool expected = true; - auto propertyItem = item.addProperty(property_name, expected); - EXPECT_TRUE(Utils::HasTag(item, property_name)); - - EXPECT_EQ(propertyItem->modelType(), GUI::Constants::PropertyType); - EXPECT_TRUE(Utils::IsBoolVariant(propertyItem->data<QVariant>())); - EXPECT_EQ(propertyItem->data<bool>(), expected); - - EXPECT_FALSE(propertyItem->data<QVariant>(ItemDataRole::LIMITS).isValid()); -} - -TEST_F(CompoundItemTest, setBoolProperty) -{ - CompoundItem item; - auto propertyItem = item.addProperty(property_name, false); - - const bool expected = true; - item.setProperty(property_name, expected); - - EXPECT_EQ(item.property<bool>(property_name), expected); - EXPECT_EQ(propertyItem->data<bool>(), expected); -} - -TEST_F(CompoundItemTest, itemAccess) -{ - const std::string tag = "tag"; - - // creating parent with one tag - SessionItem parent; - parent.registerTag(TagInfo::universalTag(tag)); - - // inserting two children - auto property = new PropertyItem; - parent.insertItem(property, {tag, 0}); - - EXPECT_TRUE(parent.item<PropertyItem>(tag) == property); - EXPECT_THROW(parent.item<CompoundItem>(tag), std::runtime_error); -} - -TEST_F(CompoundItemTest, itemVectorAccess) -{ - const std::string tag = "tag"; - - // creating parent with one tag - SessionItem parent; - parent.registerTag(TagInfo::universalTag(tag)); - - // inserting two children - auto property1 = new PropertyItem; - auto property2 = new PropertyItem; - parent.insertItem(property1, TagRow::append(tag)); - parent.insertItem(property2, TagRow::append(tag)); - - auto items = parent.items<PropertyItem>(tag); - std::vector<PropertyItem*> expected = {property1, property2}; - EXPECT_EQ(items, expected); - EXPECT_EQ(parent.items<CompoundItem>(tag).size(), 0); -} - -//! Tests automatic index addition to default display name. - -TEST_F(CompoundItemTest, displayNameIndexAddition) -{ - const std::string tag = "tag"; - - // creating parent with one tag - SessionItem parent; - parent.registerTag(TagInfo::universalTag(tag)); - - // inserting two children - auto child0 = new CompoundItem; - parent.insertItem(child0, TagRow::append(tag)); - auto child1 = new CompoundItem; - parent.insertItem(child1, TagRow::append(tag)); - - // Default display names of items of the same type should have indices - EXPECT_EQ(child0->displayName(), GUI::Constants::CompoundItemType + "0"); - EXPECT_EQ(child1->displayName(), GUI::Constants::CompoundItemType + "1"); - - // however, if children have custom display name, they should remain intact - child0->setDisplayName("Jekyll"); - child1->setDisplayName("Hyde"); - EXPECT_EQ(child0->displayName(), "Jekyll"); - EXPECT_EQ(child1->displayName(), "Hyde"); -} - -//! Test all children method. -//! Property items are also children. - -TEST_F(CompoundItemTest, children) -{ - CompoundItem item; - EXPECT_TRUE(item.children().empty()); - auto propertyItem = item.addProperty(property_name, false); - EXPECT_EQ(item.children(), std::vector<SessionItem*>({propertyItem})); -} diff --git a/mvvm/tests/testmodel/containeritem.test.cpp b/mvvm/tests/testmodel/containeritem.test.cpp deleted file mode 100644 index f76fad8b4bfb7f540f2a0bcbf25baea00bf8adf2..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/containeritem.test.cpp +++ /dev/null @@ -1,48 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/containeritem.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/standarditems/containeritem.h" -#include "test_utils.h" -#include <memory> - -using namespace ModelView; - -//! Test of ContainerItem. - -class ContainerItemTest : public ::testing::Test { -public: - ~ContainerItemTest(); -}; - -ContainerItemTest::~ContainerItemTest() = default; - -TEST_F(ContainerItemTest, initialState) -{ - ContainerItem item; - EXPECT_EQ(item.size(), 0); - EXPECT_TRUE(item.empty()); -} - -TEST_F(ContainerItemTest, isEmpty) -{ - ContainerItem item; - - // inserting two children - auto property = new PropertyItem; - item.insertItem(property, {"", 0}); - - EXPECT_EQ(item.size(), 1); - EXPECT_FALSE(item.empty()); -} diff --git a/mvvm/tests/testmodel/containerutils.test.cpp b/mvvm/tests/testmodel/containerutils.test.cpp deleted file mode 100644 index 4d35cdf723049d0e9257991f5d3bc2979486792f..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/containerutils.test.cpp +++ /dev/null @@ -1,83 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/containerutils.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/utils/containerutils.h" -#include <complex> - -using namespace ModelView; - -//! Tests of container utils. - -class ContainerUtilsTest : public ::testing::Test { -public: - ~ContainerUtilsTest(); -}; - -ContainerUtilsTest::~ContainerUtilsTest() = default; - -TEST_F(ContainerUtilsTest, isUniquePtr) -{ - EXPECT_FALSE(Utils::is_unique_ptr<int>::value); - EXPECT_TRUE(Utils::is_unique_ptr<std::unique_ptr<int>>::value); -} - -TEST_F(ContainerUtilsTest, IndexOfItem) -{ - // searching in vector of integers - std::vector<int> vv{1, 7, 5}; - EXPECT_EQ(Utils::IndexOfItem(vv, 1), 0); - EXPECT_EQ(Utils::IndexOfItem(vv, 10), -1); - EXPECT_EQ(Utils::IndexOfItem(vv, 5), 2); - EXPECT_EQ(Utils::IndexOfItem(vv.begin(), vv.end(), 7), 1); - - // searching in vector of SessionItem's - std::vector<SessionItem*> items{new SessionItem, new SessionItem, new SessionItem}; - SessionItem other; - EXPECT_EQ(Utils::IndexOfItem(items, items[0]), 0); - EXPECT_EQ(Utils::IndexOfItem(items, items[1]), 1); - EXPECT_EQ(Utils::IndexOfItem(items, items[2]), 2); - EXPECT_EQ(Utils::IndexOfItem(items, &other), -1); - for (auto x : items) - delete x; - - // searching in vector of unique_ptr - std::vector<std::unique_ptr<SessionItem>> unique_items; - unique_items.emplace_back(std::make_unique<SessionItem>()); - unique_items.emplace_back(std::make_unique<SessionItem>()); - EXPECT_EQ(Utils::IndexOfItem(unique_items, unique_items[0].get()), 0); - EXPECT_EQ(Utils::IndexOfItem(unique_items, unique_items[1].get()), 1); - EXPECT_EQ(Utils::IndexOfItem(unique_items, &other), -1); -} - -TEST_F(ContainerUtilsTest, Real) -{ - std::vector<std::complex<double>> data = {{1.0, 10.0}, {2.0, 20.0}}; - EXPECT_EQ(Utils::Real(data), (std::vector<double>{1.0, 2.0})); - EXPECT_EQ(Utils::Imag(data), (std::vector<double>{10.0, 20.0})); -} - -TEST_F(ContainerUtilsTest, UniqueWithOrder) -{ - std::vector<int> data = {1, 42, 1, 6, 43, 6}; - EXPECT_EQ(Utils::UniqueWithOrder(data), (std::vector<int>{1, 42, 6, 43})); -} - -TEST_F(ContainerUtilsTest, Contains) -{ - std::vector<int> data = {1, 42, 1, 6, 43, 6}; - EXPECT_TRUE(Utils::Contains(data, 42)); - EXPECT_FALSE(Utils::Contains(data, 99)); -} diff --git a/mvvm/tests/testmodel/copyitemcommand.test.cpp b/mvvm/tests/testmodel/copyitemcommand.test.cpp deleted file mode 100644 index 0512ed6efd1a8bc75563d7fd40ec024f7db6fb6a..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/copyitemcommand.test.cpp +++ /dev/null @@ -1,90 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/copyitemcommand.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/commands/copyitemcommand.h" -#include "mvvm/model/compounditem.h" -#include "mvvm/model/itemutils.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/model/taginfo.h" -#include <stdexcept> - -using namespace ModelView; - -class CopyItemCommandTest : public ::testing::Test { -public: - ~CopyItemCommandTest(); -}; - -CopyItemCommandTest::~CopyItemCommandTest() = default; - -TEST_F(CopyItemCommandTest, copyChild) -{ - SessionModel model; - - // parent with children and data - auto parent = model.insertItem<SessionItem>(model.rootItem(), {"", 0}); - parent->registerTag(TagInfo::universalTag("tag1"), /*set_as_default*/ true); - - auto child0 = model.insertItem<SessionItem>(parent, "tag1"); - child0->setData(42.0); - auto child1 = model.insertItem<SessionItem>(parent, "tag1"); - child1->setData(43.0); - - // making copy of child - auto command = std::make_unique<CopyItemCommand>(child1, parent, TagRow{"tag1", 1}); - command->execute(); - - // checking that parent has now three children - auto copy = std::get<SessionItem*>(command->result()); - EXPECT_FALSE(command->isObsolete()); - EXPECT_TRUE(copy != nullptr); - EXPECT_EQ(parent->childrenCount(), 3); - std::vector<SessionItem*> expected = {child0, copy, child1}; - EXPECT_EQ(parent->getItems("tag1"), expected); - EXPECT_EQ(copy->data<double>(), 43.0); - - // undoing command - command->undo(); - expected = {child0, child1}; - EXPECT_EQ(parent->getItems("tag1"), expected); - EXPECT_FALSE(command->isObsolete()); -} - -//! Attempt to copy item to invalid tag - -TEST_F(CopyItemCommandTest, invalidCopyAttempt) -{ - SessionModel model; - - // parent with children and data - auto parent = model.insertItem<CompoundItem>(model.rootItem()); - parent->addProperty("thickness", 42.0); - parent->registerTag(TagInfo::universalTag("tag1"), /*set_as_default*/ true); - - auto child0 = model.insertItem<SessionItem>(parent); - child0->setData(42.0); - - // making copy of child - auto command = std::make_unique<CopyItemCommand>(child0, parent, TagRow{"thickness", 0}); - command->execute(); - - // checking that parent has now three children - EXPECT_TRUE(command->isObsolete()); - EXPECT_EQ(std::get<SessionItem*>(command->result()), nullptr); - - // undoing of obsolete command is not possible - EXPECT_THROW(command->undo(), std::runtime_error); -} diff --git a/mvvm/tests/testmodel/customvariants.test.cpp b/mvvm/tests/testmodel/customvariants.test.cpp deleted file mode 100644 index 57a5df4d6f9037f755375e814dba4cbb51d55bd7..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/customvariants.test.cpp +++ /dev/null @@ -1,248 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/customvariants.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/model/comboproperty.h" -#include "mvvm/model/customvariants.h" -#include "mvvm/model/externalproperty.h" -#include "mvvm/model/itemutils.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/model/taginfo.h" -#include "mvvm/model/variant_constants.h" -#include <QColor> -#include <functional> -#include <memory> - -using namespace ModelView; - -class CustomVariantsTest : public ::testing::Test { -public: - ~CustomVariantsTest(); - - template <typename T> QVariant variantFromArgument(const T& value) - { - return QVariant::fromValue(value); - } -}; - -CustomVariantsTest::~CustomVariantsTest() = default; - -//! To keep under control implicit type conversion. - -TEST_F(CustomVariantsTest, VariantFromTemplateArgument) -{ - EXPECT_EQ(variantFromArgument(true).typeName(), GUI::Constants::bool_type_name); - EXPECT_EQ(variantFromArgument(1).typeName(), GUI::Constants::int_type_name); - EXPECT_EQ(variantFromArgument(42.0).typeName(), GUI::Constants::double_type_name); - EXPECT_EQ(variantFromArgument(std::string("abc")).typeName(), GUI::Constants::string_type_name); -} - -//! Variant compatibility. - -TEST_F(CustomVariantsTest, VariantName) -{ - const std::vector<double> vec{1, 2}; - const ComboProperty combo = ComboProperty::createFrom({"a1", "a2", "s3"}); - EXPECT_EQ(Utils::VariantName(QVariant()), GUI::Constants::invalid_type_name); - EXPECT_EQ(Utils::VariantName(QVariant::fromValue(true)), GUI::Constants::bool_type_name); - EXPECT_EQ(Utils::VariantName(QVariant::fromValue(1)), GUI::Constants::int_type_name); - EXPECT_EQ(Utils::VariantName(QVariant::fromValue(42.0)), GUI::Constants::double_type_name); - EXPECT_EQ(Utils::VariantName(QVariant::fromValue(std::string("string"))), - GUI::Constants::string_type_name); - EXPECT_EQ(Utils::VariantName(QVariant::fromValue(vec)), - GUI::Constants::vector_double_type_name); - EXPECT_EQ(Utils::VariantName(QVariant::fromValue(combo)), - GUI::Constants::comboproperty_type_name); - EXPECT_EQ(Utils::VariantName(QVariant::fromValue(QColor(Qt::red))), - GUI::Constants::qcolor_type_name); - EXPECT_EQ(Utils::VariantName(QVariant::fromValue(ExternalProperty())), - GUI::Constants::extproperty_type_name); - EXPECT_EQ(Utils::VariantName(QVariant::fromValue(RealLimits())), - GUI::Constants::reallimits_type_name); -} - -//! Variant compatibility. - -TEST_F(CustomVariantsTest, CompatibleVariantTypes) -{ - QVariant undefined; - QVariant bool_variant = QVariant::fromValue(true); - QVariant int_variant = QVariant::fromValue(1); - QVariant double_variant = QVariant::fromValue(42.0); - QVariant string_variant = QVariant::fromValue(std::string("string")); - std::vector<double> vec{1, 2}; - QVariant vector_variant = QVariant::fromValue(vec); - ComboProperty combo = ComboProperty::createFrom({"a1", "a2", "s3"}); - QVariant combo_variant = QVariant::fromValue(combo); - QVariant color_variant = QVariant::fromValue(QColor(Qt::red)); - QVariant extprop_variant = QVariant::fromValue(ExternalProperty()); - QVariant limits_variant = QVariant::fromValue(RealLimits()); - - std::vector<QVariant> variants = {bool_variant, int_variant, double_variant, - string_variant, vector_variant, combo_variant, - color_variant, extprop_variant, limits_variant}; - for (size_t i = 0; i < variants.size(); ++i) { - EXPECT_TRUE(Utils::CompatibleVariantTypes(undefined, variants[i])); - EXPECT_FALSE(Utils::VariantType(undefined) == Utils::VariantType(variants[i])); - for (size_t j = 0; j < variants.size(); ++j) { - if (i == j) { - EXPECT_TRUE(Utils::VariantType(variants[i]) == Utils::VariantType(variants[j])); - EXPECT_TRUE(Utils::CompatibleVariantTypes(variants[i], variants[j])); - } else { - EXPECT_FALSE(Utils::CompatibleVariantTypes(variants[i], variants[j])); - EXPECT_FALSE(Utils::VariantType(variants[i]) == Utils::VariantType(variants[j])); - } - } - } -} - -//! Test variant equality reported by GUI::Session::ItemUtils::isTheSame - -TEST_F(CustomVariantsTest, IsTheSameVariant) -{ - const std::vector<double> vec1{1, 2}; - const std::vector<double> vec2{1, 2, 3}; - const ComboProperty combo1 = ComboProperty::createFrom({"a1", "a2"}); - const ComboProperty combo2 = ComboProperty::createFrom({"b1"}); - const ExternalProperty extprop1; - const ExternalProperty extprop2("abc", QColor(Qt::red), "123"); - const RealLimits lim1; - const RealLimits lim2 = RealLimits::limited(1.0, 2.0); - - ComboProperty combo3 = ComboProperty::createFrom({"e1", "e2"}); - ComboProperty combo4 = ComboProperty::createFrom({"e1", "e2"}); - combo3.setValue("e1"); - combo4.setValue("e2"); - - std::vector<QVariant> variants = {QVariant(), - QVariant::fromValue(true), - QVariant::fromValue(false), - QVariant::fromValue(1), - QVariant::fromValue(2), - QVariant::fromValue(42.0), - QVariant::fromValue(43.0), - QVariant::fromValue(std::string("string1")), - QVariant::fromValue(std::string("string2")), - QVariant::fromValue(vec1), - QVariant::fromValue(vec2), - QVariant::fromValue(combo1), - QVariant::fromValue(combo2), - QVariant::fromValue(QColor(Qt::red)), - QVariant::fromValue(QColor(Qt::green)), - QVariant::fromValue(extprop1), - QVariant::fromValue(extprop2), - QVariant::fromValue(lim1), - QVariant::fromValue(lim2), - QVariant::fromValue(combo3), - QVariant::fromValue(combo4)}; - - for (size_t i = 0; i < variants.size(); ++i) { - for (size_t j = 0; j < variants.size(); ++j) { - if (i == j) - EXPECT_TRUE(Utils::IsTheSame(variants[i], variants[j])); - else - EXPECT_FALSE(Utils::IsTheSame(variants[i], variants[j])); - } - } -} - -//! Checks if ComboProperty based variant is the same. - -TEST_F(CustomVariantsTest, IsTheSameComboProperty) -{ - ComboProperty combo1 = ComboProperty::createFrom({"a1", "a2"}); - ComboProperty combo2 = ComboProperty::createFrom({"a1", "a2"}); - - EXPECT_TRUE(Utils::IsTheSame(QVariant::fromValue(combo1), QVariant::fromValue(combo1))); - - combo1.setValue("a1"); - combo2.setValue("a2"); - EXPECT_FALSE(Utils::IsTheSame(QVariant::fromValue(combo1), QVariant::fromValue(combo2))); - - QVariant v1 = QVariant::fromValue(combo1); - QVariant v2 = QVariant::fromValue(combo2); - EXPECT_FALSE(Utils::IsTheSame(v1, v2)); -} - -//! Test toQtVAriant function. - -TEST_F(CustomVariantsTest, toQtVariant) -{ - // from Variant based on std::string to variant based on QString - QVariant stdstring_variant = QVariant::fromValue(std::string("abc")); - QVariant qstring_variant = QVariant::fromValue(QString("abc")); - QVariant converted = Utils::toQtVariant(stdstring_variant); - - EXPECT_FALSE(qstring_variant == stdstring_variant); - EXPECT_TRUE(qstring_variant == converted); - - // Double variant should be unchanged - QVariant value(42.0); - EXPECT_TRUE(Utils::toQtVariant(value) == QVariant::fromValue(42.0)); - - QVariant invalid; - EXPECT_FALSE(Utils::toQtVariant(invalid).isValid()); -} - -//! Test translation of variants - -TEST_F(CustomVariantsTest, toCustomVariant) -{ - // from Variant based on QString to variant based on std::string - QVariant stdstring_variant = QVariant::fromValue(std::string("abc")); - QVariant qstring_variant = QVariant::fromValue(QString("abc")); - QVariant converted = Utils::toCustomVariant(qstring_variant); - - EXPECT_FALSE(qstring_variant == stdstring_variant); - EXPECT_TRUE(stdstring_variant == converted); - - // Double variant should be unchanged - QVariant value(42.0); - EXPECT_TRUE(Utils::toCustomVariant(value) == QVariant::fromValue(42.0)); - - QVariant invalid; - EXPECT_FALSE(Utils::toCustomVariant(invalid).isValid()); -} - -//! Checks all functions related to variant types. - -// FIXME replace tests in loop with parameterized tests - -TEST_F(CustomVariantsTest, isVariantType) -{ - using is_variant_t = std::function<bool(const QVariant&)>; - - std::vector<std::pair<QVariant, is_variant_t>> data = { - {QVariant::fromValue(true), Utils::IsBoolVariant}, - {QVariant::fromValue(1), Utils::IsIntVariant}, - {QVariant::fromValue(42.0), Utils::IsDoubleVariant}, - {QVariant::fromValue(ComboProperty()), Utils::IsComboVariant}, - {QVariant::fromValue(std::string("string1")), Utils::IsStdStringVariant}, - {QVariant::fromValue(std::vector<double>({1, 2})), Utils::IsDoubleVectorVariant}, - {QVariant::fromValue(QColor(Qt::red)), Utils::IsColorVariant}, - {QVariant::fromValue(ExternalProperty()), Utils::IsExtPropertyVariant}, - {QVariant::fromValue(RealLimits()), Utils::IsRealLimitsVariant}}; - - for (size_t i = 0; i < data.size(); ++i) { - auto is_variant_func = data[i].second; - for (size_t j = 0; j < data.size(); ++j) { - auto variant = data[j].first; - if (i == j) - EXPECT_TRUE(is_variant_func(variant)); - else - EXPECT_FALSE(is_variant_func(variant)); - } - } -} diff --git a/mvvm/tests/testmodel/data1ditem.test.cpp b/mvvm/tests/testmodel/data1ditem.test.cpp deleted file mode 100644 index 4e8e5a1d077d8e2a8f990396e61f0d1e757210f6..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/data1ditem.test.cpp +++ /dev/null @@ -1,202 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/data1ditem.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mockwidgets.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/standarditems/axisitems.h" -#include "mvvm/standarditems/data1ditem.h" -#include <stdexcept> - -using namespace ModelView; -using ::testing::_; - -//! Testing Data1DItem. - -class Data1DItemTest : public ::testing::Test { -public: - ~Data1DItemTest(); -}; - -Data1DItemTest::~Data1DItemTest() = default; - -//! Initial state. - -TEST_F(Data1DItemTest, initialState) -{ - Data1DItem item; - - EXPECT_EQ(item.getItem(Data1DItem::T_AXIS), nullptr); - EXPECT_EQ(item.binCenters(), std::vector<double>()); - EXPECT_EQ(item.binValues(), std::vector<double>()); - EXPECT_EQ(item.binErrors(), std::vector<double>()); - EXPECT_FALSE(item.hasData()); -} - -//! Checking the method ::setFixedBinAxis. - -TEST_F(Data1DItemTest, setFixedBinAxis) -{ - Data1DItem item; - - item.setAxis<FixedBinAxisItem>(5, 0.0, 5.0); - - // check type of the axis - EXPECT_TRUE(item.item<FixedBinAxisItem>(Data1DItem::T_AXIS) != nullptr); - - // check bin centers and values - std::vector<double> expected_centers = {0.5, 1.5, 2.5, 3.5, 4.5}; - EXPECT_EQ(item.binCenters(), expected_centers); - std::vector<double> expected_values = std::vector<double>(expected_centers.size(), 0.0); - EXPECT_EQ(item.binValues(), expected_values); - - // setting another axis - // for the moment we have disabled possibility to re-create axes to faciltate undo/redo - // item.setAxis(FixedBinAxisItem::create(1, 1.0, 2.0)); - // expected_centers = {1.5}; - // EXPECT_EQ(item.binCenters(), expected_centers); - // expected_values = {0.0}; - // EXPECT_EQ(item.binValues(), expected_values); -} - -//! Sets fixed bin axis via templated method. - -TEST_F(Data1DItemTest, setTemplatedFixedBinAxis) -{ - Data1DItem item; - - auto axis = item.setAxis<FixedBinAxisItem>(5, 0.0, 5.0); - - // check type of the axis - EXPECT_EQ(item.item<FixedBinAxisItem>(Data1DItem::T_AXIS), axis); - - // check bin centers and values - std::vector<double> expected_centers = {0.5, 1.5, 2.5, 3.5, 4.5}; - EXPECT_EQ(item.binCenters(), expected_centers); - std::vector<double> expected_values = std::vector<double>(expected_centers.size(), 0.0); - EXPECT_EQ(item.binValues(), expected_values); -} - -//! Sets fixed bin axis via templated method. - -TEST_F(Data1DItemTest, setTemplatedFixedBinAxisInModelContext) -{ - SessionModel model; - auto dataItem = model.insertItem<Data1DItem>(); - - auto axis = dataItem->setAxis<FixedBinAxisItem>(5, 0.0, 5.0); - - // check type of the axis - EXPECT_EQ(dataItem->item<FixedBinAxisItem>(Data1DItem::T_AXIS), axis); - - // check bin centers and values - std::vector<double> expected_centers = {0.5, 1.5, 2.5, 3.5, 4.5}; - EXPECT_EQ(dataItem->binCenters(), expected_centers); - std::vector<double> expected_values = std::vector<double>(expected_centers.size(), 0.0); - EXPECT_EQ(dataItem->binValues(), expected_values); -} - -//! Sets fixed bin axis via model context. -// FIXME Not clear if this method should be used - -TEST_F(Data1DItemTest, setFixedBinAxisInModel) -{ - SessionModel model; - - auto dataItem = model.insertItem<Data1DItem>(); - model.insertItem<FixedBinAxisItem>(dataItem)->setParameters(5, 0.0, 5.0); - - // check type of the axis - EXPECT_TRUE(dataItem->item<FixedBinAxisItem>(Data1DItem::T_AXIS) != nullptr); - - // check bin centers and values - std::vector<double> expected_centers = {0.5, 1.5, 2.5, 3.5, 4.5}; - EXPECT_EQ(dataItem->binCenters(), expected_centers); - std::vector<double> expected_values = std::vector<double>(expected_centers.size(), 0.0); - EXPECT_TRUE(dataItem->binValues().empty()); -} - -//! Checking the method ::setValues. - -TEST_F(Data1DItemTest, setValues) -{ - Data1DItem item; - - // check that it is not possible to set content to uninitialized axis - std::vector<double> expected_content = {1.0, 2.0, 3.0}; - EXPECT_THROW(item.setValues(expected_content), std::runtime_error); - - item.setAxis<FixedBinAxisItem>(3, 0.0, 3.0); - item.setValues(expected_content); - EXPECT_EQ(item.binValues(), expected_content); -} - -//! Checking the method ::setErrors. - -TEST_F(Data1DItemTest, setErrors) -{ - Data1DItem item; - - // check that it is not possible to errors to uninitialized axis - std::vector<double> expected_errors = {10.0, 20.0, 30.0}; - - EXPECT_THROW(item.setErrors(expected_errors), std::runtime_error); - - item.setAxis<FixedBinAxisItem>(3, 0.0, 3.0); - item.setErrors(expected_errors); - - EXPECT_EQ(item.binErrors(), expected_errors); -} - -//! Checking the signals when axes changed. - -TEST_F(Data1DItemTest, checkSignalsOnAxisChange) -{ - SessionModel model; - auto item = model.insertItem<Data1DItem>(); - - MockWidgetForItem widget(item); - - const std::string expected_value_tag{Data1DItem::P_VALUES}; - const TagRow expected_axis_tagrow{Data1DItem::T_AXIS, 0}; - - EXPECT_CALL(widget, onDataChange(_, _)).Times(0); - EXPECT_CALL(widget, onPropertyChange(item, expected_value_tag)).Times(1); - EXPECT_CALL(widget, onChildPropertyChange(_, _)).Times(2); - EXPECT_CALL(widget, onItemInserted(item, expected_axis_tagrow)).Times(1); - EXPECT_CALL(widget, onAboutToRemoveItem(_, _)).Times(0); - - // trigger change - item->setAxis<FixedBinAxisItem>(3, 0.0, 3.0); -} - -//! Checking the signals when bin values changed. - -TEST_F(Data1DItemTest, checkSignalsOnBinValuesChange) -{ - SessionModel model; - auto item = model.insertItem<Data1DItem>(); - item->setAxis<FixedBinAxisItem>(3, 0.0, 3.0); - - MockWidgetForItem widget(item); - - EXPECT_CALL(widget, onDataChange(_, _)).Times(0); - EXPECT_CALL(widget, onPropertyChange(item, Data1DItem::P_VALUES)).Times(1); - EXPECT_CALL(widget, onChildPropertyChange(_, _)).Times(0); - EXPECT_CALL(widget, onItemInserted(_, _)).Times(0); - EXPECT_CALL(widget, onAboutToRemoveItem(_, _)).Times(0); - - // trigger change - item->setValues(std::vector<double>{1.0, 2.0, 3.0}); -} diff --git a/mvvm/tests/testmodel/data2ditem.test.cpp b/mvvm/tests/testmodel/data2ditem.test.cpp deleted file mode 100644 index 9b4985bdbcb0d331959858e5e4c7107e29ed5a76..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/data2ditem.test.cpp +++ /dev/null @@ -1,122 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/data2ditem.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mockwidgets.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/standarditems/axisitems.h" -#include "mvvm/standarditems/data2ditem.h" -#include <stdexcept> - -using namespace ModelView; -using ::testing::_; - -//! Testing Data1DItem. - -class Data2DItemTest : public ::testing::Test { -public: - ~Data2DItemTest(); -}; - -Data2DItemTest::~Data2DItemTest() = default; - -//! Initial state. - -TEST_F(Data2DItemTest, initialState) -{ - Data2DItem item; - - EXPECT_EQ(item.xAxis(), nullptr); - EXPECT_EQ(item.yAxis(), nullptr); - EXPECT_EQ(item.content(), std::vector<double>()); - EXPECT_TRUE(item.hasData()); - EXPECT_TRUE(item.data<std::vector<double>>().empty()); -} - -//! Checking the method ::setAxis. - -TEST_F(Data2DItemTest, setAxes) -{ - Data2DItem item; - - const int nx = 5, ny = 3; - item.setAxes(FixedBinAxisItem::create(nx, 0.0, 5.0), FixedBinAxisItem::create(ny, 0.0, 3.0)); - - // checking type of the axis - EXPECT_TRUE(item.item<FixedBinAxisItem>(Data2DItem::T_XAXIS) != nullptr); - EXPECT_TRUE(item.item<FixedBinAxisItem>(Data2DItem::T_YAXIS) != nullptr); - - // checking bin values - auto values = item.content(); - EXPECT_EQ(values.size(), nx * ny); - EXPECT_EQ(std::accumulate(values.begin(), values.end(), 0), 0.0); -} - -//! Checking the method ::setContent. - -TEST_F(Data2DItemTest, setContent) -{ - Data2DItem item; - - // check that it is not possible to set content to uninitialized axis - std::vector<double> expected_content = {1.0, 2.0}; - EXPECT_THROW(item.setContent(expected_content), std::runtime_error); - - const int nx = 1, ny = 2; - item.setAxes(FixedBinAxisItem::create(nx, 0.0, 5.0), FixedBinAxisItem::create(ny, 0.0, 3.0)); - - item.setContent(expected_content); - EXPECT_EQ(item.content(), expected_content); -} - -//! Checking the signals when axes changed. - -TEST_F(Data2DItemTest, checkSignalsOnAxisChange) -{ - SessionModel model; - auto item = model.insertItem<Data2DItem>(); - - FixedBinAxisItem::create(3, 0.0, 3.0); - - MockWidgetForItem widget(item); - - EXPECT_CALL(widget, onDataChange(item, ItemDataRole::DATA)).Times(1); // values should change - EXPECT_CALL(widget, onPropertyChange(_, _)).Times(0); - EXPECT_CALL(widget, onChildPropertyChange(_, _)).Times(0); - EXPECT_CALL(widget, onItemInserted(item, _)).Times(2); - EXPECT_CALL(widget, onAboutToRemoveItem(_, _)).Times(0); - - // trigger change - item->setAxes(FixedBinAxisItem::create(1, 0.0, 5.0), FixedBinAxisItem::create(3, 0.0, 3.0)); -} - -//! Checking the signals when content changed. - -TEST_F(Data2DItemTest, checkSignalsOnContentChange) -{ - SessionModel model; - auto item = model.insertItem<Data2DItem>(); - item->setAxes(FixedBinAxisItem::create(1, 0.0, 5.0), FixedBinAxisItem::create(3, 0.0, 3.0)); - - MockWidgetForItem widget(item); - - EXPECT_CALL(widget, onDataChange(item, ItemDataRole::DATA)).Times(1); // values should change - EXPECT_CALL(widget, onPropertyChange(_, _)).Times(0); - EXPECT_CALL(widget, onChildPropertyChange(_, _)).Times(0); - EXPECT_CALL(widget, onItemInserted(_, _)).Times(0); - EXPECT_CALL(widget, onAboutToRemoveItem(_, _)).Times(0); - - // trigger change - item->setContent(std::vector<double>{1.0, 2.0, 3.0}); -} diff --git a/mvvm/tests/testmodel/externalproperty.test.cpp b/mvvm/tests/testmodel/externalproperty.test.cpp deleted file mode 100644 index d2df92331c7638cc429ebc7c579ed4a93bb04084..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/externalproperty.test.cpp +++ /dev/null @@ -1,75 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/externalproperty.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/model/comparators.h" -#include "mvvm/model/externalproperty.h" - -using namespace ModelView; - -class ExternalPropertyTest : public ::testing::Test { -public: - ~ExternalPropertyTest(); -}; - -ExternalPropertyTest::~ExternalPropertyTest() = default; - -TEST_F(ExternalPropertyTest, initialState) -{ - ExternalProperty property; - EXPECT_FALSE(property.isValid()); - EXPECT_EQ(property.text(), ""); - EXPECT_EQ(property.identifier(), ""); - EXPECT_FALSE(property.color().isValid()); -} - -TEST_F(ExternalPropertyTest, constructor) -{ - ExternalProperty property("text", QColor(Qt::red), "123"); - EXPECT_TRUE(property.isValid()); - EXPECT_EQ(property.text(), "text"); - EXPECT_EQ(property.color(), QColor("red")); - EXPECT_EQ(property.identifier(), "123"); -} - -TEST_F(ExternalPropertyTest, equalityOperators) -{ - ExternalProperty prop1a; - ExternalProperty prop1b; - - EXPECT_TRUE(prop1a == prop1b); - EXPECT_FALSE(prop1a < prop1b); - - ExternalProperty prop2a("text", QColor(Qt::red)); - ExternalProperty prop2b("text", QColor(Qt::red)); - EXPECT_TRUE(prop2a == prop2b); - EXPECT_FALSE(prop2a < prop2b); - - EXPECT_FALSE(prop1a == prop2a); -} - -TEST_F(ExternalPropertyTest, variantEquality) -{ - if (Comparators::registered()) { - ExternalProperty prop1a; - ExternalProperty prop1b; - EXPECT_TRUE(QVariant::fromValue(prop1a) == QVariant::fromValue(prop1b)); - - ExternalProperty prop2a("text", QColor(Qt::red)); - ExternalProperty prop2b("text", QColor(Qt::red)); - EXPECT_TRUE(QVariant::fromValue(prop2a) == QVariant::fromValue(prop2b)); - - EXPECT_FALSE(QVariant::fromValue(prop1a) == QVariant::fromValue(prop2a)); - } -} diff --git a/mvvm/tests/testmodel/fileutils.test.cpp b/mvvm/tests/testmodel/fileutils.test.cpp deleted file mode 100644 index 09e4fac3968aa7959b34306cd252a5454f758d66..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/fileutils.test.cpp +++ /dev/null @@ -1,112 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/fileutils.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "folderbasedtest.h" -#include "google_test.h" -#include "mvvm/utils/fileutils.h" -#include "test_utils.h" -#include <QDir> -#include <stdexcept> -#include <string> - -using namespace ModelView; - -class FileUtilsTest : public FolderBasedTest { -public: - FileUtilsTest() : FolderBasedTest("test_FileUtils") {} - ~FileUtilsTest(); -}; - -FileUtilsTest::~FileUtilsTest() = default; - -TEST_F(FileUtilsTest, exists) -{ - EXPECT_TRUE(Utils::exists(testPath())); - EXPECT_FALSE(Utils::exists("")); - EXPECT_FALSE(Utils::exists(std::string("abc"))); -} - -TEST_F(FileUtilsTest, create_directory) -{ - std::string dirname = testPath() + std::string("/") + "subdir"; - Utils::remove(dirname); - - EXPECT_TRUE(Utils::create_directory(dirname)); - EXPECT_TRUE(Utils::exists(dirname)); -} - -TEST_F(FileUtilsTest, remove_all) -{ - std::string dirname = testPath() + std::string("/") + "subdir2"; - Utils::create_directory(dirname); - - EXPECT_TRUE(Utils::exists(dirname)); - Utils::remove_all((dirname)); - EXPECT_FALSE(Utils::exists(dirname)); -} - -TEST_F(FileUtilsTest, base_name) -{ - std::string filename = testPath() + std::string("/testmodel/fileutils.test.cpp"); - std::string base_name = Utils::base_name(filename); - - EXPECT_EQ("fileutils.test", base_name); -} - -TEST_F(FileUtilsTest, FindFiles) -{ - TestUtils::CreateTestFile(testPath(), "a.txt"); - TestUtils::CreateTestFile(testPath(), "name0.json"); - TestUtils::CreateTestFile(testPath(), "name1.json"); - - auto found_files = Utils::FindFiles(testPath(), ".json"); - - ASSERT_EQ(found_files.size(), 2); - EXPECT_NE(found_files.end(), std::find(found_files.begin(), found_files.end(), - Utils::join(testPath(), "name0.json"))); - EXPECT_NE(found_files.end(), std::find(found_files.begin(), found_files.end(), - Utils::join(testPath(), "name1.json"))); -} - -TEST_F(FileUtilsTest, parent_path) -{ - // parent path of testPath() is the main test folder - // "<build>/test_output/test_FileUtils" -> "<build>/test_output/" - EXPECT_EQ(Utils::parent_path(testPath()), TestUtils::TestOutputDir()); - - // "<build>/test_output/test_FileUtils/a.txt" -> "<build>/test_output/test_FileUtils/" - auto filename = TestUtils::CreateTestFile(testPath(), "a.txt"); - EXPECT_EQ(Utils::parent_path(filename), testPath()); -} - -TEST_F(FileUtilsTest, is_empty) -{ - // creating new empty directory - std::string dirname = testPath() + std::string("/") + "subdir_is_empty"; - Utils::remove_all(dirname); - Utils::create_directory(dirname); - - // it should be empty - EXPECT_TRUE(Utils::is_empty(dirname)); - - // creating file in it, directory should be not empty - auto filename = TestUtils::CreateTestFile(dirname, "a.txt"); - EXPECT_FALSE(Utils::is_empty(dirname)); - // file itself should be not empty - EXPECT_FALSE(Utils::is_empty(dirname)); - - // creating empty file - auto empty_filename = TestUtils::CreateEmptyFile(dirname, "a2.txt"); - EXPECT_TRUE(Utils::is_empty(empty_filename)); -} diff --git a/mvvm/tests/testmodel/graphitem.test.cpp b/mvvm/tests/testmodel/graphitem.test.cpp deleted file mode 100644 index ee96b473a653aa42f336b290b043696bdbf5bbe0..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/graphitem.test.cpp +++ /dev/null @@ -1,177 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/graphitem.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mockwidgets.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/standarditems/axisitems.h" -#include "mvvm/standarditems/data1ditem.h" -#include "mvvm/standarditems/graphitem.h" -#include "mvvm/standarditems/linkeditem.h" -#include "mvvm/standarditems/plottableitems.h" -#include <QColor> - -using namespace ModelView; -using ::testing::_; - -//! Testing GraphItem. - -class GraphItemTest : public ::testing::Test { -public: - ~GraphItemTest(); -}; - -GraphItemTest::~GraphItemTest() = default; - -//! Initial state. - -TEST_F(GraphItemTest, initialState) -{ - GraphItem item; - EXPECT_TRUE(item.dataItem() == nullptr); - EXPECT_EQ(item.binCenters(), std::vector<double>{}); - EXPECT_EQ(item.binValues(), std::vector<double>{}); - EXPECT_EQ(item.binErrors(), std::vector<double>{}); - EXPECT_EQ(item.colorName(), std::string("#000000")); -} - -//! Setting dataItem in model context. - -TEST_F(GraphItemTest, setDataItem) -{ - SessionModel model; - auto data_item = model.insertItem<Data1DItem>(); - auto graph_item = model.insertItem<GraphItem>(); - - graph_item->setDataItem(data_item); - - EXPECT_EQ(graph_item->dataItem(), data_item); -} - -//! Setting dataItem in model context. - -TEST_F(GraphItemTest, binValues) -{ - SessionModel model; - auto data_item = model.insertItem<Data1DItem>(); - auto graph_item = model.insertItem<GraphItem>(); - - std::vector<double> expected_values = {1.0, 2.0, 3.0}; - std::vector<double> expected_centers = {0.5, 1.5, 2.5}; - data_item->setAxis<FixedBinAxisItem>(3, 0.0, 3.0); - data_item->setValues(expected_values); - - graph_item->setDataItem(data_item); - - EXPECT_EQ(graph_item->binValues(), expected_values); - EXPECT_EQ(graph_item->binCenters(), expected_centers); -} - -//! Setting dataItem with errors - -TEST_F(GraphItemTest, binErrors) -{ - SessionModel model; - auto data_item = model.insertItem<Data1DItem>(); - auto graph_item = model.insertItem<GraphItem>(); - - std::vector<double> expected_values = {1.0, 2.0, 3.0}; - std::vector<double> expected_centers = {0.5, 1.5, 2.5}; - std::vector<double> expected_errors = {0.1, 0.2, 0.3}; - data_item->setAxis<FixedBinAxisItem>(3, 0.0, 3.0); - data_item->setValues(expected_values); - data_item->setErrors(expected_errors); - - graph_item->setDataItem(data_item); - - EXPECT_EQ(graph_item->binValues(), expected_values); - EXPECT_EQ(graph_item->binCenters(), expected_centers); - EXPECT_EQ(graph_item->binErrors(), expected_errors); -} - -//! Check unlinking when nullptr is set as Data1DItem. - -TEST_F(GraphItemTest, setNullData) -{ - SessionModel model; - auto data_item = model.insertItem<Data1DItem>(); - auto graph_item = model.insertItem<GraphItem>(); - - // preparing data item - std::vector<double> expected_values = {1.0, 2.0, 3.0}; - std::vector<double> expected_centers = {0.5, 1.5, 2.5}; - data_item->setAxis<FixedBinAxisItem>(3, 0.0, 3.0); - data_item->setValues(expected_values); - - graph_item->setDataItem(data_item); - EXPECT_EQ(graph_item->dataItem(), data_item); - - // setting null as data item - graph_item->setDataItem(nullptr); - EXPECT_TRUE(graph_item->dataItem() == nullptr); - EXPECT_EQ(graph_item->binCenters(), std::vector<double>{}); - EXPECT_EQ(graph_item->binValues(), std::vector<double>{}); - EXPECT_EQ(graph_item->binErrors(), std::vector<double>{}); -} - -//! Check signaling on set data item. - -TEST_F(GraphItemTest, onSetDataItem) -{ - SessionModel model; - auto data_item = model.insertItem<Data1DItem>(); - auto graph_item = model.insertItem<GraphItem>(); - - MockWidgetForItem widget(graph_item); - - EXPECT_CALL(widget, onDataChange(_, _)).Times(0); - EXPECT_CALL(widget, onPropertyChange(graph_item, GraphItem::P_LINK)).Times(1); - EXPECT_CALL(widget, onChildPropertyChange(_, _)).Times(0); - EXPECT_CALL(widget, onItemInserted(_, _)).Times(0); - EXPECT_CALL(widget, onAboutToRemoveItem(_, _)).Times(0); - - // performing action - graph_item->setDataItem(data_item); -} - -//! Sets GraphItem from another GraphItem - -TEST_F(GraphItemTest, setFromGraphItem) -{ - SessionModel model; - auto data_item = model.insertItem<Data1DItem>(); - auto graph_item = model.insertItem<GraphItem>(); - auto graph_item2 = model.insertItem<GraphItem>(); - - std::vector<double> expected_values = {1.0, 2.0, 3.0}; - std::vector<double> expected_centers = {0.5, 1.5, 2.5}; - data_item->setAxis<FixedBinAxisItem>(3, 0.0, 3.0); - data_item->setValues(expected_values); - - graph_item->setDataItem(data_item); - graph_item->penItem()->setProperty(PenItem::P_COLOR, QColor(Qt::red)); - - graph_item2->setFromGraphItem(graph_item); - - EXPECT_EQ(graph_item2->binValues(), expected_values); - EXPECT_EQ(graph_item2->binCenters(), expected_centers); - EXPECT_EQ(graph_item2->penItem()->property<QColor>(PenItem::P_COLOR), QColor(Qt::red)); -} - -TEST_F(GraphItemTest, penItem_setNamedColor) -{ - GraphItem item; - item.setNamedColor("mediumaquamarine"); - EXPECT_EQ(item.colorName(), std::string("#66cdaa")); -} diff --git a/mvvm/tests/testmodel/graphviewportitem.test.cpp b/mvvm/tests/testmodel/graphviewportitem.test.cpp deleted file mode 100644 index eb56ef723483fb6f3cd24aeec4b7dab8feebfbbe..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/graphviewportitem.test.cpp +++ /dev/null @@ -1,164 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/graphviewportitem.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mockwidgets.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/standarditems/axisitems.h" -#include "mvvm/standarditems/data1ditem.h" -#include "mvvm/standarditems/graphitem.h" -#include "mvvm/standarditems/graphviewportitem.h" - -using namespace ModelView; -using ::testing::_; - -//! Testing AxesItems. - -class GraphViewportItemTest : public ::testing::Test { -public: - ~GraphViewportItemTest(); -}; - -GraphViewportItemTest::~GraphViewportItemTest() = default; - -//! Initial state. - -TEST_F(GraphViewportItemTest, initialState) -{ - GraphViewportItem item; - EXPECT_EQ(item.xAxis()->modelType(), GUI::Constants::ViewportAxisItemType); - EXPECT_EQ(item.yAxis()->modelType(), GUI::Constants::ViewportAxisItemType); - EXPECT_EQ(item.graphItems().size(), 0); -} - -//! Add graph to viewport. - -TEST_F(GraphViewportItemTest, addItem) -{ - SessionModel model; - - auto viewport_item = model.insertItem<GraphViewportItem>(); - auto graph_item = model.insertItem<GraphItem>(viewport_item); - auto data_item = model.insertItem<Data1DItem>(); - - const std::vector<double> expected_values = {1.0, 2.0, 3.0}; - const std::vector<double> expected_centers = {0.5, 1.5, 2.5}; - data_item->setAxis<FixedBinAxisItem>(3, 0.0, 3.0); - data_item->setValues(expected_values); - - graph_item->setDataItem(data_item); - EXPECT_EQ(viewport_item->graphItems().size(), 1); - - // updating viewport to graph - viewport_item->setViewportToContent(); - - // x-axis of viewport should be set to FixedBinAxis of DataItem - auto xaxis = viewport_item->xAxis(); - EXPECT_DOUBLE_EQ(xaxis->property<double>(ViewportAxisItem::P_MIN), expected_centers[0]); - EXPECT_DOUBLE_EQ(xaxis->property<double>(ViewportAxisItem::P_MAX), expected_centers[2]); - - // y-axis of viewport should be set to min/max of expected_content - auto yaxis = viewport_item->yAxis(); - auto [expected_amin, expected_amax] = - std::minmax_element(std::begin(expected_values), std::end(expected_values)); - EXPECT_DOUBLE_EQ(yaxis->property<double>(ViewportAxisItem::P_MIN), *expected_amin); - EXPECT_DOUBLE_EQ(yaxis->property<double>(ViewportAxisItem::P_MAX), *expected_amax); -} - -//! Check signaling on set data item. - -TEST_F(GraphViewportItemTest, onAddItem) -{ - SessionModel model; - auto viewport_item = model.insertItem<GraphViewportItem>(); - - MockWidgetForItem widget(viewport_item); - - const TagRow expected_tagrow{ViewportItem::T_ITEMS, 0}; - EXPECT_CALL(widget, onDataChange(_, _)).Times(0); - EXPECT_CALL(widget, onPropertyChange(_, _)).Times(0); - EXPECT_CALL(widget, onChildPropertyChange(_, _)).Times(0); - EXPECT_CALL(widget, onItemInserted(viewport_item, expected_tagrow)).Times(1); - EXPECT_CALL(widget, onAboutToRemoveItem(_, _)).Times(0); - - // triggering action - model.insertItem<GraphItem>(viewport_item); -} - -//! Check signaling on set data item. - -TEST_F(GraphViewportItemTest, onSetDataItem) -{ - SessionModel model; - auto viewport_item = model.insertItem<GraphViewportItem>(); - - // setting upda tata item - auto data_item = model.insertItem<Data1DItem>(); - const std::vector<double> expected_values = {1.0, 2.0, 3.0}; - const std::vector<double> expected_centers = {0.5, 1.5, 2.5}; - data_item->setAxis<FixedBinAxisItem>(3, 0.0, 3.0); - data_item->setValues(expected_values); - - // inserting graph item - auto graph_item = model.insertItem<GraphItem>(viewport_item); - - MockWidgetForItem widget(viewport_item); - - EXPECT_CALL(widget, onDataChange(_, _)).Times(0); - EXPECT_CALL(widget, onPropertyChange(_, _)).Times(0); - EXPECT_CALL(widget, onChildPropertyChange(graph_item, GraphItem::P_LINK)).Times(1); - EXPECT_CALL(widget, onItemInserted(_, _)).Times(0); - EXPECT_CALL(widget, onAboutToRemoveItem(_, _)).Times(0); - - // triggering action - graph_item->setDataItem(data_item); -} - -//! Add graph to viewport. - -TEST_F(GraphViewportItemTest, setViewportToContentWithMargins) -{ - SessionModel model; - - auto viewport_item = model.insertItem<GraphViewportItem>(); - auto graph_item = model.insertItem<GraphItem>(viewport_item); - auto data_item = model.insertItem<Data1DItem>(); - - const std::vector<double> expected_values = {1.0, 2.0, 3.0}; - const std::vector<double> expected_centers = {0.5, 1.5, 2.5}; - data_item->setAxis<FixedBinAxisItem>(3, 0.0, 3.0); - data_item->setValues(expected_values); - - graph_item->setDataItem(data_item); - EXPECT_EQ(viewport_item->graphItems().size(), 1); - - // updating viewport to graph - const double bottom{0.1}, top{0.1}; - viewport_item->setViewportToContent(0.0, top, 0.0, bottom); - - // x-axis of viewport should be set to FixedBinAxis of DataItem - auto xaxis = viewport_item->xAxis(); - EXPECT_DOUBLE_EQ(xaxis->property<double>(ViewportAxisItem::P_MIN), expected_centers[0]); - EXPECT_DOUBLE_EQ(xaxis->property<double>(ViewportAxisItem::P_MAX), expected_centers[2]); - - // y-axis of viewport should be set to min/max of expected_content - auto yaxis = viewport_item->yAxis(); - auto [expected_amin, expected_amax] = - std::minmax_element(std::begin(expected_values), std::end(expected_values)); - - double expected_ymin = *expected_amin - (*expected_amax - *expected_amin) * bottom; - double expected_ymax = *expected_amax + (*expected_amax - *expected_amin) * top; - EXPECT_DOUBLE_EQ(yaxis->property<double>(ViewportAxisItem::P_MIN), expected_ymin); - EXPECT_DOUBLE_EQ(yaxis->property<double>(ViewportAxisItem::P_MAX), expected_ymax); -} diff --git a/mvvm/tests/testmodel/groupitem.test.cpp b/mvvm/tests/testmodel/groupitem.test.cpp deleted file mode 100644 index 6d2033f0a342b08f561e4739f02d79a9037111ae..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/groupitem.test.cpp +++ /dev/null @@ -1,39 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/groupitem.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/model/groupitem.h" -#include <stdexcept> - -using namespace ModelView; - -//! Testing GroupItem class. - -class GroupItemTest : public ::testing::Test { -public: - ~GroupItemTest(); -}; - -GroupItemTest::~GroupItemTest() = default; - -TEST_F(GroupItemTest, initialState) -{ - GroupItem item; - EXPECT_EQ(item.currentIndex(), -1); - EXPECT_EQ(item.currentItem(), nullptr); - EXPECT_EQ(item.currentType(), ""); - EXPECT_TRUE(item.hasData()); - EXPECT_TRUE(item.children().empty()); - EXPECT_THROW(item.setCurrentType("abc"), std::runtime_error); -} diff --git a/mvvm/tests/testmodel/insertnewitemcommand.test.cpp b/mvvm/tests/testmodel/insertnewitemcommand.test.cpp deleted file mode 100644 index af4b304f7c08f9cfe67a7c7dfe1c07204c1c33ff..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/insertnewitemcommand.test.cpp +++ /dev/null @@ -1,217 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/insertnewitemcommand.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/commands/insertnewitemcommand.h" -#include "mvvm/interfaces/itemfactoryinterface.h" -#include "mvvm/model/compounditem.h" -#include "mvvm/model/itempool.h" -#include "mvvm/model/itemutils.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/model/taginfo.h" -#include <stdexcept> - -using namespace ModelView; - -class InsertNewItemCommandTest : public ::testing::Test { -public: - ~InsertNewItemCommandTest(); - std::unique_ptr<InsertNewItemCommand> create_command(SessionItem* parent, std::string tag, - int row) - { - auto factory_func = [parent]() { - return parent->model()->factory()->createItem(GUI::Constants::BaseType); - }; - return std::make_unique<InsertNewItemCommand>(factory_func, parent, TagRow{tag, row}); - } -}; - -InsertNewItemCommandTest::~InsertNewItemCommandTest() = default; - -//! Insert new item through InsertNewItemCommand command. - -TEST_F(InsertNewItemCommandTest, insertNewItemCommand) -{ - SessionModel model; - - // command to insert item in a model - auto command = create_command(model.rootItem(), "", 0); - - // executing command - command->execute(); - EXPECT_EQ(model.rootItem()->childrenCount(), 1); - EXPECT_EQ(std::get<SessionItem*>(command->result()), model.rootItem()->getItem("", 0)); - EXPECT_EQ(command->isObsolete(), false); - - // undoing command - command->undo(); - EXPECT_EQ(model.rootItem()->childrenCount(), 0); - EXPECT_EQ(std::get<SessionItem*>(command->result()), nullptr); - EXPECT_EQ(command->isObsolete(), false); - - // executing again - command->execute(); - EXPECT_EQ(model.rootItem()->childrenCount(), 1); - EXPECT_EQ(std::get<SessionItem*>(command->result()), model.rootItem()->getItem("", 0)); - EXPECT_EQ(command->isObsolete(), false); -} - -//! Insert new item through InsertNewItemCommand command. - -TEST_F(InsertNewItemCommandTest, insertNewItemWithTagCommand) -{ - SessionModel model; - - // command to insert parent in the model - auto command1 = create_command(model.rootItem(), "", 0); - command1->execute(); // insertion - EXPECT_EQ(command1->isObsolete(), false); - - auto parent = std::get<SessionItem*>(command1->result()); - parent->registerTag(TagInfo::universalTag("tag1"), /*set_as_default*/ true); - EXPECT_EQ(parent->childrenCount(), 0); - - // command to insert child - auto command2 = create_command(parent, "tag1", 0); - command2->execute(); // insertion - EXPECT_EQ(command2->isObsolete(), false); - - EXPECT_EQ(parent->childrenCount(), 1); - EXPECT_EQ(Utils::ChildAt(parent, 0), std::get<SessionItem*>(command2->result())); - - // undoing command - command2->undo(); - EXPECT_EQ(parent->childrenCount(), 0); - EXPECT_EQ(nullptr, std::get<SessionItem*>(command2->result())); - EXPECT_EQ(command2->isObsolete(), false); -} - -//! Attempt to execute command twice. - -TEST_F(InsertNewItemCommandTest, attemptToExecuteTwice) -{ - SessionModel model; - // command to set same value - auto command = create_command(model.rootItem(), "", 0); - - // executing command - command->execute(); - EXPECT_THROW(command->execute(), std::runtime_error); -} - -//! Attempt to undo command twice. - -TEST_F(InsertNewItemCommandTest, attemptToUndoTwice) -{ - SessionModel model; - - // command to set same value - auto command = create_command(model.rootItem(), "", 0); - - // executing command - command->execute(); - command->undo(); - EXPECT_THROW(command->undo(), std::runtime_error); -} - -//! Attempt to insert second property to the compount item. - -TEST_F(InsertNewItemCommandTest, attemptInsertSecondProperty) -{ - SessionModel model; - auto parent = model.insertItem<CompoundItem>(); - parent->registerTag(TagInfo::propertyTag("radius", GUI::Constants::PropertyType)); - - // command to insert second property - auto factory_func = [parent]() { - return parent->model()->factory()->createItem(GUI::Constants::PropertyType); - }; - - // adding property to another tag is valid - InsertNewItemCommand command1(factory_func, parent, TagRow{"radius", -1}); - EXPECT_NO_THROW(command1.execute()); - EXPECT_FALSE(command1.isObsolete()); - EXPECT_EQ(std::get<SessionItem*>(command1.result()), parent->getItem("radius")); - - // adding second property to the same tag is not possible. Command should be in obsolete state - InsertNewItemCommand command2(factory_func, parent, TagRow{"radius", -1}); - EXPECT_NO_THROW(command2.execute()); - EXPECT_TRUE(command2.isObsolete()); - EXPECT_EQ(std::get<SessionItem*>(command2.result()), nullptr); - - // undoing failed command shouldn't be possible - EXPECT_THROW(command2.undo(), std::runtime_error); -} - -//! Insert new item through InsertNewItemCommand command. -//! We validate that undoing, and then redoing, would restore very first unique identifier. - -TEST_F(InsertNewItemCommandTest, insertNewPropertyItemPreservedId) -{ - SessionModel model; - // command to insert second property - auto factory_func = [&model]() { - return model.factory()->createItem(GUI::Constants::PropertyType); - }; - - EXPECT_EQ(model.rootItem()->childrenCount(), 0); - - InsertNewItemCommand command1(factory_func, model.rootItem(), TagRow{"", 0}); - command1.execute(); - - EXPECT_EQ(model.rootItem()->childrenCount(), 1); - auto orig_identifier = model.rootItem()->children()[0]->identifier(); - - command1.undo(); - EXPECT_EQ(model.rootItem()->childrenCount(), 0); - - command1.execute(); - EXPECT_EQ(model.rootItem()->childrenCount(), 1); - EXPECT_EQ(model.rootItem()->children()[0]->identifier(), orig_identifier); -} - -//! Insert new item through InsertNewItemCommand command. -//! We validate that undoing, and then redoing, would restore very first unique identifier. -//! Same as above, but we additionally controling item pool. - -TEST_F(InsertNewItemCommandTest, insertNewPropertyItemIdInPool) -{ - auto pool = std::make_shared<ItemPool>(); - SessionModel model("Model", pool); - // command to insert second property - auto factory_func = [&model]() { - return model.factory()->createItem(GUI::Constants::PropertyType); - }; - - EXPECT_EQ(model.rootItem()->childrenCount(), 0); - EXPECT_EQ(pool->size(), 1); // rootItem - - InsertNewItemCommand command1(factory_func, model.rootItem(), TagRow{"", 0}); - command1.execute(); - - EXPECT_EQ(model.rootItem()->childrenCount(), 1); - auto orig_identifier = model.rootItem()->children()[0]->identifier(); - EXPECT_EQ(pool->size(), 2); - - command1.undo(); - EXPECT_EQ(model.rootItem()->childrenCount(), 0); - - command1.execute(); - EXPECT_EQ(model.rootItem()->childrenCount(), 1); - auto restored_item = model.rootItem()->children()[0]; - EXPECT_EQ(restored_item->identifier(), orig_identifier); - EXPECT_EQ(model.findItem(orig_identifier), restored_item); - EXPECT_EQ(pool->item_for_key(orig_identifier), restored_item); -} diff --git a/mvvm/tests/testmodel/itemcatalogue.test.cpp b/mvvm/tests/testmodel/itemcatalogue.test.cpp deleted file mode 100644 index 75e11268b2f5f53242f887d72e33fd7c3b436e8e..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/itemcatalogue.test.cpp +++ /dev/null @@ -1,170 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/itemcatalogue.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/factories/itemcataloguefactory.h" -#include "mvvm/model/itemcatalogue.h" -#include "mvvm/model/propertyitem.h" -#include "mvvm/standarditems/vectoritem.h" -#include <stdexcept> - -using namespace ModelView; - -//! Testing ItemCatalogue construction - -class ItemCatalogueTest : public ::testing::Test { -public: - ~ItemCatalogueTest(); -}; - -ItemCatalogueTest::~ItemCatalogueTest() = default; - -TEST_F(ItemCatalogueTest, initialState) -{ - ItemCatalogue catalogue; - EXPECT_EQ(catalogue.itemCount(), 0); - EXPECT_EQ(catalogue.modelTypes(), std::vector<std::string>({})); - EXPECT_EQ(catalogue.labels(), std::vector<std::string>({})); -} - -TEST_F(ItemCatalogueTest, addItem) -{ - ItemCatalogue catalogue; - - catalogue.registerItem<PropertyItem>(); - - EXPECT_EQ(catalogue.itemCount(), 1); - - auto item = catalogue.create(GUI::Constants::PropertyType); - EXPECT_TRUE(dynamic_cast<PropertyItem*>(item.get()) != nullptr); - - // registration of second item is not allowed - EXPECT_THROW(catalogue.registerItem<PropertyItem>(), std::runtime_error); - - // item was not registered, creation not allowed - EXPECT_THROW(catalogue.create("non-registered"), std::runtime_error); - - // checking model types and labels - EXPECT_EQ(catalogue.modelTypes(), std::vector<std::string>({"Property"})); - EXPECT_EQ(catalogue.labels(), std::vector<std::string>({""})); -} - -TEST_F(ItemCatalogueTest, copyConstructor) -{ - ItemCatalogue catalogue; - catalogue.registerItem<PropertyItem>(); - - ItemCatalogue copy(catalogue); - - // creation of item using first catalogue - auto item = catalogue.create(GUI::Constants::PropertyType); - EXPECT_TRUE(dynamic_cast<PropertyItem*>(item.get()) != nullptr); - - // creation of item using catalogue copy - item = copy.create(GUI::Constants::PropertyType); - EXPECT_TRUE(dynamic_cast<PropertyItem*>(item.get()) != nullptr); - - // checking model types and labels in new catalogue - EXPECT_EQ(copy.modelTypes(), std::vector<std::string>({"Property"})); - EXPECT_EQ(copy.labels(), std::vector<std::string>({""})); - - // adding item to first catalogue but not the second - catalogue.registerItem<VectorItem>(); - item = catalogue.create(GUI::Constants::VectorItemType); - EXPECT_TRUE(dynamic_cast<VectorItem*>(item.get()) != nullptr); - - // copy of catalogue knows nothing about new VectorType - EXPECT_THROW(copy.create(GUI::Constants::VectorItemType), std::runtime_error); -} - -TEST_F(ItemCatalogueTest, assignmentOperator) -{ - ItemCatalogue catalogue; - catalogue.registerItem<PropertyItem>(); - - ItemCatalogue copy; - copy = catalogue; - - // creation of item using first catalogue - auto item = catalogue.create(GUI::Constants::PropertyType); - EXPECT_TRUE(dynamic_cast<PropertyItem*>(item.get()) != nullptr); - - // creation of item using catalogue copy - item = copy.create(GUI::Constants::PropertyType); - EXPECT_TRUE(dynamic_cast<PropertyItem*>(item.get()) != nullptr); -} - -TEST_F(ItemCatalogueTest, contains) -{ - ItemCatalogue catalogue; - catalogue.registerItem<PropertyItem>(); - - EXPECT_TRUE(catalogue.contains(GUI::Constants::PropertyType)); - EXPECT_FALSE(catalogue.contains(GUI::Constants::VectorItemType)); -} - -TEST_F(ItemCatalogueTest, defaultItemCatalogue) -{ - auto catalogue = CreateStandardItemCatalogue(); - - auto item = catalogue->create(GUI::Constants::BaseType); - EXPECT_TRUE(dynamic_cast<SessionItem*>(item.get()) != nullptr); - - item = catalogue->create(GUI::Constants::PropertyType); - EXPECT_TRUE(dynamic_cast<PropertyItem*>(item.get()) != nullptr); - - item = catalogue->create(GUI::Constants::VectorItemType); - EXPECT_TRUE(dynamic_cast<VectorItem*>(item.get()) != nullptr); - - item = catalogue->create(GUI::Constants::CompoundItemType); - EXPECT_TRUE(dynamic_cast<CompoundItem*>(item.get()) != nullptr); -} - -TEST_F(ItemCatalogueTest, addLabeledItem) -{ - ItemCatalogue catalogue; - catalogue.registerItem<PropertyItem>("property"); - catalogue.registerItem<VectorItem>("vector item"); - - // checking model types and labels - EXPECT_EQ(catalogue.modelTypes(), std::vector<std::string>({"Property", "Vector"})); - EXPECT_EQ(catalogue.labels(), std::vector<std::string>({"property", "vector item"})); -} - -TEST_F(ItemCatalogueTest, merge) -{ - ItemCatalogue catalogue1; - catalogue1.registerItem<PropertyItem>("property"); - catalogue1.registerItem<VectorItem>("vector"); - - ItemCatalogue catalogue2; - catalogue2.registerItem<CompoundItem>("compound"); - - // adding two catalogue together - catalogue1.merge(catalogue2); - - std::vector<std::string> expected_models = {GUI::Constants::PropertyType, - GUI::Constants::VectorItemType, - GUI::Constants::CompoundItemType}; - std::vector<std::string> expected_labels = {"property", "vector", "compound"}; - - EXPECT_EQ(catalogue1.modelTypes(), expected_models); - EXPECT_EQ(catalogue1.labels(), expected_labels); - - auto item = catalogue1.create(GUI::Constants::VectorItemType); - EXPECT_TRUE(dynamic_cast<VectorItem*>(item.get()) != nullptr); - - // duplications is not allowed - EXPECT_THROW(catalogue1.merge(catalogue2), std::runtime_error); -} diff --git a/mvvm/tests/testmodel/itemconverterfactory.test.cpp b/mvvm/tests/testmodel/itemconverterfactory.test.cpp deleted file mode 100644 index 51cfb4e6593c4e7ab8260c1558bd7e08951cd131..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/itemconverterfactory.test.cpp +++ /dev/null @@ -1,156 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/itemconverterfactory.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/factories/itemconverterfactory.h" -#include "mvvm/model/compounditem.h" -#include "mvvm/model/itemcatalogue.h" -#include "mvvm/model/propertyitem.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/model/sessionitemdata.h" -#include "mvvm/model/sessionmodel.h" -#include "test_utils.h" -#include <QJsonObject> - -using namespace ModelView; - -//! Checks converters generated by ItemFactoryConverter. - -class ItemConverterFactoryTest : public ::testing::Test { -public: - class TestItem : public CompoundItem { - public: - TestItem() : CompoundItem("TestItem") - { - setToolTip("compound"); - addProperty("Thickness", 42)->setToolTip("thickness")->setEditorType("abc"); - } - }; - - class TestModel : public SessionModel { - public: - TestModel() : SessionModel("TestModel") - { - auto catalogue = std::make_unique<ModelView::ItemCatalogue>(); - catalogue->registerItem<TestItem>(); - setItemCatalogue(std::move(catalogue)); - } - }; - - ItemConverterFactoryTest() : m_model(std::make_unique<TestModel>()) {} - - const ItemFactoryInterface* factory() const { return m_model->factory(); } - - std::unique_ptr<SessionModel> m_model; -}; - -//! Clone converter for simple property item. - -TEST_F(ItemConverterFactoryTest, propertyItemCloneConverter) -{ - auto converter = CreateItemCloneConverter(factory()); - - PropertyItem item; - item.setToolTip("abc"); - - auto object = converter->to_json(&item); - auto reco = converter->from_json(object); - - EXPECT_EQ(reco->modelType(), item.modelType()); - EXPECT_EQ(reco->displayName(), item.displayName()); - EXPECT_EQ(reco->toolTip(), std::string("abc")); - EXPECT_EQ(reco->itemData()->roles(), item.itemData()->roles()); - EXPECT_TRUE(reco->identifier() == item.identifier()); // identifier preserved -} - -//! Copy converter for simple property item. - -TEST_F(ItemConverterFactoryTest, propertyItemCopyConverter) -{ - auto converter = CreateItemCopyConverter(factory()); - - PropertyItem item; - item.setToolTip("abc"); - - auto object = converter->to_json(&item); - auto reco = converter->from_json(object); - - EXPECT_EQ(reco->modelType(), item.modelType()); - EXPECT_EQ(reco->displayName(), item.displayName()); - EXPECT_EQ(reco->toolTip(), std::string("abc")); - EXPECT_EQ(reco->itemData()->roles(), item.itemData()->roles()); - EXPECT_FALSE(reco->identifier() == item.identifier()); // identifier has changed -} - -//! Project converter for simple property item. -//! It preserves only identifier and data roles. - -TEST_F(ItemConverterFactoryTest, propertyItemProjectConverter) -{ - auto converter = CreateItemProjectConverter(factory()); - - PropertyItem item; - item.setToolTip("abc"); - - auto object = converter->to_json(&item); - auto reco = converter->from_json(object); - - EXPECT_EQ(reco->modelType(), item.modelType()); - EXPECT_EQ(reco->displayName(), item.displayName()); - EXPECT_EQ(reco->toolTip(), ""); // tooltips are not preserved - EXPECT_TRUE(reco->identifier() == item.identifier()); // identifier preserved -} - -//! Clone converter for simple property item. - -TEST_F(ItemConverterFactoryTest, testItemCloneConverter) -{ - auto converter = CreateItemCloneConverter(factory()); - - TestItem item; - item.setToolTip("abc"); - - auto object = converter->to_json(&item); - auto reco = converter->from_json(object); - - EXPECT_EQ(reco->modelType(), item.modelType()); - EXPECT_EQ(reco->displayName(), item.displayName()); - EXPECT_EQ(reco->toolTip(), std::string("abc")); // updated tooltip is preserved - EXPECT_EQ(reco->itemData()->roles(), item.itemData()->roles()); - EXPECT_TRUE(reco->identifier() == item.identifier()); // identifier preserved - EXPECT_EQ(reco->getItem("Thickness")->toolTip(), "thickness"); - EXPECT_EQ(reco->getItem("Thickness")->identifier(), item.getItem("Thickness")->identifier()); -} - -//! Clone converter for simple property item. -//! At this time - -TEST_F(ItemConverterFactoryTest, testItemProjectConverter) -{ - auto converter = CreateItemProjectConverter(factory()); - - TestItem item; - item.setToolTip("abc"); - - auto object = converter->to_json(&item); - auto reco = converter->from_json(object); - - EXPECT_EQ(reco->modelType(), item.modelType()); - EXPECT_EQ(reco->displayName(), item.displayName()); - EXPECT_EQ(reco->toolTip(), std::string("compound")); // initial tooltip exist - EXPECT_EQ(reco->itemData()->roles(), item.itemData()->roles()); - EXPECT_TRUE(reco->identifier() == item.identifier()); // identifier preserved - EXPECT_EQ(reco->getItem("Thickness")->toolTip(), "thickness"); - EXPECT_EQ(reco->getItem("Thickness")->identifier(), item.getItem("Thickness")->identifier()); -} diff --git a/mvvm/tests/testmodel/itemlistener.test.cpp b/mvvm/tests/testmodel/itemlistener.test.cpp deleted file mode 100644 index f8ea0bd6b89650b081e106c584c44d6c2497bd39..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/itemlistener.test.cpp +++ /dev/null @@ -1,110 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/itemlistener.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/model/propertyitem.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/signals/itemlistener.h" -#include <memory> - -using namespace ModelView; - -//! Testing ItemListener. - -class ItemListenerTest : public ::testing::Test { -public: - class TestController : public ItemListener<PropertyItem> { - public: - ~TestController(); - size_t ondata_change_call_count{0}; - size_t on_unsubscribe_call_count{0}; - void subscribe() - { - auto on_data_change = [this](SessionItem*, int) { ondata_change_call_count++; }; - setOnDataChange(on_data_change); - } - - void unsubscribe() { on_unsubscribe_call_count++; } - }; - - ~ItemListenerTest(); -}; - -ItemListenerTest::~ItemListenerTest() = default; -ItemListenerTest::TestController::~TestController() = default; - -//! Initial state. - -TEST_F(ItemListenerTest, initialState) -{ - TestController controller; - EXPECT_EQ(controller.currentItem(), nullptr); -} - -//! Check that controller aware of item deletion. - -TEST_F(ItemListenerTest, itemDeletedBeforeController) -{ - SessionModel model; - auto item = model.insertItem<PropertyItem>(); - - auto controller = std::make_unique<TestController>(); - controller->setItem(item); - item->setData(42.0); - - EXPECT_EQ(controller->currentItem(), item); - EXPECT_EQ(controller->ondata_change_call_count, 1); - - model.removeItem(model.rootItem(), {"", 0}); - EXPECT_EQ(controller->currentItem(), nullptr); -} - -//! Checks unsubscribe scenario. - -TEST_F(ItemListenerTest, unsubscribeScenario) -{ - SessionModel model; - auto item = model.insertItem<PropertyItem>(); - - auto controller = std::make_unique<TestController>(); - controller->setItem(item); - item->setData(42.0); - - EXPECT_EQ(controller->currentItem(), item); - EXPECT_EQ(controller->ondata_change_call_count, 1); - EXPECT_EQ(controller->on_unsubscribe_call_count, 0); - - // setting item to nullptr - controller->setItem(nullptr); - EXPECT_EQ(controller->currentItem(), nullptr); - EXPECT_EQ(controller->on_unsubscribe_call_count, 1); - // change in data shouldn't lead to update - item->setData(45.0); - EXPECT_EQ(controller->ondata_change_call_count, 1); -} - -//! Checks that controller can be deleted before item. - -TEST_F(ItemListenerTest, controllerDeletedBeforeItem) -{ - SessionModel model; - auto item = model.insertItem<PropertyItem>(); - - auto controller = std::make_unique<TestController>(); - controller->setItem(item); - EXPECT_EQ(controller->currentItem(), item); - - controller.reset(); - item->setData(42.0); -} diff --git a/mvvm/tests/testmodel/itemmanager.test.cpp b/mvvm/tests/testmodel/itemmanager.test.cpp deleted file mode 100644 index 1b2efa4b757ba6b532b623538f94f1a32e903c8f..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/itemmanager.test.cpp +++ /dev/null @@ -1,42 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/itemmanager.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/model/itemmanager.h" -#include "mvvm/model/itempool.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/model/sessionmodel.h" -#include <memory> - -using namespace ModelView; - -//! Testing ItemFactory in the context of SessionModel and unique identifiers of SessionItem. - -class ItemManagerTest : public ::testing::Test { -public: - ~ItemManagerTest(); -}; - -ItemManagerTest::~ItemManagerTest() = default; - -TEST_F(ItemManagerTest, initialState) -{ - ItemManager manager; - EXPECT_EQ(manager.itemPool(), nullptr); - - std::shared_ptr<ItemPool> pool(new ItemPool); - manager.setItemPool(pool); - EXPECT_EQ(manager.itemPool(), pool.get()); - EXPECT_EQ(manager.itemPool()->size(), 0); -} diff --git a/mvvm/tests/testmodel/itemmapper.test.cpp b/mvvm/tests/testmodel/itemmapper.test.cpp deleted file mode 100644 index 331a680026e1d09abd222b767492238b0baf1cfa..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/itemmapper.test.cpp +++ /dev/null @@ -1,254 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/itemmapper.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mockwidgets.h" -#include "mvvm/model/compounditem.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/signals/itemmapper.h" -#include <stdexcept> - -using namespace ModelView; -using ::testing::_; - -class ItemMapperTest : public ::testing::Test { -public: - ~ItemMapperTest(); -}; - -ItemMapperTest::~ItemMapperTest() = default; - -//! Check that mapper works only in model context. - -TEST(ItemMapperTest, initialState) -{ - // item outside model context can't have a mapper - auto item = std::make_unique<SessionItem>(); - EXPECT_THROW(item->mapper(), std::runtime_error); - - // item in model context does have a mapper - SessionModel model; - auto item2 = model.insertItem<SessionItem>(model.rootItem()); - EXPECT_NO_THROW(item2->mapper()); -} - -//! Destroying item, expecting single call of onItemDestroy in MockWidget. - -TEST(ItemMapperTest, onItemDestroy) -{ - SessionModel model; - auto item = model.insertItem<SessionItem>(model.rootItem()); - - MockWidgetForItem widget(item); - - auto expected_item = item; - EXPECT_CALL(widget, onItemDestroy(expected_item)).Times(1); - EXPECT_CALL(widget, onDataChange(_, _)).Times(0); - EXPECT_CALL(widget, onPropertyChange(_, _)).Times(0); - EXPECT_CALL(widget, onChildPropertyChange(_, _)).Times(0); - EXPECT_CALL(widget, onItemInserted(_, _)).Times(0); - EXPECT_CALL(widget, onItemRemoved(_, _)).Times(0); - EXPECT_CALL(widget, onAboutToRemoveItem(_, _)).Times(0); - - // performing action - model.removeItem(model.rootItem(), {"", 0}); -} - -//! Setting data to item, expecting onDataChange callback. - -TEST(ItemMapperTest, onDataChange) -{ - SessionModel model; - auto item = model.insertItem<SessionItem>(model.rootItem()); - - MockWidgetForItem widget(item); - - auto expected_role = ItemDataRole::DATA; - auto expected_item = item; - EXPECT_CALL(widget, onDataChange(expected_item, expected_role)).Times(1); - EXPECT_CALL(widget, onPropertyChange(_, _)).Times(0); - EXPECT_CALL(widget, onChildPropertyChange(_, _)).Times(0); - EXPECT_CALL(widget, onItemInserted(_, _)).Times(0); - EXPECT_CALL(widget, onItemRemoved(_, _)).Times(0); - EXPECT_CALL(widget, onAboutToRemoveItem(_, _)).Times(0); - - // perform action - item->setData(42.0); -} - -//! Setting same data to item, expecting no callbacks on onDataChange. - -TEST(ItemMapperTest, onDataChangeDuplicate) -{ - SessionModel model; - auto item = model.insertItem<SessionItem>(model.rootItem()); - - MockWidgetForItem widget(item); - - EXPECT_CALL(widget, onItemDestroy(_)).Times(0); - EXPECT_CALL(widget, onDataChange(_, _)).Times(1); - EXPECT_CALL(widget, onPropertyChange(_, _)).Times(0); - EXPECT_CALL(widget, onChildPropertyChange(_, _)).Times(0); - EXPECT_CALL(widget, onItemInserted(_, _)).Times(0); - EXPECT_CALL(widget, onItemRemoved(_, _)).Times(0); - EXPECT_CALL(widget, onAboutToRemoveItem(_, _)).Times(0); - - // perform actions, only one call should be triggered - item->setData(42.0); - item->setData(42.0); // same data -} - -//! Setting mapper activity to false, change the data, expect no callbacks. - -TEST(ItemMapperTest, setActivity) -{ - SessionModel model; - auto item = model.insertItem<SessionItem>(model.rootItem()); - - MockWidgetForItem widget(item); - - item->mapper()->setActive(false); - - EXPECT_CALL(widget, onItemDestroy(_)).Times(0); - EXPECT_CALL(widget, onDataChange(_, _)).Times(0); - EXPECT_CALL(widget, onPropertyChange(_, _)).Times(0); - EXPECT_CALL(widget, onChildPropertyChange(_, _)).Times(0); - EXPECT_CALL(widget, onItemInserted(_, _)).Times(0); - EXPECT_CALL(widget, onItemRemoved(_, _)).Times(0); - EXPECT_CALL(widget, onAboutToRemoveItem(_, _)).Times(0); - - // perform actions, no calls should be triggered - item->setData(42.0); -} - -//! Unsubscribing from item, expecting no callbacks. - -TEST(ItemMapperTest, unsubscribe) -{ - SessionModel model; - auto item = model.insertItem<SessionItem>(model.rootItem()); - - MockWidgetForItem widget1(item); - MockWidgetForItem widget2(item); - - item->mapper()->unsubscribe(&widget1); - - EXPECT_CALL(widget1, onDataChange(_, _)).Times(0); - EXPECT_CALL(widget2, onDataChange(_, _)).Times(1); - - // perform action, only one widget should be triggered - item->setData(42.0); -} - -//! Changing item property. - -TEST(ItemMapperTest, onPropertyChange) -{ - SessionModel model; - auto item = model.insertItem<CompoundItem>(); - EXPECT_TRUE(item != nullptr); - - auto property = item->addProperty("height", 42.0); - - MockWidgetForItem widget(item); - - EXPECT_CALL(widget, onItemDestroy(_)).Times(0); - EXPECT_CALL(widget, onDataChange(_, _)).Times(0); - EXPECT_CALL(widget, onPropertyChange(item, "height")).Times(1); - EXPECT_CALL(widget, onChildPropertyChange(_, _)).Times(0); - EXPECT_CALL(widget, onItemInserted(_, _)).Times(0); - EXPECT_CALL(widget, onItemRemoved(_, _)).Times(0); - EXPECT_CALL(widget, onAboutToRemoveItem(_, _)).Times(0); - - // perform action - item->setProperty("height", 43.0); - EXPECT_EQ(item->property<double>("height"), 43.0); - EXPECT_EQ(property->data<double>(), 43.0); -} - -//! Changing item property. - -TEST(ItemMapperTest, onChildPropertyChange) -{ - SessionModel model; - auto compound1 = model.insertItem<CompoundItem>(); - compound1->registerTag(TagInfo::universalTag("tag1"), /*set_as_default*/ true); - auto compound2 = model.insertItem<CompoundItem>(compound1); - - auto property = compound2->addProperty("height", 42.0); - - MockWidgetForItem widget(compound1); - - EXPECT_CALL(widget, onItemDestroy(_)).Times(0); - EXPECT_CALL(widget, onDataChange(_, _)).Times(0); - EXPECT_CALL(widget, onPropertyChange(_, _)).Times(0); - EXPECT_CALL(widget, onChildPropertyChange(compound2, "height")).Times(1); - EXPECT_CALL(widget, onItemInserted(_, _)).Times(0); - EXPECT_CALL(widget, onItemRemoved(_, _)).Times(0); - EXPECT_CALL(widget, onAboutToRemoveItem(_, _)).Times(0); - - // perform action - compound2->setProperty("height", 43.0); - EXPECT_EQ(compound2->property<double>("height"), 43.0); - EXPECT_EQ(property->data<double>(), 43.0); -} - -//! Inserting item to item. - -TEST(ItemMapperTest, onItemInsert) -{ - SessionModel model; - auto compound1 = model.insertItem<CompoundItem>(); - compound1->registerTag(TagInfo::universalTag("tag1"), /*set_as_default*/ true); - - MockWidgetForItem widget(compound1); - - const TagRow expected_tagrow{"tag1", 0}; - EXPECT_CALL(widget, onItemDestroy(_)).Times(0); - EXPECT_CALL(widget, onDataChange(_, _)).Times(0); - EXPECT_CALL(widget, onPropertyChange(_, _)).Times(0); - EXPECT_CALL(widget, onChildPropertyChange(_, _)).Times(0); - EXPECT_CALL(widget, onItemInserted(compound1, expected_tagrow)).Times(1); - EXPECT_CALL(widget, onItemRemoved(_, _)).Times(0); - EXPECT_CALL(widget, onAboutToRemoveItem(_, _)).Times(0); - - // perform action - model.insertItem<CompoundItem>(compound1, expected_tagrow); -} - -//! Inserting item to item. - -TEST(ItemMapperTest, onAboutToRemoveItem) -{ - const TagRow expected_tagrow = {"tag1", 0}; - - SessionModel model; - auto compound1 = model.insertItem<CompoundItem>(); - compound1->registerTag(TagInfo::universalTag("tag1"), /*set_as_default*/ true); - model.insertItem<CompoundItem>(compound1, expected_tagrow); - - MockWidgetForItem widget(compound1); - - EXPECT_CALL(widget, onItemDestroy(_)).Times(0); - EXPECT_CALL(widget, onDataChange(_, _)).Times(0); - EXPECT_CALL(widget, onPropertyChange(_, _)).Times(0); - EXPECT_CALL(widget, onChildPropertyChange(_, _)).Times(0); - EXPECT_CALL(widget, onItemInserted(_, _)).Times(0); - EXPECT_CALL(widget, onItemRemoved(compound1, expected_tagrow)).Times(1); - EXPECT_CALL(widget, onAboutToRemoveItem(compound1, expected_tagrow)).Times(1); - - // perform action - model.removeItem(compound1, expected_tagrow); -} diff --git a/mvvm/tests/testmodel/itempool.test.cpp b/mvvm/tests/testmodel/itempool.test.cpp deleted file mode 100644 index 3f2cb5fbe6d4a4edd922e750a9c4322ec1a2a47a..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/itempool.test.cpp +++ /dev/null @@ -1,115 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/itempool.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/model/itempool.h" -#include "mvvm/model/sessionitem.h" -#include <memory> -#include <stdexcept> - -using namespace ModelView; - -//! Tests of ItemPool and its abilities to register/deregister SessionItem. - -class ItemPoolTest : public ::testing::Test { -public: - ~ItemPoolTest(); -}; - -ItemPoolTest::~ItemPoolTest() = default; - -TEST_F(ItemPoolTest, initialState) -{ - std::unique_ptr<ItemPool> pool(new ItemPool); - EXPECT_EQ(pool->size(), 0u); -} - -//! Explicit item registrations. - -TEST_F(ItemPoolTest, registerItem) -{ - std::unique_ptr<ItemPool> pool(new ItemPool); - std::unique_ptr<SessionItem> item(new SessionItem); - - // registering item - auto key = pool->register_item(item.get()); - EXPECT_EQ(pool->size(), 1u); - EXPECT_FALSE(key.empty()); - - // checking registered key and item - EXPECT_EQ(key, pool->key_for_item(item.get())); - EXPECT_EQ(item.get(), pool->item_for_key(key)); - - // checking unexisting registration - std::unique_ptr<SessionItem> item2(new SessionItem); - EXPECT_EQ(identifier_type(), pool->key_for_item(item2.get())); - EXPECT_EQ(nullptr, pool->item_for_key("ABC")); - - // registering second item - auto key2 = pool->register_item(item2.get()); - EXPECT_EQ(pool->size(), 2u); - EXPECT_EQ(key2, pool->key_for_item(item2.get())); - EXPECT_FALSE(key == key2); - - // attempt to register item twice - EXPECT_THROW(pool->register_item(item2.get()), std::runtime_error); -} - -//! Explicit item de-registrations. - -TEST_F(ItemPoolTest, deregisterItem) -{ - std::unique_ptr<ItemPool> pool(new ItemPool); - std::unique_ptr<SessionItem> item1(new SessionItem); - std::unique_ptr<SessionItem> item2(new SessionItem); - - auto key1 = pool->register_item(item1.get()); - auto key2 = pool->register_item(item2.get()); - - EXPECT_EQ(pool->size(), 2u); - EXPECT_EQ(item1.get(), pool->item_for_key(key1)); - EXPECT_EQ(item2.get(), pool->item_for_key(key2)); - - // deregistering item - pool->unregister_item(item1.get()); - EXPECT_EQ(pool->size(), 1u); - EXPECT_EQ(nullptr, pool->item_for_key(key1)); - EXPECT_EQ(item2.get(), pool->item_for_key(key2)); - - // attempt to deregister twice - EXPECT_THROW(pool->unregister_item(item1.get()), std::runtime_error); - - // deregistering last remaining item - pool->unregister_item(item2.get()); - EXPECT_EQ(pool->size(), 0u); -} - -//! Providing custom key. - -TEST_F(ItemPoolTest, customKey) -{ - std::shared_ptr<ItemPool> pool(new ItemPool); - EXPECT_EQ(pool.use_count(), 1l); - - // explicit item registration - const identifier_type id("abc-cde-fgh"); - auto item = new SessionItem; - pool->register_item(item, id); - - // attempt to reuse key again - std::unique_ptr<SessionItem> item2(new SessionItem); - EXPECT_THROW(pool->register_item(item2.get(), id), std::runtime_error); - - delete item; -} diff --git a/mvvm/tests/testmodel/itemutils.test.cpp b/mvvm/tests/testmodel/itemutils.test.cpp deleted file mode 100644 index aa87db6f5cacca6ef6a067393caf08305290ac41..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/itemutils.test.cpp +++ /dev/null @@ -1,328 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/itemutils.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/model/customvariants.h" -#include "mvvm/model/itemutils.h" -#include "mvvm/model/propertyitem.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/model/taginfo.h" -#include "mvvm/standarditems/vectoritem.h" -#include <memory> - -using namespace ModelView; - -class ItemUtilsTest : public ::testing::Test { -}; - -//! Simple iteration over item and its children - -TEST_F(ItemUtilsTest, iterateItem) -{ - std::vector<const SessionItem*> visited_items; - - auto fun = [&](const SessionItem* item) { visited_items.push_back(item); }; - - // iteration over nullptr - Utils::iterate(nullptr, fun); - EXPECT_TRUE(visited_items.empty()); - - // iteration over lonely parent - std::unique_ptr<SessionItem> parent(new SessionItem); - parent->registerTag(TagInfo::universalTag("defaultTag"), /*set_as_default*/ true); - - std::vector<const SessionItem*> expected = {parent.get()}; - Utils::iterate(parent.get(), fun); - EXPECT_EQ(visited_items, expected); - - // adding children - auto child1 = new SessionItem; - auto child2 = new SessionItem; - parent->insertItem(child1, TagRow::append()); - parent->insertItem(child2, TagRow::append()); - - visited_items.clear(); - Utils::iterate(parent.get(), fun); - - expected = {parent.get(), child1, child2}; - EXPECT_EQ(visited_items, expected); -} - -//! Conditional iteration over item and its children. - -TEST_F(ItemUtilsTest, iterateIfItem) -{ - std::vector<const SessionItem*> visited_items; - - // function which will not let iterate over children - std::function<bool(const SessionItem*)> fun = [&](const SessionItem* item) { - visited_items.push_back(item); - return false; - }; - - // iteration over lonely parent - std::unique_ptr<SessionItem> parent(new SessionItem); - parent->registerTag(TagInfo::universalTag("defaultTag"), /*set_as_default*/ true); - - auto child1 = new SessionItem; - auto child2 = new SessionItem; - parent->insertItem(child1, TagRow::append()); - parent->insertItem(child2, TagRow::append()); - - std::vector<const SessionItem*> expected = {parent.get()}; - Utils::iterate_if(parent.get(), fun); - EXPECT_EQ(visited_items, expected); -} - -//! Iteration over root item of the model. - -TEST_F(ItemUtilsTest, iterateModel) -{ - SessionModel model; - - // building model - auto parent1 = model.insertItem<SessionItem>(); - auto parent2 = model.insertItem<SessionItem>(); - parent1->registerTag(TagInfo::universalTag("defaultTag"), /*set_as_default*/ true); - parent2->registerTag(TagInfo::universalTag("defaultTag"), /*set_as_default*/ true); - auto child1 = model.insertItem<SessionItem>(parent1); - auto child2 = model.insertItem<SessionItem>(parent1); - - std::vector<const SessionItem*> visited_items; - auto fun = [&](const SessionItem* item) { visited_items.push_back(item); }; - - // iteration - Utils::iterate(model.rootItem(), fun); - - std::vector<const SessionItem*> expected = {model.rootItem(), parent1, child1, child2, parent2}; - EXPECT_EQ(visited_items, expected); -} - -//! Copy number of child in parents tree. - -TEST_F(ItemUtilsTest, itemCopyNumber) -{ - SessionModel model; - - auto parent = model.insertItem<SessionItem>(); - parent->registerTag(TagInfo::universalTag("defaultTag"), /*set_as_default*/ true); - - auto child1 = model.insertItem<SessionItem>(parent); - auto child2 = model.insertItem<SessionItem>(parent); - auto child3 = model.insertItem<PropertyItem>(parent); - - EXPECT_EQ(Utils::CopyNumber(child1), 0); - EXPECT_EQ(Utils::CopyNumber(child2), 1); - EXPECT_EQ(Utils::CopyNumber(child3), -1); -} - -//! Checks method ::HasTag. - -TEST_F(ItemUtilsTest, HasTag) -{ - SessionItem item; - item.registerTag(TagInfo::universalTag("default_tag"), /*set_as_default*/ true); - - EXPECT_TRUE(Utils::HasTag(item, "default_tag")); - EXPECT_FALSE(Utils::HasTag(item, "nonexisting_tag")); -} - -//! Checks method ::IsSinglePropertyTag. - -TEST_F(ItemUtilsTest, IsSinglePropertyTag) -{ - SessionItem item; - item.registerTag(TagInfo::universalTag("default_tag"), /*set_as_default*/ true); - item.registerTag(TagInfo::propertyTag("property_tag", GUI::Constants::PropertyType)); - - EXPECT_FALSE(Utils::IsSinglePropertyTag(item, "default_tag")); - EXPECT_TRUE(Utils::IsSinglePropertyTag(item, "property_tag")); -} - -//! Checks method ::RegisteredTags. - -TEST_F(ItemUtilsTest, RegisteredTags) -{ - SessionItem item; - EXPECT_TRUE(Utils::RegisteredTags(item).empty()); - - item.registerTag(TagInfo::universalTag("default_tag"), /*set_as_default*/ true); - item.registerTag(TagInfo::propertyTag("property_tag", GUI::Constants::PropertyType)); - - EXPECT_EQ(Utils::RegisteredTags(item), - std::vector<std::string>({"default_tag", "property_tag"})); -} - -//! Checks method ::RegisteredUniversalTags. - -TEST_F(ItemUtilsTest, RegisteredUniversalTags) -{ - SessionItem item; - EXPECT_TRUE(Utils::RegisteredUniversalTags(item).empty()); - - item.registerTag(TagInfo::universalTag("default_tag"), /*set_as_default*/ true); - item.registerTag(TagInfo::propertyTag("property_tag", GUI::Constants::PropertyType)); - - EXPECT_EQ(Utils::RegisteredUniversalTags(item), std::vector<std::string>({"default_tag"})); -} - -//! Check access to top level and property items. - -TEST_F(ItemUtilsTest, TopLevelItems) -{ - SessionModel model; - - auto parent = model.insertItem<SessionItem>(); - parent->registerTag(TagInfo::universalTag("default_tag"), /*set_as_default*/ true); - parent->registerTag(TagInfo::propertyTag("property_tag", GUI::Constants::PropertyType)); - - auto child1 = model.insertItem<SessionItem>(parent, "default_tag"); - model.insertItem<PropertyItem>(parent, "property_tag"); - auto child3 = model.insertItem<SessionItem>(parent, "default_tag"); - - EXPECT_EQ(Utils::TopLevelItems(*model.rootItem()), std::vector<SessionItem*>({parent})); - EXPECT_EQ(Utils::TopLevelItems(*child1), std::vector<SessionItem*>({})); - EXPECT_EQ(Utils::TopLevelItems(*parent), std::vector<SessionItem*>({child1, child3})); -} - -//! Check access to top level and property items. - -TEST_F(ItemUtilsTest, SinglePropertyItems) -{ - SessionModel model; - - auto parent = model.insertItem<SessionItem>(); - parent->registerTag(TagInfo::universalTag("default_tag"), /*set_as_default*/ true); - parent->registerTag(TagInfo::propertyTag("property_tag", GUI::Constants::PropertyType)); - - auto child1 = model.insertItem<SessionItem>(parent, "default_tag"); - auto child2 = model.insertItem<PropertyItem>(parent, "property_tag"); - model.insertItem<SessionItem>(parent, "default_tag"); - - EXPECT_EQ(Utils::SinglePropertyItems(*model.rootItem()), std::vector<SessionItem*>({})); - EXPECT_EQ(Utils::SinglePropertyItems(*child1), std::vector<SessionItem*>({})); - EXPECT_EQ(Utils::SinglePropertyItems(*parent), std::vector<SessionItem*>({child2})); -} - -//! Looking for next item. - -TEST_F(ItemUtilsTest, FindNextSibling) -{ - SessionModel model; - - auto parent = model.insertItem<SessionItem>(); - parent->registerTag(TagInfo::universalTag("default_tag"), /*set_as_default*/ true); - parent->registerTag(TagInfo::propertyTag("property_tag", GUI::Constants::PropertyType)); - - auto property = model.insertItem<PropertyItem>(parent, "property_tag"); - auto child0 = model.insertItem<SessionItem>(parent, "default_tag"); - auto child1 = model.insertItem<SessionItem>(parent, "default_tag"); - auto child2 = model.insertItem<SessionItem>(parent, "default_tag"); - - EXPECT_EQ(Utils::FindNextSibling(child0), child1); - EXPECT_EQ(Utils::FindNextSibling(child1), child2); - EXPECT_EQ(Utils::FindNextSibling(child2), nullptr); - EXPECT_EQ(Utils::FindNextSibling(property), nullptr); - EXPECT_EQ(Utils::FindNextSibling(parent), nullptr); -} - -//! Looking for previous item. - -TEST_F(ItemUtilsTest, FindPreviousSibling) -{ - SessionModel model; - - auto parent = model.insertItem<SessionItem>(); - parent->registerTag(TagInfo::universalTag("default_tag"), /*set_as_default*/ true); - parent->registerTag(TagInfo::propertyTag("property_tag", GUI::Constants::PropertyType)); - - auto property = model.insertItem<PropertyItem>(parent, "property_tag"); - auto child0 = model.insertItem<SessionItem>(parent, "default_tag"); - auto child1 = model.insertItem<SessionItem>(parent, "default_tag"); - auto child2 = model.insertItem<SessionItem>(parent, "default_tag"); - - EXPECT_EQ(Utils::FindPreviousSibling(child0), nullptr); - EXPECT_EQ(Utils::FindPreviousSibling(child1), child0); - EXPECT_EQ(Utils::FindPreviousSibling(child2), child1); - EXPECT_EQ(Utils::FindPreviousSibling(property), nullptr); - EXPECT_EQ(Utils::FindPreviousSibling(parent), nullptr); -} - -//! Looking for previous item. - -TEST_F(ItemUtilsTest, FindNextItemToSelect) -{ - SessionModel model; - - auto parent = model.insertItem<SessionItem>(); - parent->registerTag(TagInfo::universalTag("default_tag"), /*set_as_default*/ true); - parent->registerTag(TagInfo::propertyTag("property_tag", GUI::Constants::PropertyType)); - - auto property = model.insertItem<PropertyItem>(parent, "property_tag"); - auto child0 = model.insertItem<SessionItem>(parent, "default_tag"); - auto child1 = model.insertItem<SessionItem>(parent, "default_tag"); - auto child2 = model.insertItem<SessionItem>(parent, "default_tag"); - - EXPECT_EQ(Utils::FindNextItemToSelect(child0), child1); - EXPECT_EQ(Utils::FindNextItemToSelect(child1), child2); - EXPECT_EQ(Utils::FindNextItemToSelect(child2), child1); - EXPECT_EQ(Utils::FindNextItemToSelect(property), parent); - EXPECT_EQ(Utils::FindNextItemToSelect(parent), model.rootItem()); -} - -//! Looking for previous item. - -TEST_F(ItemUtilsTest, IsItemAncestor) -{ - SessionModel model; - EXPECT_FALSE(Utils::IsItemAncestor(model.rootItem(), model.rootItem())); - - // rootItem in ancestor of vectorItem, but not vice versa - auto vector_item = model.insertItem<VectorItem>(); - EXPECT_TRUE(Utils::IsItemAncestor(vector_item, model.rootItem())); - EXPECT_FALSE(Utils::IsItemAncestor(model.rootItem(), vector_item)); - - auto x_item = vector_item->getItem(VectorItem::P_X); - - EXPECT_TRUE(Utils::IsItemAncestor(x_item, model.rootItem())); - EXPECT_TRUE(Utils::IsItemAncestor(x_item, vector_item)); - EXPECT_FALSE(Utils::IsItemAncestor(model.rootItem(), x_item)); - EXPECT_FALSE(Utils::IsItemAncestor(vector_item, x_item)); - - auto y_item = vector_item->getItem(VectorItem::P_Y); - EXPECT_FALSE(Utils::IsItemAncestor(x_item, y_item)); -} - -TEST_F(ItemUtilsTest, UniqueItems) -{ - SessionModel model; - auto item0 = model.insertItem<SessionItem>(model.rootItem()); - auto item1 = model.insertItem<SessionItem>(model.rootItem()); - auto item2 = model.insertItem<SessionItem>(model.rootItem()); - std::vector<SessionItem*> data = {nullptr, item0, item1, item2, item0, item2, nullptr}; - std::vector<SessionItem*> expected = {item0, item1, item2}; - EXPECT_EQ(Utils::UniqueItems(data), expected); -} - -TEST_F(ItemUtilsTest, CastedItems) -{ - SessionModel model; - auto item0 = model.insertItem<SessionItem>(model.rootItem()); - auto item1 = model.insertItem<PropertyItem>(model.rootItem()); - auto item2 = model.insertItem<VectorItem>(model.rootItem()); - std::vector<SessionItem*> data = {nullptr, item0, item1, item2, item0, item1, item2, nullptr}; - - EXPECT_EQ(Utils::CastedItems<PropertyItem>(data), std::vector<PropertyItem*>({item1, item1})); -} diff --git a/mvvm/tests/testmodel/jsondocument.test.cpp b/mvvm/tests/testmodel/jsondocument.test.cpp deleted file mode 100644 index 3a462e2e277343c5f7039fbc862bc8b9736dd508..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/jsondocument.test.cpp +++ /dev/null @@ -1,177 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/jsondocument.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "folderbasedtest.h" -#include "google_test.h" -#include "mvvm/model/propertyitem.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/model/sessionitemtags.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/model/taginfo.h" -#include "mvvm/serialization/jsondocument.h" -#include "test_utils.h" -#include <stdexcept> - -using namespace ModelView; - -//! Tests JsonDocument class - -class JsonDocumentTest : public FolderBasedTest { -public: - JsonDocumentTest() : FolderBasedTest("test_JsonDocument") {} - ~JsonDocumentTest(); - - class TestModel1 : public SessionModel { - public: - TestModel1() : SessionModel("TestModel1") {} - ~TestModel1(); - }; - - class TestModel2 : public SessionModel { - public: - TestModel2() : SessionModel("TestModel2") {} - ~TestModel2(); - }; -}; - -JsonDocumentTest::~JsonDocumentTest() = default; -JsonDocumentTest::TestModel1::~TestModel1() = default; -JsonDocumentTest::TestModel2::~TestModel2() = default; - -//! Saving the model with content into document and restoring it after. - -TEST_F(JsonDocumentTest, saveLoadSingleModel) -{ - auto fileName = TestUtils::TestFileName(testDir(), "saveLoadSingleModel.json"); - SessionModel model("TestModel"); - JsonDocument document({&model}); - - // filling model with parent and child - auto parent = model.insertItem<SessionItem>(); - parent->setDisplayName("parent_name"); - parent->registerTag(TagInfo::universalTag("defaultTag"), /*set_as_default*/ true); - const auto parent_identifier = parent->identifier(); - - parent->setData(QVariant::fromValue(42)); - auto child = model.insertItem<PropertyItem>(parent); - child->setDisplayName("child_name"); - const auto child_identifier = child->identifier(); - - // saving model in file - document.save(fileName); - - // modifying model further - model.removeItem(model.rootItem(), {"", 0}); - - // loading model from file - document.load(fileName); - - // checking that it is as it was right after the save - - // accessing reconstructed parent and child - auto reco_parent = model.rootItem()->getItem("", 0); - auto reco_child = reco_parent->getItem("", 0); - - // checking parent reconstruction - EXPECT_EQ(reco_parent->model(), &model); - EXPECT_EQ(reco_parent->modelType(), GUI::Constants::BaseType); - EXPECT_EQ(reco_parent->parent(), model.rootItem()); - EXPECT_EQ(reco_parent->displayName(), "SessionItem"); // name changed becase of ProjectConverter - EXPECT_EQ(reco_parent->childrenCount(), 1); - EXPECT_EQ(reco_parent->identifier(), parent_identifier); - EXPECT_EQ(reco_parent->itemTags()->defaultTag(), "defaultTag"); - EXPECT_EQ(reco_parent->data<int>(), 42); - - // checking child reconstruction - EXPECT_EQ(reco_child->model(), &model); - EXPECT_EQ(reco_child->modelType(), GUI::Constants::PropertyType); - EXPECT_EQ(reco_child->parent(), reco_parent); - EXPECT_EQ(reco_child->displayName(), "Property"); - EXPECT_EQ(reco_child->childrenCount(), 0); - EXPECT_EQ(reco_child->identifier(), child_identifier); - EXPECT_EQ(reco_child->itemTags()->defaultTag(), ""); -} - -//! Saving two models with content into document and restoring it after. - -TEST_F(JsonDocumentTest, saveLoadTwoModels) -{ - auto fileName = TestUtils::TestFileName(testDir(), "saveLoadTwoModels.json"); - TestModel1 model1; - TestModel2 model2; - JsonDocument document({&model1, &model2}); - - // filling models - auto parent1 = model1.insertItem<SessionItem>(); - const auto parent_identifier1 = parent1->identifier(); - - auto parent2 = model2.insertItem<SessionItem>(); - const auto parent_identifier2 = parent2->identifier(); - - // saving models in file - document.save(fileName); - - // modifying model further - model1.removeItem(model1.rootItem(), {"", 0}); - model2.removeItem(model2.rootItem(), {"", 0}); - - // loading model from file - document.load(fileName); - - // checking that it is as it was right after the save - - // accessing reconstructed parent and child - auto reco_parent1 = model1.rootItem()->getItem("", 0); - auto reco_parent2 = model2.rootItem()->getItem("", 0); - - // checking parent reconstruction - EXPECT_EQ(reco_parent1->model(), &model1); - EXPECT_EQ(reco_parent1->parent(), model1.rootItem()); - EXPECT_EQ(reco_parent1->identifier(), parent_identifier1); - - EXPECT_EQ(reco_parent2->model(), &model2); - EXPECT_EQ(reco_parent2->parent(), model2.rootItem()); - EXPECT_EQ(reco_parent2->identifier(), parent_identifier2); -} - -//! Attempt to restore models in wrong order. - -TEST_F(JsonDocumentTest, loadModelsInWrongOrder) -{ - auto fileName = TestUtils::TestFileName(testDir(), "loadModelsInWrongOrder.json"); - TestModel1 model1; - TestModel2 model2; - - // filling models - auto parent1 = model1.insertItem<SessionItem>(); - const auto parent_identifier1 = parent1->identifier(); - - auto parent2 = model2.insertItem<SessionItem>(); - const auto parent_identifier2 = parent2->identifier(); - - // saving models in file - { - JsonDocument document({&model1, &model2}); - document.save(fileName); - } - - // modifying model further - model1.removeItem(model1.rootItem(), {"", 0}); - model2.removeItem(model2.rootItem(), {"", 0}); - - JsonDocument document({&model2, &model1}); // intentional wrong order - - // loading model from file - EXPECT_THROW(document.load(fileName), std::runtime_error); -} diff --git a/mvvm/tests/testmodel/jsonitem_types.test.cpp b/mvvm/tests/testmodel/jsonitem_types.test.cpp deleted file mode 100644 index 642003362c1295cd31e88953fc118827eb48f6de..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/jsonitem_types.test.cpp +++ /dev/null @@ -1,43 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/jsonitem_types.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/serialization/jsonitem_types.h" - -using namespace ModelView; - -//! Testing json related flags. - -class JsonItemTypesTest : public ::testing::Test { -public: - ~JsonItemTypesTest(); -}; - -JsonItemTypesTest::~JsonItemTypesTest() = default; - -TEST_F(JsonItemTypesTest, isRegenerateIdWhenBackFromJson) -{ - EXPECT_FALSE(isRegenerateIdWhenBackFromJson(ConverterMode::none)); - EXPECT_FALSE(isRegenerateIdWhenBackFromJson(ConverterMode::clone)); - EXPECT_TRUE(isRegenerateIdWhenBackFromJson(ConverterMode::copy)); - EXPECT_FALSE(isRegenerateIdWhenBackFromJson(ConverterMode::project)); -} - -TEST_F(JsonItemTypesTest, isRebuildItemDataAndTagFromJson) -{ - EXPECT_TRUE(isRebuildItemDataAndTagFromJson(ConverterMode::none)); - EXPECT_TRUE(isRebuildItemDataAndTagFromJson(ConverterMode::clone)); - EXPECT_TRUE(isRebuildItemDataAndTagFromJson(ConverterMode::copy)); - EXPECT_FALSE(isRebuildItemDataAndTagFromJson(ConverterMode::project)); -} diff --git a/mvvm/tests/testmodel/jsonitembackupstrategy.test.cpp b/mvvm/tests/testmodel/jsonitembackupstrategy.test.cpp deleted file mode 100644 index e5cf57b37fb07872c38e3ece8e7c341f035a763d..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/jsonitembackupstrategy.test.cpp +++ /dev/null @@ -1,113 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/jsonitembackupstrategy.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/factories/itemcataloguefactory.h" -#include "mvvm/model/compounditem.h" -#include "mvvm/model/itemfactory.h" -#include "mvvm/model/propertyitem.h" -#include "mvvm/model/sessionitemtags.h" -#include "mvvm/serialization/jsonitembackupstrategy.h" - -using namespace ModelView; - -class JsonItemBackupStrategyTest : public ::testing::Test { -public: - JsonItemBackupStrategyTest() - : m_factory(std::make_unique<ItemFactory>(CreateStandardItemCatalogue())) - { - } - ~JsonItemBackupStrategyTest(); - - std::unique_ptr<JsonItemBackupStrategy> createBackupStrategy() - { - return std::make_unique<JsonItemBackupStrategy>(m_factory.get()); - } - - std::unique_ptr<ItemFactory> m_factory; -}; - -JsonItemBackupStrategyTest::~JsonItemBackupStrategyTest() = default; - -//! Saving/restoring PropertyItem. - -TEST_F(JsonItemBackupStrategyTest, propertyItem) -{ - auto strategy = createBackupStrategy(); - - PropertyItem item; - item.setData(42.0); - - strategy->saveItem(&item); - auto restored = strategy->restoreItem(); - - EXPECT_EQ(item.modelType(), restored->modelType()); - EXPECT_EQ(item.identifier(), restored->identifier()); - EXPECT_EQ(item.data<QVariant>(), restored->data<QVariant>()); -} - -//! Saving/restoring CompoundItem. - -TEST_F(JsonItemBackupStrategyTest, compoundItem) -{ - auto strategy = createBackupStrategy(); - - CompoundItem item; - auto property = item.addProperty("thickness", 42.0); - - strategy->saveItem(&item); - auto restored = strategy->restoreItem(); - - EXPECT_EQ(item.modelType(), restored->modelType()); - EXPECT_EQ(item.identifier(), restored->identifier()); - EXPECT_EQ(restored->getItem("thickness")->data<double>(), property->data<double>()); - EXPECT_EQ(restored->getItem("thickness")->identifier(), property->identifier()); -} - -//! Saving/restoring CustomItem. - -TEST_F(JsonItemBackupStrategyTest, customItem) -{ - auto strategy = createBackupStrategy(); - - const std::string model_type(GUI::Constants::BaseType); - - // creating parent with one child - auto parent = std::make_unique<SessionItem>(model_type); - parent->setDisplayName("parent_name"); - parent->registerTag(TagInfo::universalTag("defaultTag"), /*set_as_default*/ true); - auto child = new SessionItem(model_type); - child->setDisplayName("child_name"); - parent->insertItem(child, TagRow::append()); - - // creating copy - strategy->saveItem(parent.get()); - auto reco_parent = strategy->restoreItem(); - - EXPECT_EQ(reco_parent->childrenCount(), 1); - EXPECT_EQ(reco_parent->modelType(), model_type); - EXPECT_EQ(reco_parent->displayName(), "parent_name"); - EXPECT_EQ(reco_parent->identifier(), parent->identifier()); - EXPECT_EQ(reco_parent->itemTags()->defaultTag(), "defaultTag"); - EXPECT_EQ(reco_parent->model(), nullptr); - - // checking child reconstruction - auto reco_child = reco_parent->getItem("defaultTag"); - EXPECT_EQ(reco_child->parent(), reco_parent.get()); - EXPECT_EQ(reco_child->childrenCount(), 0); - EXPECT_EQ(reco_child->modelType(), model_type); - EXPECT_EQ(reco_child->displayName(), "child_name"); - EXPECT_EQ(reco_child->identifier(), child->identifier()); - EXPECT_EQ(reco_child->itemTags()->defaultTag(), ""); -} diff --git a/mvvm/tests/testmodel/jsonitemcontainerconverter.test.cpp b/mvvm/tests/testmodel/jsonitemcontainerconverter.test.cpp deleted file mode 100644 index fa3278f6ba06dd1b09caa042f64efd897ad572e5..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/jsonitemcontainerconverter.test.cpp +++ /dev/null @@ -1,201 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/jsonitemcontainerconverter.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "folderbasedtest.h" -#include "google_test.h" -#include "mvvm/model/mvvm_types.h" -#include "mvvm/model/propertyitem.h" -#include "mvvm/model/sessionitemcontainer.h" -#include "mvvm/model/sessionitemdata.h" -#include "mvvm/serialization/jsonitem_types.h" -#include "mvvm/serialization/jsonitemcontainerconverter.h" -#include "mvvm/serialization/jsonitemdataconverter.h" -#include "mvvm/serialization/jsonitemformatassistant.h" -#include "test_utils.h" -#include <QJsonArray> -#include <QJsonDocument> -#include <QJsonObject> - -using namespace ModelView; - -//! Checks JsonItemContainerConverter class and its ability to convert SessionItemContainer -//! to json and back. Full testing is not possible since JsonItemContainerConverter -//! requires machinery provided by JsonItemConverter. Simplifed item/json creation is used. - -class JsonItemContainerConverterTest : public FolderBasedTest { -public: - JsonItemContainerConverterTest() - : FolderBasedTest("test_JsonItemContainerConverterTest") - , m_itemdata_converter(std::make_unique<JsonItemDataConverter>()) - { - } - - std::unique_ptr<JsonItemContainerConverter> createConverter() const - { - //! Simplified method to convert SessionItem to JSON object. - auto to_json = [this](const SessionItem& item) { - QJsonObject result; - result[JsonItemFormatAssistant::modelKey] = QString::fromStdString(item.modelType()); - result[JsonItemFormatAssistant::itemDataKey] = - m_itemdata_converter->to_json(*item.itemData()); - result[JsonItemFormatAssistant::itemTagsKey] = QJsonObject(); - return result; - }; - - //! Simplified method to create SessionItem from JSON object - auto create_item = [this](const QJsonObject& json) { - auto result = std::make_unique<SessionItem>(); - m_itemdata_converter->from_json(json[JsonItemFormatAssistant::itemDataKey].toArray(), - *result->itemData()); - return result; - }; - - //! Simplified method to update SessionItem from JSON object - auto update_item = [this](const QJsonObject& json, SessionItem* item) { - m_itemdata_converter->from_json(json[JsonItemFormatAssistant::itemDataKey].toArray(), - *item->itemData()); - }; - - ConverterCallbacks callbacks{to_json, create_item, update_item}; - return std::make_unique<JsonItemContainerConverter>(callbacks); - } - - ~JsonItemContainerConverterTest(); - - std::unique_ptr<JsonItemDataConverter> m_itemdata_converter; -}; - -JsonItemContainerConverterTest::~JsonItemContainerConverterTest() = default; - -//! SessionItemContainer (with single property item) to json object. - -TEST_F(JsonItemContainerConverterTest, propertyContainerToJson) -{ - // creating container - TagInfo tag = TagInfo::propertyTag("thickness", GUI::Constants::PropertyType); - SessionItemContainer container(tag); - - // inserting single property item - auto item = new PropertyItem; - item->setData(42); - EXPECT_TRUE(container.insertItem(item, 0)); - - // converting top JSON and checking that it is valid JSON object - auto converter = createConverter(); - auto json = converter->to_json(container); - - JsonItemFormatAssistant assistant; - EXPECT_TRUE(assistant.isSessionItemContainer(json)); -} - -//! SessionItemContainer (with single property item) to json object and back. - -TEST_F(JsonItemContainerConverterTest, propertyContainerToJsonAndBack) -{ - // creating container - TagInfo tag = TagInfo::propertyTag("thickness", GUI::Constants::PropertyType); - SessionItemContainer container(tag); - - // inserting single property item - auto item = new PropertyItem; - item->setData(42); - EXPECT_TRUE(container.insertItem(item, 0)); - - // converting top JSON - auto converter = createConverter(); - auto json = converter->to_json(container); - - // creating second container with same layout, and updating it from JSON - SessionItemContainer container2(tag); - auto item2 = new PropertyItem; - item2->setData(43); - EXPECT_TRUE(container2.insertItem(item2, 0)); - converter->from_json(json, container2); - - // Checking that item in container2 has been reused, and get same properties as item. - EXPECT_EQ(container2.itemAt(0), item2); - EXPECT_EQ(item->displayName(), item2->displayName()); - EXPECT_EQ(item->identifier(), item2->identifier()); - EXPECT_EQ(42, item2->data<int>()); -} - -//! SessionItemContainer (with single property item) to json file and back. - -TEST_F(JsonItemContainerConverterTest, propertyContainerToFileAndBack) -{ - // creating container - TagInfo tag = TagInfo::propertyTag("thickness", GUI::Constants::PropertyType); - SessionItemContainer container(tag); - - // inserting single property item - auto item = new PropertyItem; - item->setData(42); - EXPECT_TRUE(container.insertItem(item, 0)); - - // converting top JSON and checking that it is valid JSON object - auto converter = createConverter(); - auto json = converter->to_json(container); - - // saving object to file - auto fileName = TestUtils::TestFileName(testDir(), "propertyContainerToFileAndBack.json"); - TestUtils::SaveJson(json, fileName); - - // loading from file - auto document = TestUtils::LoadJson(fileName); - - // creating second container with same layout, and updating it from JSON - SessionItemContainer container2(tag); - auto item2 = new PropertyItem; - item2->setData(43); - EXPECT_TRUE(container2.insertItem(item2, 0)); - converter->from_json(document.object(), container2); - - // Checking that item in container2 has been reused, and get same properties as item. - EXPECT_EQ(container2.itemAt(0), item2); - EXPECT_EQ(item->displayName(), item2->displayName()); - EXPECT_EQ(item->identifier(), item2->identifier()); - EXPECT_EQ(42, item2->data<int>()); -} - -//! SessionItemContainer (with universal tag and several items) to json object and back. - -TEST_F(JsonItemContainerConverterTest, universalContainerToJsonAndBack) -{ - // creating container - TagInfo tag = TagInfo::universalTag("items"); - SessionItemContainer container(tag); - - // inserting single property item - const int n_max_items = 3; - for (int i = 0; i < n_max_items; ++i) { - auto item = new PropertyItem; - item->setData(i + 42); - EXPECT_TRUE(container.insertItem(item, 0)); - } - - // converting top JSON - auto converter = createConverter(); - auto json = converter->to_json(container); - - // creating second container with same layout, but without items - SessionItemContainer container2(tag); - converter->from_json(json, container2); - - // Checking that container2 got same content as container - EXPECT_EQ(container2.itemCount(), n_max_items); - for (int i = 0; i < n_max_items; ++i) { - EXPECT_EQ(container.itemAt(i)->identifier(), container2.itemAt(i)->identifier()); - EXPECT_EQ(container.itemAt(i)->data<int>(), container2.itemAt(i)->data<int>()); - } -} diff --git a/mvvm/tests/testmodel/jsonitemconverter.test.cpp b/mvvm/tests/testmodel/jsonitemconverter.test.cpp deleted file mode 100644 index 81297b96c840f06088df379ba835720512852be9..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/jsonitemconverter.test.cpp +++ /dev/null @@ -1,237 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/jsonitemconverter.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "folderbasedtest.h" -#include "google_test.h" -#include "mvvm/model/compounditem.h" -#include "mvvm/model/itemcatalogue.h" -#include "mvvm/model/propertyitem.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/model/sessionitemtags.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/serialization/jsonitem_types.h" -#include "mvvm/serialization/jsonitemconverter.h" -#include "mvvm/serialization/jsonitemformatassistant.h" -#include "test_utils.h" -#include <QJsonArray> -#include <QJsonDocument> -#include <QJsonObject> - -using namespace ModelView; - -//! Checks JsonItem class and its ability to convert SessionItems to json and back. - -class JsonItemConverterTest : public FolderBasedTest { -public: - class TestItem : public CompoundItem { - public: - TestItem() : CompoundItem("TestItem") - { - setToolTip("compound"); - addProperty("Thickness", 42)->setToolTip("thickness"); - } - }; - - class TestModel : public SessionModel { - public: - TestModel() : SessionModel("TestModel") - { - auto catalogue = std::make_unique<ModelView::ItemCatalogue>(); - catalogue->registerItem<TestItem>(); - setItemCatalogue(std::move(catalogue)); - } - }; - - JsonItemConverterTest() - : FolderBasedTest("test_JsonItemConverter"), m_model(std::make_unique<TestModel>()) - { - } - ~JsonItemConverterTest(); - - std::unique_ptr<JsonItemConverter> createConverter() - { - ConverterContext context{m_model->factory(), ConverterMode::clone}; - return std::make_unique<JsonItemConverter>(context); - } - -private: - std::unique_ptr<SessionModel> m_model; -}; - -JsonItemConverterTest::~JsonItemConverterTest() = default; - -//! PropertyItem to json object. - -TEST_F(JsonItemConverterTest, propertyItemToJson) -{ - auto converter = createConverter(); - - PropertyItem item; - auto object = converter->to_json(&item); - - // this object represents SessionItem - JsonItemFormatAssistant assistant; - EXPECT_TRUE(assistant.isSessionItem(object)); -} - -//! PropertyItem to json object and back. - -TEST_F(JsonItemConverterTest, propertyItemToJsonAndBack) -{ - auto converter = createConverter(); - - PropertyItem item; - item.setToolTip("abc"); - auto object = converter->to_json(&item); - - auto reco = converter->from_json(object); - - EXPECT_EQ(reco->modelType(), item.modelType()); - EXPECT_EQ(reco->displayName(), item.displayName()); - EXPECT_EQ(reco->identifier(), item.identifier()); - EXPECT_EQ(reco->toolTip(), std::string("abc")); -} - -//! PropertyItem to json file and back. - -TEST_F(JsonItemConverterTest, propertyItemToFileAndBack) -{ - auto converter = createConverter(); - - PropertyItem item; - auto object = converter->to_json(&item); - - // saving object to file - auto fileName = TestUtils::TestFileName(testDir(), "propertyItemToFileAndBack.json"); - TestUtils::SaveJson(object, fileName); - - auto document = TestUtils::LoadJson(fileName); - auto reco = converter->from_json(document.object()); - - EXPECT_EQ(reco->parent(), nullptr); - EXPECT_EQ(reco->modelType(), item.modelType()); - EXPECT_EQ(reco->displayName(), item.displayName()); - EXPECT_EQ(reco->identifier(), item.identifier()); -} - -//! Parent and child to json object. - -TEST_F(JsonItemConverterTest, parentAndChildToJsonAndBack) -{ - auto converter = createConverter(); - const std::string model_type(GUI::Constants::BaseType); - - auto parent = std::make_unique<SessionItem>(model_type); - parent->setDisplayName("parent_name"); - parent->registerTag(TagInfo::universalTag("defaultTag"), /*set_as_default*/ true); - auto child = new SessionItem(model_type); - child->setDisplayName("child_name"); - parent->insertItem(child, TagRow::append()); - - // converting to json - auto object = converter->to_json(parent.get()); - JsonItemFormatAssistant assistant; - EXPECT_TRUE(assistant.isSessionItem(object)); - - // converting json back to item - auto reco_parent = converter->from_json(object); - - // checking parent reconstruction - EXPECT_EQ(reco_parent->childrenCount(), 1); - EXPECT_EQ(reco_parent->modelType(), model_type); - EXPECT_EQ(reco_parent->displayName(), "parent_name"); - EXPECT_EQ(reco_parent->identifier(), parent->identifier()); - EXPECT_EQ(reco_parent->itemTags()->defaultTag(), "defaultTag"); - EXPECT_EQ(reco_parent->model(), nullptr); - - // checking child reconstruction - auto reco_child = reco_parent->getItem("defaultTag"); - EXPECT_EQ(reco_child->parent(), reco_parent.get()); - EXPECT_EQ(reco_child->childrenCount(), 0); - EXPECT_EQ(reco_child->modelType(), model_type); - EXPECT_EQ(reco_child->displayName(), "child_name"); - EXPECT_EQ(reco_child->identifier(), child->identifier()); - EXPECT_EQ(reco_child->itemTags()->defaultTag(), ""); -} - -//! Parent and child to json file and back. - -TEST_F(JsonItemConverterTest, parentAndChildToFileAndBack) -{ - auto converter = createConverter(); - const std::string model_type(GUI::Constants::BaseType); - - auto parent = std::make_unique<SessionItem>(model_type); - parent->setDisplayName("parent_name"); - parent->registerTag(TagInfo::universalTag("defaultTag"), /*set_as_default*/ true); - auto child = new SessionItem(model_type); - child->setDisplayName("child_name"); - parent->insertItem(child, TagRow::append()); - - // converting to json - auto object = converter->to_json(parent.get()); - JsonItemFormatAssistant assistant; - EXPECT_TRUE(assistant.isSessionItem(object)); - - // saving object to file - auto fileName = TestUtils::TestFileName(testDir(), "parentAndChildToFileAndBack.json"); - TestUtils::SaveJson(object, fileName); - - // converting document back to item - auto document = TestUtils::LoadJson(fileName); - auto reco_parent = converter->from_json(document.object()); - - // checking parent reconstruction - EXPECT_EQ(reco_parent->childrenCount(), 1); - EXPECT_EQ(reco_parent->modelType(), model_type); - EXPECT_EQ(reco_parent->displayName(), "parent_name"); - EXPECT_EQ(reco_parent->identifier(), parent->identifier()); - EXPECT_EQ(reco_parent->itemTags()->defaultTag(), "defaultTag"); - EXPECT_EQ(reco_parent->model(), nullptr); - - // checking child reconstruction - auto reco_child = reco_parent->getItem("defaultTag"); - EXPECT_EQ(reco_child->parent(), reco_parent.get()); - EXPECT_EQ(reco_child->childrenCount(), 0); - EXPECT_EQ(reco_child->modelType(), model_type); - EXPECT_EQ(reco_child->displayName(), "child_name"); - EXPECT_EQ(reco_child->identifier(), child->identifier()); - EXPECT_EQ(reco_child->itemTags()->defaultTag(), ""); -} - -//! TestItem to json file and back. - -TEST_F(JsonItemConverterTest, testItemToFileAndBack) -{ - auto converter = createConverter(); - - TestItem item; - auto object = converter->to_json(&item); - - // saving object to file - auto fileName = TestUtils::TestFileName(testDir(), "testItemToFileAndBack.json"); - TestUtils::SaveJson(object, fileName); - - auto document = TestUtils::LoadJson(fileName); - auto reco = converter->from_json(document.object()); - - EXPECT_EQ(reco->parent(), nullptr); - EXPECT_EQ(reco->modelType(), item.modelType()); - EXPECT_EQ(reco->displayName(), item.displayName()); - EXPECT_EQ(reco->identifier(), item.identifier()); - - EXPECT_EQ(reco->toolTip(), "compound"); - // tooltip was preserved after the serialization - EXPECT_EQ(reco->getItem("Thickness")->toolTip(), "thickness"); -} diff --git a/mvvm/tests/testmodel/jsonitemcopystrategy.test.cpp b/mvvm/tests/testmodel/jsonitemcopystrategy.test.cpp deleted file mode 100644 index 8d3c074553fa4671b6ebd511a486414cf0c6e286..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/jsonitemcopystrategy.test.cpp +++ /dev/null @@ -1,110 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/jsonitemcopystrategy.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/factories/itemcataloguefactory.h" -#include "mvvm/model/compounditem.h" -#include "mvvm/model/itemfactory.h" -#include "mvvm/model/propertyitem.h" -#include "mvvm/model/sessionitemtags.h" -#include "mvvm/serialization/jsonitemcopystrategy.h" - -using namespace ModelView; - -class JsonItemCopyStrategyTest : public ::testing::Test { -public: - JsonItemCopyStrategyTest() - : m_factory(std::make_unique<ItemFactory>(CreateStandardItemCatalogue())) - { - } - ~JsonItemCopyStrategyTest(); - - std::unique_ptr<JsonItemCopyStrategy> createCopyStrategy() - { - return std::make_unique<JsonItemCopyStrategy>(m_factory.get()); - } - - std::unique_ptr<ItemFactory> m_factory; -}; - -JsonItemCopyStrategyTest::~JsonItemCopyStrategyTest() = default; - -//! Saving/restoring PropertyItem. - -TEST_F(JsonItemCopyStrategyTest, propertyItem) -{ - auto strategy = createCopyStrategy(); - - PropertyItem item; - item.setData(42.0); - - auto copy = strategy->createCopy(&item); - - EXPECT_EQ(item.modelType(), copy->modelType()); - EXPECT_EQ(item.data<QVariant>(), copy->data<QVariant>()); - EXPECT_FALSE(item.identifier() == copy->identifier()); -} - -//! Saving/restoring CompoundItem. - -TEST_F(JsonItemCopyStrategyTest, compoundItem) -{ - auto strategy = createCopyStrategy(); - - CompoundItem item; - auto property = item.addProperty("thickness", 42.0); - - auto copy = strategy->createCopy(&item); - - EXPECT_EQ(item.modelType(), copy->modelType()); - EXPECT_EQ(copy->getItem("thickness")->data<double>(), property->data<double>()); - EXPECT_FALSE(copy->getItem("thickness")->identifier() == property->identifier()); - EXPECT_FALSE(item.identifier() == copy->identifier()); -} - -//! Saving/restoring CustomItem. - -TEST_F(JsonItemCopyStrategyTest, customItem) -{ - auto strategy = createCopyStrategy(); - - const std::string model_type(GUI::Constants::BaseType); - - // creating parent with one child - auto parent = std::make_unique<SessionItem>(model_type); - parent->setDisplayName("parent_name"); - parent->registerTag(TagInfo::universalTag("defaultTag"), /*set_as_default*/ true); - auto child = new SessionItem(model_type); - child->setDisplayName("child_name"); - parent->insertItem(child, TagRow::append()); - - // creating copy - auto parent_copy = strategy->createCopy(parent.get()); - - EXPECT_EQ(parent_copy->childrenCount(), 1); - EXPECT_EQ(parent_copy->modelType(), model_type); - EXPECT_EQ(parent_copy->displayName(), "parent_name"); - EXPECT_EQ(parent_copy->itemTags()->defaultTag(), "defaultTag"); - EXPECT_EQ(parent_copy->model(), nullptr); - EXPECT_FALSE(parent_copy->identifier() == parent->identifier()); - - // checking child reconstruction - auto child_copy = parent_copy->getItem("defaultTag"); - EXPECT_EQ(child_copy->parent(), parent_copy.get()); - EXPECT_EQ(child_copy->childrenCount(), 0); - EXPECT_EQ(child_copy->modelType(), model_type); - EXPECT_EQ(child_copy->displayName(), "child_name"); - EXPECT_EQ(child_copy->itemTags()->defaultTag(), ""); - EXPECT_FALSE(child_copy->identifier() == child->identifier()); -} diff --git a/mvvm/tests/testmodel/jsonitemdataconverter.test.cpp b/mvvm/tests/testmodel/jsonitemdataconverter.test.cpp deleted file mode 100644 index 20bf53dd72e992b50362a9128133a1fe84a464bc..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/jsonitemdataconverter.test.cpp +++ /dev/null @@ -1,259 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/jsonitemdataconverter.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "folderbasedtest.h" -#include "google_test.h" -#include "mvvm/model/customvariants.h" -#include "mvvm/model/mvvm_types.h" -#include "mvvm/model/sessionitemdata.h" -#include "mvvm/serialization/jsonitemdataconverter.h" -#include "mvvm/serialization/jsonitemformatassistant.h" -#include "mvvm/serialization/jsonvariantconverter.h" -#include "test_utils.h" -#include <QJsonArray> -#include <QJsonObject> -#include <string> - -using namespace ModelView; - -//! Test convertion of SessionItemData from/to QJsonObject. - -class JsonItemDataConverterTest : public FolderBasedTest { -public: - JsonItemDataConverterTest() : FolderBasedTest("test_JsonItemData") {} - ~JsonItemDataConverterTest(); -}; - -JsonItemDataConverterTest::~JsonItemDataConverterTest() = default; - -//! Creating QJsonArray from SessionItemData. - -TEST_F(JsonItemDataConverterTest, getJson) -{ - JsonItemFormatAssistant assistant; - JsonItemDataConverter converter; - - // construction SessionItem data - SessionItemData data; - const int role = Qt::UserRole + 1; - data.setData(QVariant::fromValue(42), role); - data.setData(QVariant::fromValue(std::string("abc")), role + 2); - - // creating json object out of it - QJsonArray array = converter.to_json(data); - - // it should contain two json objects - EXPECT_EQ(array.size(), 2); - EXPECT_TRUE(array[0].isObject()); - EXPECT_TRUE(array[1].isObject()); - - // and these objects repesent DataRole - EXPECT_TRUE(assistant.isSessionItemData(array[0].toObject())); - EXPECT_TRUE(assistant.isSessionItemData(array[1].toObject())); -} - -//! From SessionItemData to json and back. - -TEST_F(JsonItemDataConverterTest, fromItemToJsonAndBack) -{ - JsonItemDataConverter converter; - - // initial data - const std::vector<int> roles = {1, 2, 3}; - const std::vector<QVariant> expected = {QVariant::fromValue(42), QVariant::fromValue(1.23), - QVariant::fromValue(std::string("abc"))}; - - // constructing SessionItemData - SessionItemData data; - for (size_t i = 0; i < roles.size(); ++i) - data.setData(expected[i], roles[i]); - - // constructing json array from data - QJsonArray array = converter.to_json(data); - auto fileName = TestUtils::TestFileName(testDir(), "itemdata.json"); - TestUtils::SaveJson(array, fileName); - - // constructing data from json array - SessionItemData data2; - converter.from_json(array, data2); - EXPECT_EQ(data2.roles().size(), 3u); - - EXPECT_EQ(data2.roles(), roles); - for (auto role : roles) { - EXPECT_EQ(data2.data(role), expected[role - 1]); - } -} - -//! By default tooltip role is enabled for read and write. - -TEST_F(JsonItemDataConverterTest, tooltipRole) -{ - // initial data - SessionItemData data; - data.setData(QVariant::fromValue(std::string("tooltip")), ItemDataRole::TOOLTIP); - - // constructing json array from data - JsonItemDataConverter converter; - QJsonArray array = converter.to_json(data); - - // constructing data from json array - SessionItemData data2; - converter.from_json(array, data2); - EXPECT_EQ(data2.roles().size(), 1u); - EXPECT_EQ(data2.data(ItemDataRole::TOOLTIP).value<std::string>(), "tooltip"); -} - -//! Write filtered roles, read all into empty SessionItemData. - -TEST_F(JsonItemDataConverterTest, writeFilteredReadAll) -{ - // initial data - SessionItemData data; - data.setData(QVariant::fromValue(std::string("abc")), ItemDataRole::IDENTIFIER); - data.setData(42, ItemDataRole::DATA); - data.setData(QVariant::fromValue(std::string("abc")), ItemDataRole::DISPLAY); - data.setData(QVariant::fromValue(std::string("tooltip")), ItemDataRole::TOOLTIP); - - // constructing json array from data - auto to_json_accept = [](auto role) { return role != ItemDataRole::TOOLTIP; }; - - JsonItemDataConverter converter(to_json_accept, {}); - QJsonArray array = converter.to_json(data); - - // constructing data from json array - SessionItemData data2; - converter.from_json(array, data2); - EXPECT_EQ(data2.roles().size(), 3u); - EXPECT_FALSE(data2.hasData(ItemDataRole::TOOLTIP)); -} - -//! Write all roles, read filtered into empty SessionItemData. - -TEST_F(JsonItemDataConverterTest, writeAllReadFiltered) -{ - // initial data - SessionItemData data; - data.setData(QVariant::fromValue(std::string("abc")), ItemDataRole::IDENTIFIER); - data.setData(42, ItemDataRole::DATA); - data.setData(QVariant::fromValue(std::string("abc")), ItemDataRole::DISPLAY); - data.setData(QVariant::fromValue(std::string("tooltip")), ItemDataRole::TOOLTIP); - - // constructing json array from data - auto from_json_accept = [](auto role) { return role == ItemDataRole::TOOLTIP; }; - - JsonItemDataConverter converter({}, from_json_accept); - QJsonArray array = converter.to_json(data); - - // constructing data from json array - SessionItemData data2; - converter.from_json(array, data2); - - // while array itself has 4 elements, restored data has only TOOLTIPS as defined in filter - EXPECT_EQ(array.size(), 4u); - EXPECT_EQ(data2.roles().size(), 1u); - EXPECT_TRUE(data2.hasData(ItemDataRole::TOOLTIP)); -} - -//! Update SessionItemData from json obtained from another JsonItemData. - -TEST_F(JsonItemDataConverterTest, updateFromJson) -{ - const std::vector<int> roles = {ItemDataRole::IDENTIFIER, ItemDataRole::DATA, - ItemDataRole::TOOLTIP}; - const std::vector<QVariant> variants = {QVariant::fromValue(std::string("identifier1")), - QVariant::fromValue(42), - QVariant::fromValue(std::string("tooltip1"))}; - - // initial data - SessionItemData data1; - for (size_t i = 0; i < roles.size(); ++i) - data1.setData(variants[i], roles[i]); - - // data intended for serialization - SessionItemData data2; - data1.setData(QVariant::fromValue(43), ItemDataRole::DATA); - data1.setData(QVariant::fromValue(std::string("identifier2")), ItemDataRole::IDENTIFIER); - - // constructing json array from data - JsonItemDataConverter converter; - QJsonArray array = converter.to_json(data2); - - // updating data1 from json array - converter.from_json(array, data1); - - // roles as in initial object, id+data as in data2, tooltip as in data1 - EXPECT_EQ(data1.roles(), roles); - EXPECT_EQ(data1.data(ItemDataRole::IDENTIFIER).value<std::string>(), - std::string("identifier2")); - EXPECT_EQ(data1.data(ItemDataRole::DATA).value<int>(), 43); - EXPECT_EQ(data1.data(ItemDataRole::TOOLTIP).value<std::string>(), std::string("tooltip1")); -} - -//! Checking factory method to create copying converter. -//! It is used normally in the situation, when the item data is fully serialized to JSON, and then -//! desirialized into empty item data. - -TEST_F(JsonItemDataConverterTest, createCopyConverter) -{ - auto converter = JsonItemDataConverter::createCopyConverter(); - - SessionItemData data; - data.setData(QVariant::fromValue(std::string("identifier")), ItemDataRole::IDENTIFIER); - data.setData(42, ItemDataRole::DATA); - data.setData(QVariant::fromValue(std::string("display")), ItemDataRole::DISPLAY); - data.setData(QVariant::fromValue(std::string("tooltip")), ItemDataRole::TOOLTIP); - - QJsonArray array = converter->to_json(data); - - SessionItemData data2; - converter->from_json(array, data2); - - //! Empty data should become the same. - EXPECT_EQ(data.roles(), data2.roles()); - EXPECT_EQ(data2.data(ItemDataRole::IDENTIFIER).value<std::string>(), "identifier"); - EXPECT_EQ(data2.data(ItemDataRole::DATA).value<int>(), 42); - EXPECT_EQ(data2.data(ItemDataRole::DISPLAY).value<std::string>(), "display"); - EXPECT_EQ(data2.data(ItemDataRole::TOOLTIP).value<std::string>(), "tooltip"); -} - -//! Checking factory method for typical scenario for copying whole data while writing, and updating -//! on reading. This is a repetition of previous test. - -TEST_F(JsonItemDataConverterTest, createProjectConverter) -{ - auto converter = JsonItemDataConverter::createProjectConverter(); - - SessionItemData data; - data.setData(QVariant::fromValue(std::string("identifier")), ItemDataRole::IDENTIFIER); - data.setData(42, ItemDataRole::DATA); - data.setData(QVariant::fromValue(std::string("display")), ItemDataRole::DISPLAY); - data.setData(QVariant::fromValue(std::string("tooltip")), ItemDataRole::TOOLTIP); - auto expected_roles = data.roles(); - - QJsonArray array = converter->to_json(data); - - // changing data - data.setData(QVariant::fromValue(std::string("identifier_new")), ItemDataRole::IDENTIFIER); - data.setData(43, ItemDataRole::DATA); - - // deserializing back - converter->from_json(array, data); - - //! DATA and IDENTIFIER roles should be as before the serialization - EXPECT_EQ(data.roles(), expected_roles); - EXPECT_EQ(data.data(ItemDataRole::IDENTIFIER).value<std::string>(), "identifier"); - EXPECT_EQ(data.data(ItemDataRole::DATA).value<int>(), 42); - EXPECT_EQ(data.data(ItemDataRole::DISPLAY).value<std::string>(), "display"); - EXPECT_EQ(data.data(ItemDataRole::TOOLTIP).value<std::string>(), "tooltip"); -} diff --git a/mvvm/tests/testmodel/jsonitemformatassistant.test.cpp b/mvvm/tests/testmodel/jsonitemformatassistant.test.cpp deleted file mode 100644 index 00d7b5602b48434dae322cd0e9fd19d9890ae210..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/jsonitemformatassistant.test.cpp +++ /dev/null @@ -1,126 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/jsonitemformatassistant.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/serialization/jsonitemformatassistant.h" -#include "mvvm/serialization/jsonvariantconverter.h" -#include <QJsonArray> -#include <QJsonObject> - -using namespace ModelView; - -//! Checks JsonItem class and its ability to convert SessionItems to json and back. - -class JsonItemFormatAssistantTest : public ::testing::Test { -public: - ~JsonItemFormatAssistantTest(); -}; - -JsonItemFormatAssistantTest::~JsonItemFormatAssistantTest() = default; - -//! Checks the validity of json object representing SessionItem. - -TEST_F(JsonItemFormatAssistantTest, isSessionItem) -{ - JsonItemFormatAssistant assistant; - - // empty json object is not valid - QJsonObject object; - EXPECT_FALSE(assistant.isSessionItem(object)); - - // it also should contain array - object[JsonItemFormatAssistant::modelKey] = "abc"; - object[JsonItemFormatAssistant::itemDataKey] = QJsonArray(); - object[JsonItemFormatAssistant::itemTagsKey] = 42; // intentionally incorrect - EXPECT_FALSE(assistant.isSessionItem(object)); - - // correctly constructed - object[JsonItemFormatAssistant::itemTagsKey] = QJsonObject(); - EXPECT_TRUE(assistant.isSessionItem(object)); -} - -//! Checks if json object is correctly identified as representing DataRole. - -TEST_F(JsonItemFormatAssistantTest, isValidDataRole) -{ - JsonItemFormatAssistant assistant; - JsonVariantConverter variant_converter; - - // valid json object representing DataRole - QJsonObject object; - object[JsonItemFormatAssistant::roleKey] = 42; - object[JsonItemFormatAssistant::variantKey] = variant_converter.get_json(QVariant(1.23)); - EXPECT_TRUE(assistant.isSessionItemData(object)); - - // invalid json object which can't represent DataRole - QJsonObject object2; - object2[JsonItemFormatAssistant::roleKey] = 42; - EXPECT_FALSE(assistant.isSessionItemData(object2)); - - // another invalid json object - QJsonObject object3; - object3[JsonItemFormatAssistant::roleKey] = 42; - object3[JsonItemFormatAssistant::variantKey] = variant_converter.get_json(QVariant(1.23)); - object3["abc"] = variant_converter.get_json(QVariant::fromValue(std::string("xxx"))); - EXPECT_FALSE(assistant.isSessionItemData(object3)); -} - -//! Checks the validity of json object representing SessionItemTags. - -TEST_F(JsonItemFormatAssistantTest, isSessionItemTags) -{ - JsonItemFormatAssistant assistant; - - // empty json object is not valid - QJsonObject object; - EXPECT_FALSE(assistant.isSessionItemTags(object)); - - // it also should contain array - object[JsonItemFormatAssistant::defaultTagKey] = "abc"; - object[JsonItemFormatAssistant::containerKey] = QJsonArray(); - EXPECT_TRUE(assistant.isSessionItemTags(object)); -} - -//! Checks the validity of json object representing SessionItemContainer. - -TEST_F(JsonItemFormatAssistantTest, isSessionItemContainer) -{ - JsonItemFormatAssistant assistant; - - // empty json object is not valid - QJsonObject object; - EXPECT_FALSE(assistant.isSessionItemContainer(object)); - - // it also should contain array - object[JsonItemFormatAssistant::tagInfoKey] = QJsonObject(); - object[JsonItemFormatAssistant::itemsKey] = QJsonArray(); - EXPECT_TRUE(assistant.isSessionItemContainer(object)); -} - -//! Validity of json object representing SessionModel. - -TEST_F(JsonItemFormatAssistantTest, isValidSessionModel) -{ - JsonItemFormatAssistant assistant; - - // empty json object is not valid - QJsonObject object; - EXPECT_FALSE(assistant.isSessionModel(object)); - - // json object representing valid SessionModel - QJsonObject object2; - object2[JsonItemFormatAssistant::sessionModelKey] = "abc"; - object2[JsonItemFormatAssistant::itemsKey] = QJsonArray(); - EXPECT_TRUE(assistant.isSessionModel(object2)); -} diff --git a/mvvm/tests/testmodel/jsonmodelconverter.test.cpp b/mvvm/tests/testmodel/jsonmodelconverter.test.cpp deleted file mode 100644 index 4947667802866279c3d84ccf03206b3f70362730..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/jsonmodelconverter.test.cpp +++ /dev/null @@ -1,264 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/jsonmodelconverter.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "folderbasedtest.h" -#include "google_test.h" -#include "mvvm/model/itempool.h" -#include "mvvm/model/propertyitem.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/model/sessionitemtags.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/model/taginfo.h" -#include "mvvm/serialization/jsonitem_types.h" -#include "mvvm/serialization/jsonitemformatassistant.h" -#include "mvvm/serialization/jsonmodelconverter.h" -#include "test_utils.h" -#include <QJsonArray> -#include <QJsonDocument> -#include <QJsonObject> -#include <stdexcept> - -using namespace ModelView; - -//! Checks JsonModel class and its ability to convert SessionModel to json and back. - -class JsonModelConverterTest : public FolderBasedTest { -public: - JsonModelConverterTest() : FolderBasedTest("test_JsonModelConverter") {} - ~JsonModelConverterTest(); -}; - -JsonModelConverterTest::~JsonModelConverterTest() = default; - -//! Creation of json object: empty model. - -TEST_F(JsonModelConverterTest, emptyModel) -{ - JsonModelConverter converter(ConverterMode::project); - SessionModel model("TestModel"); - - QJsonObject object = converter.to_json(model); - - EXPECT_EQ(object[JsonItemFormatAssistant::sessionModelKey], "TestModel"); - EXPECT_EQ(object[JsonItemFormatAssistant::itemsKey].toArray().size(), 0); - - JsonItemFormatAssistant assistant; - EXPECT_TRUE(assistant.isSessionModel(object)); -} - -//! Empty model to json and back. - -TEST_F(JsonModelConverterTest, emptyModelToJsonAndBack) -{ - JsonModelConverter converter(ConverterMode::project); - SessionModel model("TestModel"); - - QJsonObject object = converter.to_json(model); - - // attempt to reconstruct model of different type. - SessionModel target1("NewModel"); - EXPECT_THROW(converter.from_json(object, target1), std::runtime_error); - - // attempt to reconstruct non-empty model - SessionModel target2("TestModel"); - target2.insertItem<SessionItem>(); - EXPECT_NO_THROW(converter.from_json(object, target2)); - - // succesfull reconstruction - SessionModel target3("TestModel"); - EXPECT_NO_THROW(converter.from_json(object, target3)); - EXPECT_EQ(target3.rootItem()->childrenCount(), 0u); -} - -//! Creation of json object: single item in a model. - -TEST_F(JsonModelConverterTest, singleItemToJsonAndBack) -{ - JsonModelConverter converter(ConverterMode::project); - SessionModel model("TestModel"); - - auto item = model.insertItem<SessionItem>(); - - QJsonObject object = converter.to_json(model); - - // filling new model - SessionModel target("TestModel"); - converter.from_json(object, target); - EXPECT_EQ(target.rootItem()->childrenCount(), 1u); - auto reco_item = target.rootItem()->getItem("", 0); - EXPECT_EQ(reco_item->parent(), target.rootItem()); - EXPECT_EQ(reco_item->modelType(), item->modelType()); -} - -//! Filling model from json: parent and child in a model to json and back. - -TEST_F(JsonModelConverterTest, parentAndChildToJsonAndBack) -{ - JsonModelConverter converter(ConverterMode::project); - SessionModel model("TestModel"); - - // filling original model with content - auto parent = model.insertItem<SessionItem>(); - parent->setDisplayName("parent_name"); - parent->registerTag(TagInfo::universalTag("defaultTag"), /*set_as_default*/ true); - - parent->setData(QVariant::fromValue(42)); - auto child = model.insertItem<PropertyItem>(parent); - child->setDisplayName("child_name"); - - // writing model to json - QJsonObject object = converter.to_json(model); - - // reading model from json - SessionModel target("TestModel"); - converter.from_json(object, target); - - // accessing reconstructed parent and child - auto reco_parent = target.rootItem()->getItem("", 0); - auto reco_child = reco_parent->getItem("", 0); - - // checking parent reconstruction - EXPECT_EQ(reco_parent->model(), &target); - EXPECT_EQ(reco_parent->modelType(), GUI::Constants::BaseType); - EXPECT_EQ(reco_parent->parent(), target.rootItem()); - EXPECT_EQ(reco_parent->displayName(), - "SessionItem"); // Name changed because of ProjectConverter - EXPECT_EQ(reco_parent->childrenCount(), 1); - EXPECT_EQ(reco_parent->identifier(), parent->identifier()); - EXPECT_EQ(reco_parent->itemTags()->defaultTag(), "defaultTag"); - EXPECT_EQ(reco_parent->data<int>(), 42); - - // checking child reconstruction - EXPECT_EQ(reco_child->model(), &target); - EXPECT_EQ(reco_child->modelType(), GUI::Constants::PropertyType); - EXPECT_EQ(reco_child->parent(), reco_parent); - EXPECT_EQ(reco_child->displayName(), "Property"); // // Name changed because of ProjectConverter - EXPECT_EQ(reco_child->childrenCount(), 0); - EXPECT_EQ(reco_child->identifier(), child->identifier()); - EXPECT_EQ(reco_child->itemTags()->defaultTag(), ""); -} - -//! Item in a model to json and back: how persistent are identifiers. - -TEST_F(JsonModelConverterTest, identifiers) -{ - JsonModelConverter converter(ConverterMode::project); - auto pool1 = std::make_shared<ItemPool>(); - - // creating model and converting it to json - SessionModel source("SourceModel", pool1); - auto parent1 = source.insertItem<SessionItem>(); - QJsonObject json_source = converter.to_json(source); - - // creating source and filling it from json - auto pool2 = std::make_shared<ItemPool>(); - SessionModel target("SourceModel", pool2); - converter.from_json(json_source, target); - auto reco_parent = target.rootItem()->getItem("", 0); - - // comparing identifiers of two items from different models - auto id1 = parent1->identifier(); - auto id2 = reco_parent->identifier(); - EXPECT_EQ(id1, id2); - - // saving target in its own json - QJsonObject json_target = converter.to_json(target); - - // comparing text representations of two json - EXPECT_EQ(TestUtils::JsonToString(json_source), TestUtils::JsonToString(json_target)); - - // checking item registrations - EXPECT_EQ(pool1->item_for_key(id1), parent1); - EXPECT_EQ(pool2->item_for_key(id2), reco_parent); -} - -//! Filling model from json: parent and child in a model to json and back. - -TEST_F(JsonModelConverterTest, parentAndChildToFileAndBack) -{ - JsonModelConverter converter(ConverterMode::project); - SessionModel model("TestModel"); - - // filling original model with content - auto parent = model.insertItem<SessionItem>(); - parent->setDisplayName("parent_name"); - parent->registerTag(TagInfo::universalTag("defaultTag"), /*set_as_default*/ true); - - parent->setData(QVariant::fromValue(42)); - auto child = model.insertItem<PropertyItem>(parent); - child->setDisplayName("child_name"); - - // writing model to json - auto object = converter.to_json(model); - - // saving object to file - auto fileName = TestUtils::TestFileName(testDir(), "model.json"); - TestUtils::SaveJson(object, fileName); - - // converting document back to item - auto document = TestUtils::LoadJson(fileName); - SessionModel target("TestModel"); - converter.from_json(document.object(), target); - - // accessing reconstructed parent and child - auto reco_parent = target.rootItem()->getItem("", 0); - auto reco_child = reco_parent->getItem("", 0); - - // checking parent reconstruction - EXPECT_EQ(reco_parent->model(), &target); - EXPECT_EQ(reco_parent->modelType(), GUI::Constants::BaseType); - EXPECT_EQ(reco_parent->parent(), target.rootItem()); - EXPECT_EQ(reco_parent->displayName(), "SessionItem"); - EXPECT_EQ(reco_parent->childrenCount(), 1); - EXPECT_EQ(reco_parent->identifier(), parent->identifier()); - EXPECT_EQ(reco_parent->itemTags()->defaultTag(), "defaultTag"); - EXPECT_EQ(reco_parent->data<int>(), 42); - - // checking child reconstruction - EXPECT_EQ(reco_child->model(), &target); - EXPECT_EQ(reco_child->modelType(), GUI::Constants::PropertyType); - EXPECT_EQ(reco_child->parent(), reco_parent); - EXPECT_EQ(reco_child->displayName(), "Property"); - EXPECT_EQ(reco_child->childrenCount(), 0); - EXPECT_EQ(reco_child->identifier(), child->identifier()); - EXPECT_EQ(reco_child->itemTags()->defaultTag(), ""); -} - -//! Creation of json object (single item in a model), then writing same json object back -//! to model without emptying it. Real bug case: check if unsubscribtion mechanism works. - -TEST_F(JsonModelConverterTest, singleItemToJsonAndBackToSameModel) -{ - auto pool = std::make_shared<ItemPool>(); - - JsonModelConverter converter(ConverterMode::project); - SessionModel model("TestModel", pool); - auto item = model.insertItem<SessionItem>(); - - auto root_item = model.rootItem(); - auto root_id = root_item->identifier(); - auto item_id = item->identifier(); - - QJsonObject object = converter.to_json(model); - - // filling new model - converter.from_json(object, model); - - EXPECT_EQ(pool->size(), 2); - EXPECT_FALSE(pool->item_for_key(root_id) == model.rootItem()); // old root identifier has gone - EXPECT_TRUE(model.rootItem() != root_item); // old root item gone - - auto new_item = model.rootItem()->children().at(0); - EXPECT_EQ(pool->item_for_key(item_id), new_item); -} diff --git a/mvvm/tests/testmodel/jsontaginfoconverter.test.cpp b/mvvm/tests/testmodel/jsontaginfoconverter.test.cpp deleted file mode 100644 index d207a12f3bd5a31f391de8642ae6cc67966f9bd2..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/jsontaginfoconverter.test.cpp +++ /dev/null @@ -1,110 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/jsontaginfoconverter.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "folderbasedtest.h" -#include "google_test.h" -#include "mvvm/model/taginfo.h" -#include "mvvm/serialization/jsontaginfoconverter.h" -#include "test_utils.h" -#include <QJsonArray> -#include <QJsonDocument> -#include <QJsonObject> -#include <string> - -using namespace ModelView; - -//! Test convertion of TagInfo from/to QJsonObject. - -class JsonTagInfoConverterTest : public FolderBasedTest { -public: - JsonTagInfoConverterTest() : FolderBasedTest("test_JsonTagInfoConverter") {} - ~JsonTagInfoConverterTest(); -}; - -JsonTagInfoConverterTest::~JsonTagInfoConverterTest() = default; - -//! Checks if json object is correctly identified as representing TagInfo. - -TEST_F(JsonTagInfoConverterTest, isItemTag) -{ - JsonTagInfoConverter converter; - - // valid json object representing DataRole - QJsonObject object; - object[JsonTagInfoConverter::nameKey] = QString::fromStdString("tag1"); - object[JsonTagInfoConverter::minKey] = 0; - object[JsonTagInfoConverter::maxKey] = 1; - object[JsonTagInfoConverter::modelsKey] = QJsonArray(); - - EXPECT_TRUE(converter.isTagInfo(object)); - - // invalid (not fully constructed) json object which can't represent TagInfo - QJsonObject object2; - object2[JsonTagInfoConverter::minKey] = 42; - EXPECT_FALSE(converter.isTagInfo(object2)); -} - -//! Creating QJsonArray from TagInfo. - -TEST_F(JsonTagInfoConverterTest, toJson) -{ - JsonTagInfoConverter converter; - - TagInfo tag("tag1", 0, -1, std::vector<std::string>() = {}); - auto object = converter.to_json(tag); - - // this object represents TagInfo - EXPECT_TRUE(converter.isTagInfo(object)); -} - -//! From TagInfo to json and back. - -TEST_F(JsonTagInfoConverterTest, tagInfoToJsonAndBack) -{ - JsonTagInfoConverter converter; - - TagInfo tag("tag", 0, 42, std::vector<std::string>() = {"aaa", "bbb"}); - auto object = converter.to_json(tag); - - TagInfo reco_tag = converter.from_json(object); - - EXPECT_EQ(reco_tag.name(), tag.name()); - EXPECT_EQ(reco_tag.min(), tag.min()); - EXPECT_EQ(reco_tag.max(), tag.max()); - EXPECT_EQ(reco_tag.modelTypes(), tag.modelTypes()); -} - -//! To file and back. - -TEST_F(JsonTagInfoConverterTest, tagInfoToFileAndBack) -{ - const std::string tag_name("tag"); - const std::string model_type("model"); - JsonTagInfoConverter converter; - - TagInfo tag = TagInfo::propertyTag(tag_name, model_type); - auto object = converter.to_json(tag); - - // saving object to file - auto fileName = TestUtils::TestFileName(testDir(), "taginfo.json"); - TestUtils::SaveJson(object, fileName); - - auto document = TestUtils::LoadJson(fileName); - TagInfo reco_tag = converter.from_json(document.object()); - - EXPECT_EQ(reco_tag.name(), tag_name); - EXPECT_EQ(reco_tag.min(), 1); - EXPECT_EQ(reco_tag.max(), 1); - EXPECT_EQ(reco_tag.modelTypes(), std::vector<std::string>() = {model_type}); -} diff --git a/mvvm/tests/testmodel/jsonutils.test.cpp b/mvvm/tests/testmodel/jsonutils.test.cpp deleted file mode 100644 index bd4694be67f1941a199ba07902e49e8de8afb34c..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/jsonutils.test.cpp +++ /dev/null @@ -1,49 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/jsonutils.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/serialization/jsonutils.h" -#include "mvvm/utils/reallimits.h" -#include <limits> - -using namespace ModelView; - -class JsonUtilsTest : public ::testing::Test { -protected: - ~JsonUtilsTest(); -}; - -JsonUtilsTest::~JsonUtilsTest() = default; - -TEST_F(JsonUtilsTest, toString) -{ - EXPECT_EQ(JsonUtils::ToString(RealLimits::limitless()), "limitless"); - EXPECT_EQ(JsonUtils::ToString(RealLimits::positive()), "positive"); - EXPECT_EQ(JsonUtils::ToString(RealLimits::nonnegative()), "nonnegative"); - EXPECT_EQ(JsonUtils::ToString(RealLimits::lowerLimited(1.0)), "lowerlimited"); - EXPECT_EQ(JsonUtils::ToString(RealLimits::lowerLimited(1.042)), "lowerlimited"); - EXPECT_EQ(JsonUtils::ToString(RealLimits::lowerLimited(-0.99)), "lowerlimited"); - EXPECT_EQ(JsonUtils::ToString(RealLimits::upperLimited(1.0)), "upperlimited"); - EXPECT_EQ(JsonUtils::ToString(RealLimits::limited(-1.0, 2.0)), "limited"); -} - -TEST_F(JsonUtilsTest, CreateLimits) -{ - EXPECT_EQ(JsonUtils::CreateLimits("limitless"), RealLimits::limitless()); - EXPECT_EQ(JsonUtils::CreateLimits("positive"), RealLimits::positive()); - EXPECT_EQ(JsonUtils::CreateLimits("nonnegative"), RealLimits::nonnegative()); - EXPECT_EQ(JsonUtils::CreateLimits("lowerlimited", 1.0, 0.0), RealLimits::lowerLimited(1.0)); - EXPECT_EQ(JsonUtils::CreateLimits("upperlimited", 0.0, 42.0), RealLimits::upperLimited(42.0)); - EXPECT_EQ(JsonUtils::CreateLimits("limited", -1.0, 2.0), RealLimits::limited(-1.0, 2.0)); -} diff --git a/mvvm/tests/testmodel/jsonvariantconverter.test.cpp b/mvvm/tests/testmodel/jsonvariantconverter.test.cpp deleted file mode 100644 index fcbdc5e07eb079036376c6c989b523cadf65c0aa..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/jsonvariantconverter.test.cpp +++ /dev/null @@ -1,344 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/jsonvariantconverter.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "folderbasedtest.h" -#include "google_test.h" -#include "mvvm/model/comboproperty.h" -#include "mvvm/model/customvariants.h" -#include "mvvm/model/externalproperty.h" -#include "mvvm/model/variant_constants.h" -#include "mvvm/serialization/jsonvariantconverter.h" -#include "mvvm/utils/reallimits.h" -#include "test_utils.h" -#include <QColor> -#include <QJsonArray> -#include <QJsonDocument> -#include <QJsonObject> -#include <vector> - -using namespace ModelView; - -//! Test convertion of QVariant from/to QJsonObject. - -class JsonVariantConverterTest : public FolderBasedTest { -public: - JsonVariantConverterTest() : FolderBasedTest("test_JsonVariant") {} - ~JsonVariantConverterTest(); - - static QVariant ToJsonAndBack(const QVariant& variant) - { - JsonVariantConverter converter; - auto json = converter.get_json(variant); - return converter.get_variant(json); - } -}; - -JsonVariantConverterTest::~JsonVariantConverterTest() = default; - -//! Invalid QVariant conversion. - -TEST_F(JsonVariantConverterTest, invalidVariant) -{ - JsonVariantConverter converter; - - QVariant variant; - - // from variant to json object - auto object = converter.get_json(variant); - EXPECT_TRUE(converter.isVariant(object)); - - // from json object to variant - QVariant reco_variant = converter.get_variant(object); - EXPECT_FALSE(reco_variant.isValid()); - EXPECT_EQ(variant, reco_variant); -} - -//! Bool QVariant conversion. - -TEST_F(JsonVariantConverterTest, boolVariant) -{ - JsonVariantConverter converter; - - const bool value(true); - QVariant variant(value); - - // from variant to json object - auto object = converter.get_json(variant); - EXPECT_TRUE(converter.isVariant(object)); - - // from json object to variant - QVariant reco_variant = converter.get_variant(object); - EXPECT_TRUE(Utils::IsBoolVariant(reco_variant)); - EXPECT_EQ(reco_variant.value<bool>(), value); - EXPECT_EQ(reco_variant.typeName(), GUI::Constants::bool_type_name); - EXPECT_EQ(variant, reco_variant); - - EXPECT_EQ(ToJsonAndBack(true).value<bool>(), true); - EXPECT_EQ(ToJsonAndBack(false).value<bool>(), false); -} - -//! Int QVariant conversion. - -TEST_F(JsonVariantConverterTest, intVariant) -{ - JsonVariantConverter converter; - - const int value(42); - QVariant variant(value); - - // from variant to json object - auto object = converter.get_json(variant); - EXPECT_TRUE(converter.isVariant(object)); - - // from json object to variant - QVariant reco_variant = converter.get_variant(object); - EXPECT_TRUE(Utils::IsIntVariant(reco_variant)); - EXPECT_EQ(reco_variant.value<int>(), value); - EXPECT_EQ(reco_variant.typeName(), GUI::Constants::int_type_name); - EXPECT_EQ(variant, reco_variant); -} - -//! QVariant(std::string) conversion. - -TEST_F(JsonVariantConverterTest, stringVariant) -{ - JsonVariantConverter converter; - - const std::string value("abc"); - QVariant variant = QVariant::fromValue(value); - - // from variant to json object - auto object = converter.get_json(variant); - EXPECT_TRUE(converter.isVariant(object)); - - // from json object to variant - QVariant reco_variant = converter.get_variant(object); - EXPECT_TRUE(Utils::IsStdStringVariant(reco_variant)); - EXPECT_EQ(reco_variant.typeName(), GUI::Constants::string_type_name); - EXPECT_EQ(reco_variant.value<std::string>(), value); - - EXPECT_EQ(variant, reco_variant); -} - -//! QVariant(double) conversion. - -TEST_F(JsonVariantConverterTest, doubleVariant) -{ - JsonVariantConverter converter; - - double value(43.2); - QVariant variant = QVariant::fromValue(value); - EXPECT_EQ(variant.typeName(), GUI::Constants::double_type_name); - - // from variant to json object - auto object = converter.get_json(variant); - EXPECT_TRUE(converter.isVariant(object)); - - // from json object to variant - QVariant reco_variant = converter.get_variant(object); - EXPECT_TRUE(Utils::IsDoubleVariant(reco_variant)); - EXPECT_EQ(reco_variant.value<double>(), value); - EXPECT_EQ(variant, reco_variant); - - // more numbers - value = 1e-03; - EXPECT_DOUBLE_EQ(ToJsonAndBack(value).value<double>(), value); - value = 0.99e-7; - EXPECT_DOUBLE_EQ(ToJsonAndBack(value).value<double>(), value); - value = 3.14159265359; - EXPECT_DOUBLE_EQ(ToJsonAndBack(value).value<double>(), value); -} - -//! QVariant(double) conversion. Special value 43.0 which Qt likes to cast to int based variant. - -TEST_F(JsonVariantConverterTest, doubleVariantWhichLooksAsInt) -{ - JsonVariantConverter converter; - - double value(43.0); // special value which Qt like to cast to int-based variant - QVariant variant = QVariant::fromValue(value); - EXPECT_EQ(variant.typeName(), GUI::Constants::double_type_name); - EXPECT_TRUE(Utils::IsDoubleVariant(variant)); - - // from variant to json object - auto object = converter.get_json(variant); - EXPECT_TRUE(converter.isVariant(object)); - - // from json object to variant - QVariant reco_variant = converter.get_variant(object); - EXPECT_TRUE(Utils::IsDoubleVariant(reco_variant)); - EXPECT_EQ(reco_variant.value<double>(), value); - EXPECT_EQ(variant, reco_variant); -} - -//! QVariant(std::vector<double>) conversion. - -TEST_F(JsonVariantConverterTest, vectorOfDoubleVariant) -{ - JsonVariantConverter converter; - - const std::vector<double> value = {42.0, 43.0, 44.0}; - QVariant variant = QVariant::fromValue(value); - - // from variant to json object - auto object = converter.get_json(variant); - EXPECT_TRUE(converter.isVariant(object)); - - // from json object to variant - QVariant reco_variant = converter.get_variant(object); - EXPECT_TRUE(Utils::IsDoubleVectorVariant(reco_variant)); - EXPECT_EQ(reco_variant.value<std::vector<double>>(), value); - EXPECT_EQ(variant, reco_variant); -} - -//! QVariant(ComboProperty) conversion. - -TEST_F(JsonVariantConverterTest, comboPropertyVariant) -{ - JsonVariantConverter converter; - - ComboProperty value = ComboProperty::createFrom(std::vector<std::string>({"a1", "a2", "a3"})); - value.setSelected("a1", false); - value.setSelected("a2", true); - value.setSelected("a3", true); - - QVariant variant = QVariant::fromValue(value); - - // from variant to json object - auto object = converter.get_json(variant); - EXPECT_TRUE(converter.isVariant(object)); - - // from json object to variant - QVariant reco_variant = converter.get_variant(object); - EXPECT_TRUE(Utils::IsComboVariant(reco_variant)); - EXPECT_EQ(reco_variant.value<ComboProperty>(), value); - EXPECT_EQ(variant, reco_variant); -} - -//! QVariant(QColor) conversion. - -TEST_F(JsonVariantConverterTest, colorVariant) -{ - JsonVariantConverter converter; - - const QColor value(Qt::red); - QVariant variant = QVariant::fromValue(value); - - // from variant to json object - auto object = converter.get_json(variant); - EXPECT_TRUE(converter.isVariant(object)); - - // from json object to variant - QVariant reco_variant = converter.get_variant(object); - EXPECT_TRUE(Utils::IsColorVariant(reco_variant)); - EXPECT_EQ(reco_variant.value<QColor>(), value); - EXPECT_EQ(variant, reco_variant); -} - -//! QVariant(ExternalProperty) conversion. - -TEST_F(JsonVariantConverterTest, extPropVariant) -{ - JsonVariantConverter converter; - - const ExternalProperty value("abc", QColor(Qt::green), "123"); - QVariant variant = QVariant::fromValue(value); - - // from variant to json object - auto object = converter.get_json(variant); - EXPECT_TRUE(converter.isVariant(object)); - - // from json object to variant - QVariant reco_variant = converter.get_variant(object); - EXPECT_TRUE(Utils::IsExtPropertyVariant(reco_variant)); - EXPECT_EQ(reco_variant.value<ExternalProperty>(), value); - EXPECT_EQ(variant, reco_variant); -} - -//! QVariant(RealLimits) convertion. - -TEST_F(JsonVariantConverterTest, realLimitsVariant) -{ - JsonVariantConverter converter; - - RealLimits value = RealLimits::limited(1.0, 2.0); - QVariant variant = QVariant::fromValue(value); - - // from variant to json object - auto object = converter.get_json(variant); - EXPECT_TRUE(converter.isVariant(object)); - - // from json object to variant - QVariant reco_variant = converter.get_variant(object); - EXPECT_TRUE(Utils::IsRealLimitsVariant(reco_variant)); - EXPECT_EQ(reco_variant.value<RealLimits>(), value); - EXPECT_EQ(variant, reco_variant); - - // more values - value = RealLimits::positive(); - EXPECT_EQ(ToJsonAndBack(QVariant::fromValue(value)).value<RealLimits>(), value); - value = RealLimits::nonnegative(); - EXPECT_EQ(ToJsonAndBack(QVariant::fromValue(value)).value<RealLimits>(), value); - value = RealLimits::limited(0.123, 0.124); - EXPECT_EQ(ToJsonAndBack(QVariant::fromValue(value)).value<RealLimits>(), value); -} - -//! Writing variants to file and reading them back. - -TEST_F(JsonVariantConverterTest, toFileAndBack) -{ - const std::string string_value("abc"); - const std::vector<double> vector_value = {42.1, 42.2, 42.3}; - ComboProperty combo = ComboProperty::createFrom({"a 1", "a 2", "a/3"}); - combo.setSelected("a 1", false); - combo.setSelected("a 2", true); - combo.setSelected("a/3", true); - QColor color(Qt::red); - ExternalProperty extprop("abc", QColor(Qt::green), "1-2-3"); - - std::vector<QVariant> variants = {QVariant(), - QVariant(true), - QVariant(42), - QVariant(42.3), - QVariant(43.0), - QVariant(43.1), - QVariant(0.99e-7), - QVariant(3.14159265359), - QVariant::fromValue(string_value), - QVariant::fromValue(vector_value), - QVariant::fromValue(combo), - QVariant::fromValue(color), - QVariant::fromValue(extprop), - QVariant::fromValue(RealLimits::positive()), - QVariant::fromValue(RealLimits::limited(1.12, 2.32))}; - - // preparing array of json objects - JsonVariantConverter converter; - QJsonArray json_array; - for (auto var : variants) - json_array.append(converter.get_json(var)); - - // writing to file - auto fileName = TestUtils::TestFileName(testDir(), "variants.json"); - TestUtils::SaveJson(json_array, fileName); - - // reading variants from file - auto document = TestUtils::LoadJson(fileName); - std::vector<QVariant> reco_variants; - for (const auto x : document.array()) - reco_variants.push_back(converter.get_variant(x.toObject())); - - // comparing initial and reconstructed variants - EXPECT_EQ(variants, reco_variants); -} diff --git a/mvvm/tests/testmodel/linkeditem.test.cpp b/mvvm/tests/testmodel/linkeditem.test.cpp deleted file mode 100644 index 3cfbaa8a34b4ddd242dda0538b983ce38240c010..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/linkeditem.test.cpp +++ /dev/null @@ -1,128 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/linkeditem.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mockwidgets.h" -#include "mvvm/model/itempool.h" -#include "mvvm/model/propertyitem.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/standarditems/linkeditem.h" - -using namespace ModelView; -using ::testing::_; - -//! LinkedItem tests. - -class LinkedItemTest : public ::testing::Test { -public: - ~LinkedItemTest(); -}; - -LinkedItemTest::~LinkedItemTest() = default; - -//! Initial state of item when it is created outside of model context. - -TEST_F(LinkedItemTest, initialState) -{ - LinkedItem item; - EXPECT_EQ(item.get(), nullptr); - EXPECT_EQ(item.data<std::string>(), ""); -} - -//! Link in single model context. - -TEST_F(LinkedItemTest, sameModelContext) -{ - SessionModel model; - auto item = model.insertItem<PropertyItem>(); - auto link = model.insertItem<LinkedItem>(); - - // no link by default - EXPECT_EQ(link->get(), nullptr); - - // setting the link - link->setLink(item); - - // now linked - EXPECT_EQ(link->get(), item); - EXPECT_EQ(link->data<std::string>(), item->identifier()); -} - -//! Link in different model context. - -TEST_F(LinkedItemTest, differentModelContext) -{ - auto pool = std::make_shared<ItemPool>(); - - SessionModel model1("TestModel1", pool); - SessionModel model2("TestModel2", pool); - - auto item = model1.insertItem<PropertyItem>(); - auto link = model2.insertItem<LinkedItem>(); - - // no link by default - EXPECT_EQ(link->get(), nullptr); - - // setting the link - link->setLink(item); - - // now linked - EXPECT_EQ(link->get(), item); -} - -//! Signals when links is set. - -TEST_F(LinkedItemTest, onSetLink) -{ - SessionModel model; - auto item = model.insertItem<PropertyItem>(); - auto link = model.insertItem<LinkedItem>(); - - // no link by default - EXPECT_EQ(link->get(), nullptr); - - MockWidgetForItem widget(link); - - auto expected_role = ItemDataRole::DATA; - auto expected_item = link; - EXPECT_CALL(widget, onDataChange(expected_item, expected_role)).Times(1); - EXPECT_CALL(widget, onPropertyChange(_, _)).Times(0); - - // making action - link->setLink(item); -} - -//! Link in different model context. - -TEST_F(LinkedItemTest, setNullAsLink) -{ - auto pool = std::make_shared<ItemPool>(); - - SessionModel model("TestModel", pool); - auto link = model.insertItem<LinkedItem>(); - auto item = model.insertItem<PropertyItem>(); - - // no link by default - EXPECT_EQ(link->get(), nullptr); - - // setting link - link->setLink(item); - EXPECT_EQ(link->get(), item); - - // still null link - link->setLink(nullptr); - EXPECT_EQ(link->get(), nullptr); - EXPECT_TRUE(link->data<QVariant>().isValid()); - EXPECT_EQ(link->data<std::string>(), ""); -} diff --git a/mvvm/tests/testmodel/modelhaschangedcontroller.test.cpp b/mvvm/tests/testmodel/modelhaschangedcontroller.test.cpp deleted file mode 100644 index 6685a9d83e98e4639244015ad6a68f21aaeab693..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/modelhaschangedcontroller.test.cpp +++ /dev/null @@ -1,135 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/modelhaschangedcontroller.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/model/propertyitem.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/project/modelhaschangedcontroller.h" - -using namespace ModelView; - -//! Tests for ModelHasChangedController class. - -class ModelHasChangedControllerTest : public ::testing::Test { -public: - ~ModelHasChangedControllerTest(); -}; - -ModelHasChangedControllerTest::~ModelHasChangedControllerTest() = default; - -//! Tests initial state of the controller. - -TEST_F(ModelHasChangedControllerTest, initialState) -{ - SessionModel model; - ModelHasChangedController controller(&model); - EXPECT_FALSE(controller.hasChanged()); -} - -//! Tests if controller 'sees' item insertion. - -TEST_F(ModelHasChangedControllerTest, insertItem) -{ - SessionModel model; - ModelHasChangedController controller(&model); - - model.insertItem<PropertyItem>(); - EXPECT_TRUE(controller.hasChanged()); - - controller.resetChanged(); - EXPECT_FALSE(controller.hasChanged()); -} - -//! Tests if controller sees item insertion. - -TEST_F(ModelHasChangedControllerTest, removeItem) -{ - SessionModel model; - model.insertItem<PropertyItem>(); - - ModelHasChangedController controller(&model); - EXPECT_FALSE(controller.hasChanged()); - - model.removeItem(model.rootItem(), {"", 0}); - - EXPECT_TRUE(controller.hasChanged()); -} - -//! Tests if controller sees item data change. - -TEST_F(ModelHasChangedControllerTest, dataChanged) -{ - SessionModel model; - auto item = model.insertItem<PropertyItem>(); - - ModelHasChangedController controller(&model); - EXPECT_FALSE(controller.hasChanged()); - - item->setData(42.0); - EXPECT_TRUE(controller.hasChanged()); -} - -//! Tests if controller sees model reset. - -TEST_F(ModelHasChangedControllerTest, modelReset) -{ - SessionModel model; - model.insertItem<PropertyItem>(); - - ModelHasChangedController controller(&model); - EXPECT_FALSE(controller.hasChanged()); - - model.clear(); - EXPECT_TRUE(controller.hasChanged()); -} - -//! Tests callback functioning. - -TEST_F(ModelHasChangedControllerTest, callback) -{ - int change_count{0}; - auto on_change = [&change_count]() { change_count++; }; - - SessionModel model; - ModelHasChangedController controller(&model, on_change); - - model.insertItem<PropertyItem>(); - EXPECT_TRUE(controller.hasChanged()); - EXPECT_EQ(change_count, 1); - - controller.resetChanged(); - EXPECT_FALSE(controller.hasChanged()); - EXPECT_EQ(change_count, 1); -} - -//! Tests callback functioning. - -TEST_F(ModelHasChangedControllerTest, timeOfLife) -{ - int change_count{0}; - auto on_change = [&change_count]() { change_count++; }; - - SessionModel model; - auto controller = std::make_unique<ModelHasChangedController>(&model, on_change); - - // change the model, check controller - model.insertItem<PropertyItem>(); - EXPECT_TRUE(controller->hasChanged()); - EXPECT_EQ(change_count, 1); - - // remove controller, change the model - controller.reset(); - model.insertItem<PropertyItem>(); - EXPECT_EQ(change_count, 1); -} diff --git a/mvvm/tests/testmodel/modellistener.test.cpp b/mvvm/tests/testmodel/modellistener.test.cpp deleted file mode 100644 index a841df460f1204f5013d5eccb72cd73a08df0bf3..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/modellistener.test.cpp +++ /dev/null @@ -1,98 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/modellistener.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/model/propertyitem.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/signals/modellistener.h" -#include <memory> - -using namespace ModelView; - -//! Tests of ModelListener class. - -class ModelListenerTest : public ::testing::Test { -public: - class TestListener : public ModelListener<SessionModel> { - public: - TestListener(SessionModel* model) : ModelListener(model) {} - ~TestListener(); - }; - - ~ModelListenerTest(); -}; - -ModelListenerTest::~ModelListenerTest() = default; -ModelListenerTest::TestListener::~TestListener() = default; - -//! Initial state. - -TEST_F(ModelListenerTest, initialState) -{ - SessionModel model; - TestListener listener(&model); - EXPECT_EQ(listener.model(), &model); -} - -TEST_F(ModelListenerTest, onDataChange) -{ - auto model = std::make_unique<SessionModel>(); - auto listener = std::make_unique<TestListener>(model.get()); - - int counter{0}; - auto on_data_change = [&counter](SessionItem*, int) { counter++; }; - listener->setOnDataChange(on_data_change); - - auto item = model->insertItem<PropertyItem>(); - item->setData(42.0); - - EXPECT_EQ(counter, 1); -} - -//! Check that controller aware of item deletion. - -TEST_F(ModelListenerTest, modelDeletedBeforeListener) -{ - auto model = std::make_unique<SessionModel>(); - auto listener = std::make_unique<TestListener>(model.get()); - - EXPECT_EQ(listener->model(), model.get()); - - model.reset(); - EXPECT_EQ(listener->model(), nullptr); -} - -//! Checks that the listenerr can be deleted before the model. - -TEST_F(ModelListenerTest, listenerDeletedBeforeTheModel) -{ - // create model and its listener - auto model = std::make_unique<SessionModel>(); - auto listener = std::make_unique<TestListener>(model.get()); - - // assign to data-changed event - int counter{0}; - auto on_data_change = [&counter](SessionItem*, int) { counter++; }; - listener->setOnDataChange(on_data_change); - - // changing the data and checking the listener - auto item = model->insertItem<PropertyItem>(); - item->setData(42.0); - EXPECT_EQ(counter, 1); - - // deleting the listener and trying to change the data again - listener.reset(); - item->setData(43.0); - EXPECT_EQ(counter, 1); -} diff --git a/mvvm/tests/testmodel/modelmapper.test.cpp b/mvvm/tests/testmodel/modelmapper.test.cpp deleted file mode 100644 index db3da8e5bf06506a19219e0270a7a8f39b2ca75c..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/modelmapper.test.cpp +++ /dev/null @@ -1,230 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/modelmapper.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mockwidgets.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/model/sessionitemtags.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/model/tagrow.h" -#include "mvvm/signals/modelmapper.h" - -using namespace ModelView; -using ::testing::_; - -//! Testing ModelMapper callbacks on basic model manipulations. - -class ModelMapperTest : public ::testing::Test { -public: - ~ModelMapperTest(); -}; - -ModelMapperTest::~ModelMapperTest() = default; - -//! Setting item data and checking corresponding signal. - -TEST(ModelMapperTest, onDataChange) -{ - SessionModel model; - MockWidgetForModel widget(&model); - - EXPECT_CALL(widget, onItemInserted(_, _)); - auto item = model.insertItem<SessionItem>(model.rootItem()); - - // expecting signal to be called once - const int role = ItemDataRole::DATA; - EXPECT_CALL(widget, onDataChange(item, role)).Times(1); - EXPECT_CALL(widget, onItemInserted(_, _)).Times(0); - EXPECT_CALL(widget, onAboutToRemoveItem(_, _)).Times(0); - EXPECT_CALL(widget, onItemRemoved(_, _)).Times(0); - EXPECT_CALL(widget, onModelDestroyed(_)).Times(0); - EXPECT_CALL(widget, onModelAboutToBeReset(_)).Times(0); - EXPECT_CALL(widget, onModelReset(_)).Times(0); - model.setData(item, 42.0, ItemDataRole::DATA); // perform action - - // setting same data shouldn't trigger the signal - EXPECT_CALL(widget, onDataChange(_, _)).Times(0); - EXPECT_CALL(widget, onItemInserted(_, _)).Times(0); - EXPECT_CALL(widget, onItemRemoved(_, _)).Times(0); - EXPECT_CALL(widget, onAboutToRemoveItem(_, _)).Times(0); - EXPECT_CALL(widget, onModelDestroyed(_)).Times(0); - EXPECT_CALL(widget, onModelAboutToBeReset(_)).Times(0); - EXPECT_CALL(widget, onModelReset(_)).Times(0); - model.setData(item, 42.0, ItemDataRole::DATA); // perform action - - // setting new data through item - EXPECT_CALL(widget, onDataChange(item, role)).Times(1); - EXPECT_CALL(widget, onItemInserted(_, _)).Times(0); - EXPECT_CALL(widget, onItemRemoved(_, _)).Times(0); - EXPECT_CALL(widget, onAboutToRemoveItem(_, _)).Times(0); - EXPECT_CALL(widget, onModelDestroyed(_)).Times(0); - EXPECT_CALL(widget, onModelAboutToBeReset(_)).Times(0); - EXPECT_CALL(widget, onModelReset(_)).Times(0); - item->setData(43.0); // perform action -} - -//! Testing signaling after unsubscribe. - -TEST(ModelMapperTest, onDataChangeUnsubscribe) -{ - SessionModel model; - MockWidgetForModel widget(&model); - - EXPECT_CALL(widget, onItemInserted(_, _)); - auto item = model.insertItem<SessionItem>(model.rootItem()); - - // unsubscribing - widget.setModel(nullptr); - - // no calls should be done - EXPECT_CALL(widget, onDataChange(_, _)).Times(0); - EXPECT_CALL(widget, onItemInserted(_, _)).Times(0); - EXPECT_CALL(widget, onAboutToRemoveItem(_, _)).Times(0); - EXPECT_CALL(widget, onItemRemoved(_, _)).Times(0); - EXPECT_CALL(widget, onModelDestroyed(_)).Times(0); - EXPECT_CALL(widget, onModelAboutToBeReset(_)).Times(0); - EXPECT_CALL(widget, onModelReset(_)).Times(0); - - item->setData(43.0); // perform action -} - -//! Testing signaling after subscribe/unsubscribe twice. - -TEST(ModelMapperTest, onDataChangeMultipleUnsubscribe) -{ - SessionModel model; - MockWidgetForModel widget(&model); - - EXPECT_CALL(widget, onItemInserted(_, _)); - auto item = model.insertItem<SessionItem>(model.rootItem()); - - // unsubscribing - widget.setModel(nullptr); - // subscribing again - widget.setModel(&model); - // unsubscribing - widget.setModel(nullptr); - // subscribing again - widget.setModel(&model); - - const int role = ItemDataRole::DATA; - EXPECT_CALL(widget, onDataChange(item, role)).Times(1); - EXPECT_CALL(widget, onItemInserted(_, _)).Times(0); - EXPECT_CALL(widget, onAboutToRemoveItem(_, _)).Times(0); - EXPECT_CALL(widget, onItemRemoved(_, _)).Times(0); - EXPECT_CALL(widget, onModelDestroyed(_)).Times(0); - EXPECT_CALL(widget, onModelAboutToBeReset(_)).Times(0); - EXPECT_CALL(widget, onModelReset(_)).Times(0); - model.setData(item, 42.0, ItemDataRole::DATA); // perform action -} - -//! Inserting item and checking corresponding signals. - -TEST(ModelMapperTest, onItemInserted) -{ - SessionModel model; - MockWidgetForModel widget(&model); - - EXPECT_CALL(widget, onDataChange(_, _)).Times(0); - const TagRow expected_tagrow{model.rootItem()->itemTags()->defaultTag(), 0}; - EXPECT_CALL(widget, onItemInserted(model.rootItem(), expected_tagrow)).Times(1); - EXPECT_CALL(widget, onItemRemoved(_, _)).Times(0); - EXPECT_CALL(widget, onAboutToRemoveItem(_, _)).Times(0); - EXPECT_CALL(widget, onModelDestroyed(_)).Times(0); - EXPECT_CALL(widget, onModelAboutToBeReset(_)).Times(0); - EXPECT_CALL(widget, onModelReset(_)).Times(0); - - // perform action - model.insertItem<SessionItem>(model.rootItem(), expected_tagrow); -} - -//! Inserting item and checking corresponding signals. - -TEST(ModelMapperTest, onItemRemoved) -{ - SessionModel model; - MockWidgetForModel widget(&model); - - const TagRow expected_tagrow{model.rootItem()->itemTags()->defaultTag(), 0}; - EXPECT_CALL(widget, onItemInserted(model.rootItem(), expected_tagrow)).Times(1); - model.insertItem<SessionItem>(model.rootItem(), expected_tagrow); - - EXPECT_CALL(widget, onDataChange(_, _)).Times(0); - EXPECT_CALL(widget, onItemInserted(_, _)).Times(0); - EXPECT_CALL(widget, onItemRemoved(model.rootItem(), expected_tagrow)).Times(1); - EXPECT_CALL(widget, onAboutToRemoveItem(model.rootItem(), expected_tagrow)).Times(1); - EXPECT_CALL(widget, onModelDestroyed(_)).Times(0); - EXPECT_CALL(widget, onModelAboutToBeReset(_)).Times(0); - EXPECT_CALL(widget, onModelReset(_)).Times(0); - // perform action - model.removeItem(model.rootItem(), expected_tagrow); -} - -//! Testing signals on model destruction. - -TEST(ModelMapperTest, onModelDestroyed) -{ - auto model = std::make_unique<SessionModel>(); - auto widget = std::make_unique<MockWidgetForModel>(model.get()); - - EXPECT_CALL(*widget, onDataChange(_, _)).Times(0); - EXPECT_CALL(*widget, onItemInserted(_, _)).Times(0); - EXPECT_CALL(*widget, onItemRemoved(_, _)).Times(0); - EXPECT_CALL(*widget, onAboutToRemoveItem(_, _)).Times(0); - EXPECT_CALL(*widget, onModelAboutToBeReset(_)).Times(0); - EXPECT_CALL(*widget, onModelReset(_)).Times(0); - EXPECT_CALL(*widget, onModelDestroyed(model.get())).Times(1); - - // perform action - model.reset(); -} - -//! Testing signals on model destruction. - -TEST(ModelMapperTest, onModelReset) -{ - auto model = std::make_unique<SessionModel>(); - auto widget = std::make_unique<MockWidgetForModel>(model.get()); - - EXPECT_CALL(*widget, onDataChange(_, _)).Times(0); - EXPECT_CALL(*widget, onItemInserted(_, _)).Times(0); - EXPECT_CALL(*widget, onItemRemoved(_, _)).Times(0); - EXPECT_CALL(*widget, onAboutToRemoveItem(_, _)).Times(0); - EXPECT_CALL(*widget, onModelDestroyed(_)).Times(0); - EXPECT_CALL(*widget, onModelAboutToBeReset(_)).Times(1); - EXPECT_CALL(*widget, onModelReset(model.get())).Times(1); - - // perform action - model->clear(); -} - -//! Testing signals on cleaning the model using rebuild function. - -TEST(ModelMapperTest, onClearRebuild) -{ - auto model = std::make_unique<SessionModel>(); - - auto widget = std::make_unique<MockWidgetForModel>(model.get()); - - EXPECT_CALL(*widget, onDataChange(_, _)).Times(0); - EXPECT_CALL(*widget, onItemInserted(_, _)).Times(1); - EXPECT_CALL(*widget, onItemRemoved(_, _)).Times(0); - EXPECT_CALL(*widget, onAboutToRemoveItem(_, _)).Times(0); - EXPECT_CALL(*widget, onModelDestroyed(_)).Times(0); - EXPECT_CALL(*widget, onModelAboutToBeReset(_)).Times(1); - EXPECT_CALL(*widget, onModelReset(model.get())).Times(1); - - auto rebuild = [](auto item) { item->insertItem(new SessionItem, TagRow::append()); }; - model->clear(rebuild); -} diff --git a/mvvm/tests/testmodel/modelutils.test.cpp b/mvvm/tests/testmodel/modelutils.test.cpp deleted file mode 100644 index c2ddb8d1a464bdc37443074fa682dfb8d3a6a92d..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/modelutils.test.cpp +++ /dev/null @@ -1,173 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/modelutils.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/model/modelutils.h" -#include "toyitems.h" -#include "toymodel.h" - -using namespace ModelView; - -class ModelUtilsTest : public ::testing::Test { -public: - ~ModelUtilsTest(); -}; - -ModelUtilsTest::~ModelUtilsTest() = default; - -TEST_F(ModelUtilsTest, topItem) -{ - ToyItems::SampleModel model; - EXPECT_EQ(Utils::TopItem<>(&model), nullptr); - EXPECT_EQ(Utils::TopItem<SessionItem>(&model), nullptr); - EXPECT_EQ(Utils::TopItem<ToyItems::MultiLayerItem>(&model), nullptr); - - auto multilayer1 = model.insertItem<ToyItems::MultiLayerItem>(); - model.insertItem<ToyItems::MultiLayerItem>(); - - EXPECT_EQ(Utils::TopItem<>(&model), multilayer1); - EXPECT_EQ(Utils::TopItem<SessionItem>(&model), multilayer1); - EXPECT_EQ(Utils::TopItem<ToyItems::MultiLayerItem>(&model), multilayer1); -} - -TEST_F(ModelUtilsTest, topItems) -{ - ToyItems::SampleModel model; - EXPECT_EQ(Utils::TopItems<>(&model).size(), 0); - EXPECT_EQ(Utils::TopItems<SessionItem>(&model).size(), 0); - EXPECT_EQ(Utils::TopItems<ToyItems::MultiLayerItem>(&model).size(), 0); - - auto multilayer1 = model.insertItem<ToyItems::MultiLayerItem>(); - auto particle = model.insertItem<ToyItems::ParticleItem>(); - auto multilayer2 = model.insertItem<ToyItems::MultiLayerItem>(); - - std::vector<SessionItem*> expected1 = {multilayer1, particle, multilayer2}; - EXPECT_EQ(Utils::TopItems<SessionItem>(&model), expected1); - std::vector<ToyItems::MultiLayerItem*> expected2 = {multilayer1, multilayer2}; - EXPECT_EQ(Utils::TopItems<ToyItems::MultiLayerItem>(&model), expected2); -} - -TEST_F(ModelUtilsTest, findItems) -{ - ToyItems::SampleModel model; - EXPECT_EQ(Utils::FindItems<>(&model).size(), 1); // because of rootItem - EXPECT_EQ(Utils::FindItems<SessionItem>(&model).size(), 1); // because of rootItem - EXPECT_EQ(Utils::FindItems<ToyItems::MultiLayerItem>(&model).size(), 0); - - auto multilayer1 = model.insertItem<ToyItems::MultiLayerItem>(); - model.insertItem<ToyItems::ParticleItem>(); - auto multilayer2 = model.insertItem<ToyItems::MultiLayerItem>(); - - std::vector<ToyItems::MultiLayerItem*> expected2 = {multilayer1, multilayer2}; - EXPECT_EQ(Utils::FindItems<ToyItems::MultiLayerItem>(&model), expected2); - - // adding layers to multilayer - auto layer1 = model.insertItem<ToyItems::LayerItem>(multilayer1); - auto layer2 = model.insertItem<ToyItems::LayerItem>(multilayer2); - - std::vector<ToyItems::LayerItem*> expected3 = {layer1, layer2}; - EXPECT_EQ(Utils::FindItems<ToyItems::LayerItem>(&model), expected3); -} - -TEST_F(ModelUtilsTest, CreateCopy) -{ - ToyItems::SampleModel model; - auto layer = model.insertItem<ToyItems::LayerItem>(); - layer->setProperty(ToyItems::LayerItem::P_THICKNESS, 42.0); - - auto modelCopy = Utils::CreateCopy<ToyItems::SampleModel>(model); - auto layerCopy = modelCopy->topItem<ToyItems::LayerItem>(); - EXPECT_EQ(layerCopy->property<double>(ToyItems::LayerItem::P_THICKNESS), 42.0); - - // Copied model has unique identifiers - EXPECT_FALSE(model.rootItem()->identifier() == modelCopy->rootItem()->identifier()); - EXPECT_FALSE(layerCopy->identifier() == layer->identifier()); -} - -TEST_F(ModelUtilsTest, CreateClone) -{ - ToyItems::SampleModel model; - auto layer = model.insertItem<ToyItems::LayerItem>(); - layer->setProperty(ToyItems::LayerItem::P_THICKNESS, 42.0); - - auto modelCopy = Utils::CreateClone<ToyItems::SampleModel>(model); - auto layerCopy = modelCopy->topItem<ToyItems::LayerItem>(); - EXPECT_EQ(layerCopy->property<double>(ToyItems::LayerItem::P_THICKNESS), 42.0); - - // Copied model has unique identifiers - EXPECT_TRUE(layerCopy->identifier() == layer->identifier()); - - // root item by current conveniton still has unique identifier event for cloned model - // probably for the uniformity this has to be changed, and test below changed to EXPECT_TRUE - // This will require change in JsonModelConverter - EXPECT_FALSE(model.rootItem()->identifier() == modelCopy->rootItem()->identifier()); -} - -TEST_F(ModelUtilsTest, DeleteItemFromModel) -{ - ToyItems::SampleModel model; - - auto item = model.insertItem<SessionItem>(); - EXPECT_EQ(model.rootItem()->childrenCount(), 1); - Utils::DeleteItemFromModel(item); - EXPECT_EQ(model.rootItem()->childrenCount(), 0); -} - -TEST_F(ModelUtilsTest, MoveItemUp) -{ - ToyItems::SampleModel model; - - auto multilayer = model.insertItem<ToyItems::MultiLayerItem>(); - auto layer0 = model.insertItem<ToyItems::LayerItem>(multilayer); - auto layer1 = model.insertItem<ToyItems::LayerItem>(multilayer); - auto layer2 = model.insertItem<ToyItems::LayerItem>(multilayer); - - std::vector<SessionItem*> expected = {layer0, layer1, layer2}; - - // original layout - EXPECT_EQ(multilayer->getItems(ToyItems::MultiLayerItem::T_LAYERS), expected); - - // moving top layer up doesn't change the order - Utils::MoveUp(layer0); - EXPECT_EQ(multilayer->getItems(ToyItems::MultiLayerItem::T_LAYERS), expected); - - // moving bottom layer up does change the order - Utils::MoveUp(layer2); - expected = {layer0, layer2, layer1}; - EXPECT_EQ(multilayer->getItems(ToyItems::MultiLayerItem::T_LAYERS), expected); -} - -TEST_F(ModelUtilsTest, MoveItemDown) -{ - ToyItems::SampleModel model; - - auto multilayer = model.insertItem<ToyItems::MultiLayerItem>(); - auto layer0 = model.insertItem<ToyItems::LayerItem>(multilayer); - auto layer1 = model.insertItem<ToyItems::LayerItem>(multilayer); - auto layer2 = model.insertItem<ToyItems::LayerItem>(multilayer); - - std::vector<SessionItem*> expected = {layer0, layer1, layer2}; - - // original layout - EXPECT_EQ(multilayer->getItems(ToyItems::MultiLayerItem::T_LAYERS), expected); - - // moving bottom layer down doesn't change the order - Utils::MoveDown(layer2); - EXPECT_EQ(multilayer->getItems(ToyItems::MultiLayerItem::T_LAYERS), expected); - - // moving top layer down doesn't change the order - Utils::MoveDown(layer0); - expected = {layer1, layer0, layer2}; - EXPECT_EQ(multilayer->getItems(ToyItems::MultiLayerItem::T_LAYERS), expected); -} diff --git a/mvvm/tests/testmodel/moveitemcommand.test.cpp b/mvvm/tests/testmodel/moveitemcommand.test.cpp deleted file mode 100644 index fa31719956479e1d70e29e47950bfc5cce7d8545..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/moveitemcommand.test.cpp +++ /dev/null @@ -1,335 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/moveitemcommand.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/commands/moveitemcommand.h" -#include "mvvm/model/itemutils.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/model/taginfo.h" - -using namespace ModelView; - -class MoveItemCommandTest : public ::testing::Test { -public: - ~MoveItemCommandTest(); -}; - -MoveItemCommandTest::~MoveItemCommandTest() = default; - -TEST_F(MoveItemCommandTest, rootContextNext) -{ - SessionModel model; - auto item0 = model.insertItem<SessionItem>(model.rootItem()); // 0 - auto item1 = model.insertItem<SessionItem>(model.rootItem()); // 1 - auto item2 = model.insertItem<SessionItem>(model.rootItem()); // 2 - auto item3 = model.insertItem<SessionItem>(model.rootItem()); // 3 - - // expecting 4 items in the order of insertion - std::vector<SessionItem*> expected = {item0, item1, item2, item3}; - EXPECT_EQ(model.rootItem()->children(), expected); - - // moving item1 to the next position - MoveItemCommand command(item1, model.rootItem(), {"", 2}); - command.execute(); - EXPECT_EQ(std::get<bool>(command.result()), true); - - // expecting new order of items - expected = {item0, item2, item1, item3}; - EXPECT_EQ(model.rootItem()->children(), expected); - - // undoing command - command.undo(); - EXPECT_EQ(std::get<bool>(command.result()), true); - expected = {item0, item1, item2, item3}; - EXPECT_EQ(model.rootItem()->children(), expected); - - // redoing - command.execute(); - EXPECT_EQ(std::get<bool>(command.result()), true); - EXPECT_EQ(command.isObsolete(), false); - - expected = {item0, item2, item1, item3}; - EXPECT_EQ(model.rootItem()->children(), expected); -} - -TEST_F(MoveItemCommandTest, rootContextSamePos) -{ - SessionModel model; - auto item0 = model.insertItem<SessionItem>(model.rootItem()); - auto item1 = model.insertItem<SessionItem>(model.rootItem()); - auto item2 = model.insertItem<SessionItem>(model.rootItem()); - auto item3 = model.insertItem<SessionItem>(model.rootItem()); - - // expecting 4 items in the order of insertion - std::vector<SessionItem*> expected = {item0, item1, item2, item3}; - EXPECT_EQ(model.rootItem()->children(), expected); - - // moving item1 to the same position - MoveItemCommand command(item1, model.rootItem(), {"", 1}); - command.execute(); - EXPECT_EQ(std::get<bool>(command.result()), true); - EXPECT_EQ(command.isObsolete(), false); - - // expecting new order of items - expected = {item0, item1, item2, item3}; - EXPECT_EQ(model.rootItem()->children(), expected); - - // undoing command - command.undo(); - EXPECT_EQ(std::get<bool>(command.result()), true); - EXPECT_EQ(command.isObsolete(), false); - - expected = {item0, item1, item2, item3}; - EXPECT_EQ(model.rootItem()->children(), expected); -} - -TEST_F(MoveItemCommandTest, rootContextPrev) -{ - SessionModel model; - auto item0 = model.insertItem<SessionItem>(model.rootItem()); - auto item1 = model.insertItem<SessionItem>(model.rootItem()); - auto item2 = model.insertItem<SessionItem>(model.rootItem()); - auto item3 = model.insertItem<SessionItem>(model.rootItem()); - - // expecting 4 items in the order of insertion - std::vector<SessionItem*> expected = {item0, item1, item2, item3}; - EXPECT_EQ(model.rootItem()->children(), expected); - - // moving item2 to item1's place - MoveItemCommand command(item2, model.rootItem(), {"", 1}); - command.execute(); - EXPECT_EQ(std::get<bool>(command.result()), true); - EXPECT_EQ(command.isObsolete(), false); - - // expecting new order of items - expected = {item0, item2, item1, item3}; - EXPECT_EQ(model.rootItem()->children(), expected); - - // undoing command - command.undo(); - EXPECT_EQ(std::get<bool>(command.result()), true); - EXPECT_EQ(command.isObsolete(), false); - - expected = {item0, item1, item2, item3}; - EXPECT_EQ(model.rootItem()->children(), expected); -} - -TEST_F(MoveItemCommandTest, rootContextLast) -{ - SessionModel model; - auto item0 = model.insertItem<SessionItem>(model.rootItem()); - auto item1 = model.insertItem<SessionItem>(model.rootItem()); - auto item2 = model.insertItem<SessionItem>(model.rootItem()); - auto item3 = model.insertItem<SessionItem>(model.rootItem()); - - // expecting 4 items in the order of insertion - std::vector<SessionItem*> expected = {item0, item1, item2, item3}; - EXPECT_EQ(model.rootItem()->children(), expected); - - // moving item0 in the back of the list - MoveItemCommand command(item0, model.rootItem(), {"", model.rootItem()->childrenCount() - 1}); - command.execute(); - EXPECT_EQ(std::get<bool>(command.result()), true); - EXPECT_EQ(command.isObsolete(), false); - - // expecting new order of items - expected = {item1, item2, item3, item0}; - EXPECT_EQ(model.rootItem()->children(), expected); - - // undoing command - command.undo(); - EXPECT_EQ(std::get<bool>(command.result()), true); - EXPECT_EQ(command.isObsolete(), false); - - expected = {item0, item1, item2, item3}; - EXPECT_EQ(model.rootItem()->children(), expected); -} - -TEST_F(MoveItemCommandTest, rootContextLast2) -{ - SessionModel model; - auto item0 = model.insertItem<SessionItem>(model.rootItem()); - auto item1 = model.insertItem<SessionItem>(model.rootItem()); - auto item2 = model.insertItem<SessionItem>(model.rootItem()); - auto item3 = model.insertItem<SessionItem>(model.rootItem()); - - // expecting 4 items in the order of insertion - std::vector<SessionItem*> expected = {item0, item1, item2, item3}; - EXPECT_EQ(model.rootItem()->children(), expected); - - // moving item0 in the back of the list - MoveItemCommand command(item0, model.rootItem(), {"", 3}); - command.execute(); - EXPECT_EQ(std::get<bool>(command.result()), true); - EXPECT_EQ(command.isObsolete(), false); - - // expecting new order of items - expected = {item1, item2, item3, item0}; - EXPECT_EQ(model.rootItem()->children(), expected); - - // undoing command - command.undo(); - EXPECT_EQ(std::get<bool>(command.result()), true); - EXPECT_EQ(command.isObsolete(), false); - - expected = {item0, item1, item2, item3}; - EXPECT_EQ(model.rootItem()->children(), expected); -} - -TEST_F(MoveItemCommandTest, fromRootToParent) -{ - SessionModel model; - auto item0 = model.insertItem<SessionItem>(model.rootItem()); - auto parent = model.insertItem<SessionItem>(model.rootItem()); - parent->registerTag(TagInfo::universalTag("tag1"), /*set_as_default*/ true); - - auto child0 = model.insertItem<SessionItem>(parent); - auto child1 = model.insertItem<SessionItem>(parent); - - // expected items for root item - std::vector<SessionItem*> expected = {item0, parent}; - EXPECT_EQ(model.rootItem()->children(), expected); - - // expected items for parent - expected = {child0, child1}; - EXPECT_EQ(parent->children(), expected); - - // moving item0 from root to parent - MoveItemCommand command(item0, parent, {"", 1}); - command.execute(); - EXPECT_EQ(std::get<bool>(command.result()), true); - EXPECT_EQ(command.isObsolete(), false); - - // expected items for root item - expected = {parent}; - EXPECT_EQ(model.rootItem()->children(), expected); - - // expected items for parent - expected = {child0, item0, child1}; - EXPECT_EQ(parent->children(), expected); - - // undoing command - command.undo(); - EXPECT_EQ(std::get<bool>(command.result()), true); - EXPECT_EQ(command.isObsolete(), false); - - // expected items for root item - expected = {item0, parent}; - EXPECT_EQ(model.rootItem()->children(), expected); - - // expected items for parent - expected = {child0, child1}; - EXPECT_EQ(parent->children(), expected); -} - -TEST_F(MoveItemCommandTest, fromParentToRoot) -{ - SessionModel model; - auto item0 = model.insertItem<SessionItem>(model.rootItem()); - auto parent = model.insertItem<SessionItem>(model.rootItem()); - parent->registerTag(TagInfo::universalTag("tag1"), /*set_as_default*/ true); - - auto child0 = model.insertItem<SessionItem>(parent); - auto child1 = model.insertItem<SessionItem>(parent); - - // expected items for root item - std::vector<SessionItem*> expected = {item0, parent}; - EXPECT_EQ(model.rootItem()->children(), expected); - - // expected items for parent - expected = {child0, child1}; - EXPECT_EQ(parent->children(), expected); - - // moving child0 from parent to root - MoveItemCommand command(child0, model.rootItem(), {"", 0}); - command.execute(); - EXPECT_EQ(std::get<bool>(command.result()), true); - EXPECT_EQ(command.isObsolete(), false); - - // expected items for root item - expected = {child0, item0, parent}; - EXPECT_EQ(model.rootItem()->children(), expected); - - // expected items for parent - expected = {child1}; - EXPECT_EQ(parent->children(), expected); - - // undoing command - command.undo(); - EXPECT_EQ(std::get<bool>(command.result()), true); - EXPECT_EQ(command.isObsolete(), false); - - // expected items for root item - expected = {item0, parent}; - EXPECT_EQ(model.rootItem()->children(), expected); - - // expected items for parent - expected = {child0, child1}; - EXPECT_EQ(parent->children(), expected); -} - -TEST_F(MoveItemCommandTest, betweenParentTags) -{ - SessionModel model; - auto parent = model.insertItem<SessionItem>(model.rootItem()); - parent->registerTag(TagInfo::universalTag("tag1")); - parent->registerTag(TagInfo::universalTag("tag2")); - - auto child0 = model.insertItem<SessionItem>(parent, "tag1"); - auto child1 = model.insertItem<SessionItem>(parent, "tag1"); - auto child2 = model.insertItem<SessionItem>(parent, "tag2"); - auto child3 = model.insertItem<SessionItem>(parent, "tag2"); - - // expected items for root item - std::vector<SessionItem*> expected = {parent}; - EXPECT_EQ(model.rootItem()->children(), expected); - - // expected items for parent - expected = {child0, child1, child2, child3}; - EXPECT_EQ(parent->children(), expected); - - // moving child2 to another tag - MoveItemCommand command(child2, parent, {"tag1", 0}); - command.execute(); - EXPECT_EQ(std::get<bool>(command.result()), true); - EXPECT_EQ(command.isObsolete(), false); - - // expected items for root item - expected = {parent}; - EXPECT_EQ(model.rootItem()->children(), expected); - - // expected items for parents tag - expected = {child2, child0, child1, child3}; - EXPECT_EQ(parent->children(), expected); - expected = {child2, child0, child1}; - EXPECT_EQ(parent->getItems("tag1"), expected); - expected = {child3}; - EXPECT_EQ(parent->getItems("tag2"), expected); - - // undoing command - command.undo(); - EXPECT_EQ(std::get<bool>(command.result()), true); - EXPECT_EQ(command.isObsolete(), false); - - // expected items for root item - expected = {parent}; - EXPECT_EQ(model.rootItem()->children(), expected); - - // expected items for parent - expected = {child0, child1}; - EXPECT_EQ(parent->getItems("tag1"), expected); - expected = {child2, child3}; - EXPECT_EQ(parent->getItems("tag2"), expected); -} diff --git a/mvvm/tests/testmodel/numericutils.test.cpp b/mvvm/tests/testmodel/numericutils.test.cpp deleted file mode 100644 index 12a4894a5c86a1e279c7ec0f12a1acdd18e27b09..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/numericutils.test.cpp +++ /dev/null @@ -1,35 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/numericutils.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/utils/numericutils.h" -#include <cmath> - -using namespace ModelView; - -class NumericUtilsTest : public ::testing::Test { -public: - ~NumericUtilsTest(); -}; - -NumericUtilsTest::~NumericUtilsTest() = default; - -TEST_F(NumericUtilsTest, areAlmostEqual) -{ - EXPECT_TRUE(Utils::AreAlmostEqual(0.0, 0.0)); - EXPECT_TRUE(Utils::AreAlmostEqual(1.0, 1.0)); - EXPECT_TRUE(Utils::AreAlmostEqual(10.0 / 100.0, 100.0 / 1000.0)); - EXPECT_TRUE(Utils::AreAlmostEqual(std::sin(0.0), 0.0)); - EXPECT_FALSE(Utils::AreAlmostEqual(std::cos(0.0), 0.0)); -} diff --git a/mvvm/tests/testmodel/path.test.cpp b/mvvm/tests/testmodel/path.test.cpp deleted file mode 100644 index 97f0b8d4a2bd141119ad7a501c40dea9c20ad553..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/path.test.cpp +++ /dev/null @@ -1,131 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/path.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/model/modelutils.h" -#include "mvvm/model/path.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/model/taginfo.h" -#include <memory> - -using namespace ModelView; - -class PathTest : public ::testing::Test { -public: - ~PathTest(); -}; - -PathTest::~PathTest() = default; - -TEST_F(PathTest, initialState) -{ - Path path; - EXPECT_TRUE(path.str().empty()); -} - -TEST_F(PathTest, append) -{ - Path path; - path.append(1); - EXPECT_EQ(path.str(), "1"); - - path.append(2); - EXPECT_EQ(path.str(), "1,2"); - - path.prepend(3); - EXPECT_EQ(path.str(), "3,1,2"); -} - -TEST_F(PathTest, fromVector) -{ - Path path = Path::fromVector({1, 2, 3}); - EXPECT_EQ(path.str(), "1,2,3"); -} - -TEST_F(PathTest, fromString) -{ - Path path = Path::fromString("3,2,3"); - EXPECT_EQ(path.str(), "3,2,3"); -} - -TEST_F(PathTest, PathFromItem) -{ - SessionModel model; - - // unexisting path - EXPECT_TRUE(Utils::PathFromItem(nullptr).str().empty()); - // yet another unexisting path - auto alienItem = std::make_unique<SessionItem>(); - EXPECT_TRUE(Utils::PathFromItem(alienItem.get()).str().empty()); - - // three children beneeth root item - auto item0 = model.insertItem<SessionItem>(); - item0->registerTag(TagInfo::universalTag("defaultTag"), /*set_as_default*/ true); - auto item1 = model.insertItem<SessionItem>(); - item1->registerTag(TagInfo::universalTag("defaultTag"), /*set_as_default*/ true); - auto item2 = model.insertItem<SessionItem>(); - item2->registerTag(TagInfo::universalTag("defaultTag"), /*set_as_default*/ true); - - EXPECT_EQ(Utils::PathFromItem(item0).str(), "0"); - EXPECT_EQ(Utils::PathFromItem(item1).str(), "1"); - EXPECT_EQ(Utils::PathFromItem(item2).str(), "2"); - - // adding granchildren to item0 - auto child00 = model.insertItem<SessionItem>(item0); - auto child01 = model.insertItem<SessionItem>(item0); - - EXPECT_EQ(Utils::PathFromItem(child00).str(), "0,0"); - EXPECT_EQ(Utils::PathFromItem(child01).str(), "0,1"); - - // adding grandchildren to item2 - auto child20 = model.insertItem<SessionItem>(item2); - child20->registerTag(TagInfo::universalTag("defaultTag"), /*set_as_default*/ true); - - auto child200 = model.insertItem<SessionItem>(child20); - auto child201 = model.insertItem<SessionItem>(child20); - - EXPECT_EQ(Utils::PathFromItem(child200).str(), "2,0,0"); - EXPECT_EQ(Utils::PathFromItem(child201).str(), "2,0,1"); -} - -TEST_F(PathTest, itemFromPath) -{ - SessionModel model; - - // access to non-existing item - Path non_existing; - non_existing.append(8); - EXPECT_EQ(Utils::ItemFromPath(model, non_existing), nullptr); - - auto item0 = model.insertItem<SessionItem>(); - item0->registerTag(TagInfo::universalTag("defaultTag"), /*set_as_default*/ true); - auto item1 = model.insertItem<SessionItem>(); - item1->registerTag(TagInfo::universalTag("defaultTag"), /*set_as_default*/ true); - auto item2 = model.insertItem<SessionItem>(); - item2->registerTag(TagInfo::universalTag("defaultTag"), /*set_as_default*/ true); - - EXPECT_EQ(Utils::ItemFromPath(model, Path::fromVector({0})), item0); - EXPECT_EQ(Utils::ItemFromPath(model, Path::fromVector({1})), item1); - EXPECT_EQ(Utils::ItemFromPath(model, Path::fromVector({2})), item2); - - auto child20 = model.insertItem<SessionItem>(item2); - child20->registerTag(TagInfo::universalTag("defaultTag"), /*set_as_default*/ true); - auto child200 = model.insertItem<SessionItem>(child20); - auto child201 = model.insertItem<SessionItem>(child20); - - EXPECT_EQ(Utils::ItemFromPath(model, Path::fromVector({2, 0})), child20); - EXPECT_EQ(Utils::ItemFromPath(model, Path::fromVector({2, 0, 0})), child200); - EXPECT_EQ(Utils::ItemFromPath(model, Path::fromVector({2, 0, 1})), child201); -} diff --git a/mvvm/tests/testmodel/plottableitems.test.cpp b/mvvm/tests/testmodel/plottableitems.test.cpp deleted file mode 100644 index 5ef46c4bd03a1d2c25818b183c3839cdc4025313..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/plottableitems.test.cpp +++ /dev/null @@ -1,57 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/plottableitems.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/model/comboproperty.h" -#include "mvvm/standarditems/plottableitems.h" -#include <QColor> - -using namespace ModelView; - -//! Testing PlottableItemsTest. - -class PlottableItemsTest : public ::testing::Test { -public: - ~PlottableItemsTest(); -}; - -PlottableItemsTest::~PlottableItemsTest() = default; - -//! Initial state. - -TEST_F(PlottableItemsTest, penItem_initialState) -{ - PenItem item; - EXPECT_EQ(item.property<QColor>(PenItem::P_COLOR), QColor(Qt::black)); - EXPECT_EQ(item.property<int>(PenItem::P_WIDTH), 1); - EXPECT_EQ(item.property<ComboProperty>(PenItem::P_STYLE).currentIndex(), Qt::SolidLine); -} - -TEST_F(PlottableItemsTest, penItem_setSelected) -{ - PenItem item; - - item.setSelected(true); - EXPECT_EQ(item.property<ComboProperty>(PenItem::P_STYLE).currentIndex(), Qt::DashLine); - - item.setSelected(false); - EXPECT_EQ(item.property<ComboProperty>(PenItem::P_STYLE).currentIndex(), Qt::SolidLine); -} - -TEST_F(PlottableItemsTest, penItem_setNamedColor) -{ - PenItem item; - item.setNamedColor("mediumaquamarine"); - EXPECT_EQ(item.colorName(), std::string("#66cdaa")); -} diff --git a/mvvm/tests/testmodel/progresshandler.test.cpp b/mvvm/tests/testmodel/progresshandler.test.cpp deleted file mode 100644 index fac76bf911ed562956da591fa024188d6d4edc76..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/progresshandler.test.cpp +++ /dev/null @@ -1,73 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/progresshandler.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/utils/progresshandler.h" - -using namespace ModelView; - -class ProgressHandlerTest : public ::testing::Test { -public: - ~ProgressHandlerTest(); -}; - -ProgressHandlerTest::~ProgressHandlerTest() = default; - -TEST_F(ProgressHandlerTest, initialState) -{ - ProgressHandler handler; - EXPECT_FALSE(handler.has_interrupt_request()); -} - -TEST_F(ProgressHandlerTest, fullConstructor) -{ - size_t max_ticks = 1000; - int progress{0}; - auto on_progress_change = [&progress](int value) { - progress = value; - return false; - }; - - ProgressHandler handler(on_progress_change, max_ticks); - - handler.setCompletedTicks(100); - EXPECT_FALSE(handler.has_interrupt_request()); - EXPECT_EQ(progress, 10); - - handler.setCompletedTicks(900); - EXPECT_FALSE(handler.has_interrupt_request()); - EXPECT_EQ(progress, 100); // reports value in percents -} - -TEST_F(ProgressHandlerTest, interruptRequest) -{ - size_t max_ticks = 1000; - int progress{0}; - auto on_progress_change = [&progress](int value) { - progress = value; - return true; - }; - - ProgressHandler handler(on_progress_change, max_ticks); - - handler.setCompletedTicks(1000); - EXPECT_TRUE(handler.has_interrupt_request()); - EXPECT_EQ(progress, 100); // reports value in percents - - // checking reset - handler.reset(); - EXPECT_FALSE(handler.has_interrupt_request()); - handler.setCompletedTicks(100); - EXPECT_EQ(progress, 10); // reports value in percents -} diff --git a/mvvm/tests/testmodel/project.test.cpp b/mvvm/tests/testmodel/project.test.cpp deleted file mode 100644 index a0789451eb37fb7d83923f9f1bf1b43a0f453f8e..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/project.test.cpp +++ /dev/null @@ -1,139 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/project.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "folderbasedtest.h" -#include "google_test.h" -#include "mvvm/model/propertyitem.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/project/project.h" -#include "mvvm/project/project_types.h" -#include "mvvm/utils/fileutils.h" -#include "test_utils.h" -#include <cctype> - -using namespace ModelView; - -namespace { -const std::string samplemodel_name = "SampleModel"; -const std::string materialmodel_name = "MaterialModel"; - -//! Constructs json file name from SessionModel typeName (as it is done internaly by Project). -std::string get_json_filename(const std::string& model_name) -{ - std::string result(model_name); - std::transform(result.begin(), result.end(), result.begin(), ::tolower); - return result + ".json"; -} - -} // namespace - -//! Tests for Project class. - -class ProjectTest : public FolderBasedTest { -public: - ProjectTest() - : FolderBasedTest("test_ProjectTest") - , sample_model(std::make_unique<SessionModel>(samplemodel_name)) - , material_model(std::make_unique<SessionModel>(materialmodel_name)) - { - } - ~ProjectTest(); - - std::vector<SessionModel*> models() const - { - return {sample_model.get(), material_model.get()}; - }; - - ProjectContext createContext() - { - ProjectContext result; - result.m_models_callback = [this]() { return models(); }; - return result; - } - - std::unique_ptr<SessionModel> sample_model; - std::unique_ptr<SessionModel> material_model; -}; - -ProjectTest::~ProjectTest() = default; - -TEST_F(ProjectTest, initialState) -{ - Project project(createContext()); - EXPECT_TRUE(project.projectDir().empty()); - EXPECT_FALSE(project.isModified()); -} - -//! Testing saveModel. - -TEST_F(ProjectTest, saveModel) -{ - Project project(createContext()); - - // create project directory and save file - auto project_dir = createEmptyDir("Untitled1"); - project.save(project_dir); - - EXPECT_EQ(project.projectDir(), project_dir); - EXPECT_FALSE(project.isModified()); - - auto sample_json = Utils::join(project_dir, get_json_filename(samplemodel_name)); - EXPECT_TRUE(Utils::exists(sample_json)); - - auto material_json = Utils::join(project_dir, get_json_filename(materialmodel_name)); - EXPECT_TRUE(Utils::exists(material_json)); -} - -//! Testing loadModel. - -TEST_F(ProjectTest, loadModel) -{ - Project project(createContext()); - - auto item0 = sample_model->insertItem<PropertyItem>(); - item0->setData(std::string("sample_model_item")); - auto item0_identifier = item0->identifier(); - - auto item1 = material_model->insertItem<PropertyItem>(); - item1->setData(std::string("material_model_item")); - auto item1_identifier = item1->identifier(); - - // create project directory and save file - auto project_dir = createEmptyDir("Untitled2"); - - EXPECT_TRUE(project.isModified()); - project.save(project_dir); - EXPECT_FALSE(project.isModified()); - - EXPECT_EQ(project.projectDir(), project_dir); - - // cleaning models - sample_model->clear(); - material_model->clear(); - EXPECT_EQ(sample_model->rootItem()->childrenCount(), 0); - EXPECT_EQ(material_model->rootItem()->childrenCount(), 0); - EXPECT_TRUE(project.isModified()); - - // loading - project.load(project_dir); - EXPECT_EQ(sample_model->rootItem()->childrenCount(), 1); - EXPECT_EQ(material_model->rootItem()->childrenCount(), 1); - - // checking identifiers - EXPECT_EQ(sample_model->rootItem()->children()[0]->identifier(), item0_identifier); - EXPECT_EQ(material_model->rootItem()->children()[0]->identifier(), item1_identifier); - - EXPECT_EQ(project.projectDir(), project_dir); - EXPECT_FALSE(project.isModified()); -} diff --git a/mvvm/tests/testmodel/projectchangecontroller.test.cpp b/mvvm/tests/testmodel/projectchangecontroller.test.cpp deleted file mode 100644 index 81eb26f00c6d977a158e725c1c12d48a351610ec..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/projectchangecontroller.test.cpp +++ /dev/null @@ -1,81 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/projectchangecontroller.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/model/propertyitem.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/project/projectchangecontroller.h" - -using namespace ModelView; - -//! Tests for ProjectChangeController class. - -class ProjectChangeControllerTest : public ::testing::Test { -public: - ~ProjectChangeControllerTest(); -}; - -ProjectChangeControllerTest::~ProjectChangeControllerTest() = default; - -TEST_F(ProjectChangeControllerTest, initialState) -{ - SessionModel sample_model("SampleModel"); - SessionModel material_model("MaterialModel"); - std::vector<SessionModel*> models = {&sample_model, &material_model}; - - ProjectChangedController controller(models); - EXPECT_FALSE(controller.hasChanged()); -} - -TEST_F(ProjectChangeControllerTest, twoModelsChange) -{ - SessionModel sample_model("SampleModel"); - SessionModel material_model("MaterialModel"); - std::vector<SessionModel*> models = {&sample_model, &material_model}; - - ProjectChangedController controller(models); - - sample_model.insertItem<PropertyItem>(); - material_model.insertItem<PropertyItem>(); - - EXPECT_TRUE(controller.hasChanged()); - - controller.resetChanged(); - EXPECT_FALSE(controller.hasChanged()); -} - -TEST_F(ProjectChangeControllerTest, callback) -{ - int model_changed_count{0}; - - SessionModel sample_model("SampleModel"); - SessionModel material_model("MaterialModel"); - std::vector<SessionModel*> models = {&sample_model, &material_model}; - - auto on_model_changed = [&model_changed_count]() { ++model_changed_count; }; - ProjectChangedController controller(models, on_model_changed); - - // changing first model - sample_model.insertItem<PropertyItem>(); - EXPECT_TRUE(controller.hasChanged()); - EXPECT_EQ(model_changed_count, 1); - - // changing second model - material_model.insertItem<PropertyItem>(); - EXPECT_TRUE(controller.hasChanged()); - EXPECT_EQ(model_changed_count, 1); // controller reports only once - - controller.resetChanged(); - EXPECT_FALSE(controller.hasChanged()); -} diff --git a/mvvm/tests/testmodel/projectmanager.test.cpp b/mvvm/tests/testmodel/projectmanager.test.cpp deleted file mode 100644 index fa9cf5edde99ccbd2d22fe2c7bc57ca942d5dd8f..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/projectmanager.test.cpp +++ /dev/null @@ -1,253 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/projectmanager.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "folderbasedtest.h" -#include "google_test.h" -#include "mvvm/model/propertyitem.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/project/project_types.h" -#include "mvvm/project/projectmanager.h" -#include "mvvm/utils/fileutils.h" -#include "test_utils.h" -#include <cctype> - -using namespace ModelView; - -namespace { -const std::string samplemodel_name = "samplemodel"; - -} // namespace - -//! Tests for ProjectManager class. - -class ProjectManagerTest : public FolderBasedTest { -public: - ProjectManagerTest() - : FolderBasedTest("test_ProjectManager") - , sample_model(std::make_unique<ModelView::SessionModel>(samplemodel_name)) - { - } - ~ProjectManagerTest(); - - std::vector<SessionModel*> models() const { return {sample_model.get()}; }; - - ProjectContext createContext() - { - ProjectContext result; - result.m_models_callback = [this]() { return models(); }; - return result; - } - - std::unique_ptr<SessionModel> sample_model; -}; - -ProjectManagerTest::~ProjectManagerTest() = default; - -//! Initial state of ProjectManager. Project created, and not-saved. - -TEST_F(ProjectManagerTest, initialState) -{ - ProjectManager manager(createContext()); - EXPECT_TRUE(manager.currentProjectDir().empty()); - EXPECT_FALSE(manager.isModified()); -} - -// ---------------------------------------------------------------------------- -// Untitled, empty project -// ---------------------------------------------------------------------------- - -//! Creating new project. Use untitled+empty project as a starting point. -//! Should succeed, since old empty project doesn't need to be saved. - -TEST_F(ProjectManagerTest, untitledEmptyNew) -{ - ProjectManager manager(createContext()); - - const auto project_dir = createEmptyDir("Project_untitledEmptyNew"); - EXPECT_TRUE(manager.createNewProject(project_dir)); - - EXPECT_EQ(manager.currentProjectDir(), project_dir); - EXPECT_FALSE(manager.isModified()); - - // project directory should contain a json file with the model - auto model_json = Utils::join(project_dir, samplemodel_name + ".json"); - EXPECT_TRUE(Utils::exists(model_json)); -} - -//! Saving of new project. Use untitled+empty project as a starting point. -//! Should fail since project directory is not defined. - -TEST_F(ProjectManagerTest, untitledEmptySave) -{ - ProjectManager manager(createContext()); - EXPECT_FALSE(manager.saveCurrentProject()); - EXPECT_FALSE(manager.isModified()); -} - -//! Saving of new project. Use untitled+empty project as a starting point. -//! Should be saved, file sould appear on disk. - -TEST_F(ProjectManagerTest, untitledEmptySaveAs) -{ - ProjectManager manager(createContext()); - - const auto project_dir = createEmptyDir("Project_untitledEmptySaveAs"); - EXPECT_TRUE(manager.saveProjectAs(project_dir)); - EXPECT_FALSE(manager.isModified()); - - // project directory should contain a json file with the model - auto model_json = Utils::join(project_dir, samplemodel_name + ".json"); - EXPECT_TRUE(Utils::exists(model_json)); -} - -// ---------------------------------------------------------------------------- -// Untitled, modified -// ---------------------------------------------------------------------------- - -//! Creating new project. Use untitled+modified project as a starting point. -//! Should fail, since modified old project will prevent creation of the new one. - -TEST_F(ProjectManagerTest, untitledModifiedNew) -{ - ProjectManager manager(createContext()); - - // modifying the model - sample_model->insertItem<PropertyItem>(); - - EXPECT_TRUE(manager.isModified()); - - const auto project_dir = createEmptyDir("Project_untitledModifiedNew"); - EXPECT_FALSE(manager.createNewProject(project_dir)); - - EXPECT_TRUE(manager.currentProjectDir().empty()); - EXPECT_TRUE(manager.isModified()); - - // project directory should be empty - auto model_json = Utils::join(project_dir, samplemodel_name + ".json"); - EXPECT_FALSE(Utils::exists(model_json)); -} - -//! Saving of new project. Use untitled+modified project as a starting point. -//! Should fail since project directory is not defined. - -TEST_F(ProjectManagerTest, untitledModifiedSave) -{ - ProjectManager manager(createContext()); - // modifying the model - sample_model->insertItem<PropertyItem>(); - - EXPECT_FALSE(manager.saveCurrentProject()); - EXPECT_TRUE(manager.isModified()); -} - -//! Saving of new project. Use untitled+empty project as a starting point. -//! Should be saved, file sould appear on disk. - -TEST_F(ProjectManagerTest, untitledModifiedSaveAs) -{ - ProjectManager manager(createContext()); - sample_model->insertItem<PropertyItem>(); // modifying the model - - const auto project_dir = createEmptyDir("Project_untitledModifiedSaveAs"); - EXPECT_TRUE(manager.saveProjectAs(project_dir)); - EXPECT_FALSE(manager.isModified()); - - // project directory should contain a json file with the model - auto model_json = Utils::join(project_dir, samplemodel_name + ".json"); - EXPECT_TRUE(Utils::exists(model_json)); -} - -// ---------------------------------------------------------------------------- -// Titled, unmodified -// ---------------------------------------------------------------------------- - -//! Creating new project. Use titled+unmodified project as a starting point. -//! Should succeed, since old empty project doesn't need to be saved. - -TEST_F(ProjectManagerTest, titledUnmodifiedNew) -{ - ProjectManager manager(createContext()); - - const auto project_dir = createEmptyDir("Project_titledUnmodifiedNew"); - EXPECT_TRUE(manager.saveProjectAs(project_dir)); - EXPECT_EQ(manager.currentProjectDir(), project_dir); - - const auto project_dir2 = createEmptyDir("Project_titledUnmodifiedNew2"); - EXPECT_TRUE(manager.createNewProject(project_dir2)); - - EXPECT_EQ(manager.currentProjectDir(), project_dir2); - EXPECT_FALSE(manager.isModified()); - - // project directory should contain a json file with the model - auto model_json = Utils::join(project_dir2, samplemodel_name + ".json"); - EXPECT_TRUE(Utils::exists(model_json)); -} - -// ---------------------------------------------------------------------------- -// Titled, modified -// ---------------------------------------------------------------------------- - -//! Saving of new project. Use titled+modified project as a starting point. -//! Should succeed. - -TEST_F(ProjectManagerTest, titledModifiedSave) -{ - ProjectManager manager(createContext()); - - const auto project_dir = createEmptyDir("Project_titledModifiedSave"); - EXPECT_TRUE(manager.saveProjectAs(project_dir)); - EXPECT_EQ(manager.currentProjectDir(), project_dir); - - // modifying the model - sample_model->insertItem<PropertyItem>(); - - EXPECT_TRUE(manager.saveCurrentProject()); - EXPECT_FALSE(manager.isModified()); -} - -// ---------------------------------------------------------------------------- -// Callbacks -// ---------------------------------------------------------------------------- - -TEST_F(ProjectManagerTest, callback) -{ - int project_modified_count{0}; - - auto context = createContext(); - context.m_modified_callback = [&project_modified_count]() { ++project_modified_count; }; - - ProjectManager manager(context); - - EXPECT_EQ(project_modified_count, 0); - - // saving the project - const auto project_dir = createEmptyDir("Project_callback"); - EXPECT_TRUE(manager.saveProjectAs(project_dir)); - EXPECT_EQ(manager.currentProjectDir(), project_dir); - EXPECT_EQ(project_modified_count, 0); - - // modifying the model - sample_model->insertItem<PropertyItem>(); - EXPECT_EQ(project_modified_count, 1); - EXPECT_TRUE(manager.isModified()); - - // modifying the model second time - sample_model->insertItem<PropertyItem>(); - EXPECT_EQ(project_modified_count, 1); // do not sum up - EXPECT_TRUE(manager.isModified()); - - EXPECT_TRUE(manager.saveCurrentProject()); - EXPECT_FALSE(manager.isModified()); - EXPECT_EQ(project_modified_count, 1); -} diff --git a/mvvm/tests/testmodel/projectmanagerdecorator.test.cpp b/mvvm/tests/testmodel/projectmanagerdecorator.test.cpp deleted file mode 100644 index 4e8fc3ed970dd335962d9832b807534590879055..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/projectmanagerdecorator.test.cpp +++ /dev/null @@ -1,208 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/projectmanagerdecorator.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "folderbasedtest.h" -#include "google_test.h" -#include "mvvm/model/propertyitem.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/project/project_types.h" -#include "mvvm/project/projectmanagerdecorator.h" -#include "mvvm/utils/fileutils.h" -#include <cctype> - -using namespace ModelView; - -namespace { -const std::string samplemodel_name = "samplemodel"; - -} // namespace - -//! Tests for ProjectManager class. - -class ProjectManagerDecoratorTest : public FolderBasedTest { -public: - ProjectManagerDecoratorTest() - : FolderBasedTest("test_ProjectManagerDecorator") - , sample_model(std::make_unique<ModelView::SessionModel>(samplemodel_name)) - { - } - ~ProjectManagerDecoratorTest(); - - std::vector<SessionModel*> models() const { return {sample_model.get()}; }; - - ProjectContext projectContext() - { - ProjectContext result; - result.m_models_callback = [this]() { return models(); }; - return result; - } - - UserInteractionContext userContext(const std::string& create_dir = {}, - const std::string& select_dir = {}) - { - UserInteractionContext result; - result.m_create_dir_callback = [create_dir]() -> std::string { return create_dir; }; - result.m_select_dir_callback = [select_dir]() -> std::string { return select_dir; }; - return result; - } - - std::unique_ptr<SessionModel> sample_model; -}; - -ProjectManagerDecoratorTest::~ProjectManagerDecoratorTest() = default; - -//! Initial state of ProjectManager. Project created, and not-saved. - -TEST_F(ProjectManagerDecoratorTest, initialState) -{ - ProjectManagerDecorator manager(projectContext(), userContext()); - EXPECT_TRUE(manager.currentProjectDir().empty()); -} - -//! Starting from new document (without project dir defined). -//! Create new project in given directory. - -TEST_F(ProjectManagerDecoratorTest, untitledEmptyCreateNew) -{ - const auto project_dir = createEmptyDir("Project_untitledEmptyCreateNew"); - - ProjectManagerDecorator manager(projectContext(), userContext(project_dir, {})); - EXPECT_TRUE(manager.currentProjectDir().empty()); - - // saving new project to 'project_dir' directory. - EXPECT_TRUE(manager.createNewProject()); - - // checking that current projectDir has pointing to the right place - EXPECT_EQ(manager.currentProjectDir(), project_dir); - - // project directory should contain a json file with the model - auto model_json = Utils::join(project_dir, samplemodel_name + ".json"); - EXPECT_TRUE(Utils::exists(model_json)); -} - -//! Starting from new document (without project dir defined). -//! Saving project. Same behavior as SaveAs. - -TEST_F(ProjectManagerDecoratorTest, untitledEmptySaveCurrentProject) -{ - const auto project_dir = createEmptyDir("Project_untitledEmptySaveCurrentProject"); - - ProjectManagerDecorator manager(projectContext(), userContext(project_dir, {})); - EXPECT_TRUE(manager.currentProjectDir().empty()); - - // saving new project to 'project_dir' directory. - EXPECT_TRUE(manager.saveCurrentProject()); - - // checking thaxt current projectDir has pointing to the right place - EXPECT_EQ(manager.currentProjectDir(), project_dir); - - // project directory should contain a json file with the model - auto model_json = Utils::join(project_dir, samplemodel_name + ".json"); - EXPECT_TRUE(Utils::exists(model_json)); -} - -//! Starting from new document (without project dir defined). -//! Save under given name. - -TEST_F(ProjectManagerDecoratorTest, untitledEmptySaveAs) -{ - const auto project_dir = createEmptyDir("Project_untitledEmptySaveAs"); - - ProjectManagerDecorator manager(projectContext(), userContext(project_dir, {})); - EXPECT_TRUE(manager.currentProjectDir().empty()); - - // saving new project to "project_dir" directory. - EXPECT_TRUE(manager.saveProjectAs()); - - // checking that current projectDir has pointing to the right place - EXPECT_EQ(manager.currentProjectDir(), project_dir); - - // project directory should contain a json file with the model - auto model_json = Utils::join(project_dir, samplemodel_name + ".json"); - EXPECT_TRUE(Utils::exists(model_json)); -} - -//! Starting from new document (without project dir defined). -//! Attempt to save under empty name, immitating the user canceled directory selection dialog. - -TEST_F(ProjectManagerDecoratorTest, untitledEmptySaveAsCancel) -{ - ProjectManagerDecorator manager(projectContext(), userContext({}, {})); // immitates canceling - EXPECT_TRUE(manager.currentProjectDir().empty()); - - // saving new project to "project_dir" directory. - EXPECT_FALSE(manager.saveProjectAs()); - EXPECT_TRUE(manager.currentProjectDir().empty()); -} - -//! Starting from new document (without project dir defined). -//! Attempt to save in the non-existing directory. - -TEST_F(ProjectManagerDecoratorTest, untitledEmptySaveAsWrongDir) -{ - ProjectManagerDecorator manager(projectContext(), userContext("non-existing", {})); - - // saving new project to "project_dir" directory. - EXPECT_FALSE(manager.saveProjectAs()); - EXPECT_TRUE(manager.currentProjectDir().empty()); -} - -//! Untitled, modified document. Attempt to open existing project will lead to -//! the dialog save/discard/cancel. As a result of whole exersize, existing project -//! should be opened, previous project saved. - -TEST_F(ProjectManagerDecoratorTest, untitledModifiedOpenExisting) -{ - const auto existing_project_dir = createEmptyDir("Project_untitledModifiedOpenExisting1"); - const auto unsaved_project_dir = createEmptyDir("Project_untitledModifiedOpenExisting2"); - - // create "existing project" - { - ProjectManagerDecorator manager(projectContext(), userContext(existing_project_dir, {})); - manager.saveProjectAs(); - } - - // preparing manager with untitled, unmodified project - auto open_dir = [&existing_project_dir]() -> std::string { return existing_project_dir; }; - auto create_dir = [&unsaved_project_dir]() -> std::string { return unsaved_project_dir; }; - auto result = SaveChangesAnswer::DISCARD; - auto ask_create = [&result]() { - result = SaveChangesAnswer::SAVE; - return SaveChangesAnswer::SAVE; - }; - auto user_context = userContext({}, {}); - user_context.m_create_dir_callback = create_dir; - user_context.m_select_dir_callback = open_dir; - user_context.m_answer_callback = ask_create; - ProjectManagerDecorator manager(projectContext(), user_context); - - // modifying untitled project - sample_model->insertItem<PropertyItem>(); - EXPECT_TRUE(manager.isModified()); - EXPECT_TRUE(manager.currentProjectDir().empty()); - - // attempt to open existing project - manager.openExistingProject(); - - // check if user was asked and his answer coincide with expectation - EXPECT_EQ(result, SaveChangesAnswer::SAVE); - - // check that previous project was saved - auto model_json = Utils::join(unsaved_project_dir, samplemodel_name + ".json"); - EXPECT_TRUE(Utils::exists(model_json)); - - // currently manager is pointing to existing project - EXPECT_FALSE(manager.isModified()); - EXPECT_EQ(manager.currentProjectDir(), existing_project_dir); -} diff --git a/mvvm/tests/testmodel/projectutils.test.cpp b/mvvm/tests/testmodel/projectutils.test.cpp deleted file mode 100644 index 217d23bb73811bb01d5ff168000985a7a24c95e6..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/projectutils.test.cpp +++ /dev/null @@ -1,97 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/projectutils.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "folderbasedtest.h" -#include "google_test.h" -#include "mvvm/interfaces/applicationmodelsinterface.h" -#include "mvvm/interfaces/projectinterface.h" -#include "mvvm/model/propertyitem.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/project/project_types.h" -#include "mvvm/project/projectutils.h" -#include "mvvm/utils/fileutils.h" -#include "test_utils.h" - -using namespace ModelView; - -//! Tests of ProjectUtils namespace functions. - -class ProjectUtilsTest : public FolderBasedTest { -public: - ProjectUtilsTest() - : FolderBasedTest("test_ProjectUtils") - , sample_model(std::make_unique<SessionModel>("SampleModel")) - { - } - - ~ProjectUtilsTest(); - - std::vector<SessionModel*> models() const { return {sample_model.get()}; }; - - ProjectContext createContext() - { - ProjectContext result; - result.m_models_callback = [this]() { return models(); }; - return result; - } - - std::unique_ptr<SessionModel> sample_model; -}; - -ProjectUtilsTest::~ProjectUtilsTest() = default; - -//! Testing helper structure. - -TEST_F(ProjectUtilsTest, SuggestFileName) -{ - SessionModel model("TestModel"); - EXPECT_EQ(std::string("testmodel.json"), GUI::Project::Utils::SuggestFileName(model)); -} - -TEST_F(ProjectUtilsTest, CreateUntitledProject) -{ - auto project = GUI::Project::Utils::CreateUntitledProject(createContext()); - EXPECT_TRUE(project->projectDir().empty()); -} - -TEST_F(ProjectUtilsTest, ProjectWindowTitle) -{ - auto project = GUI::Project::Utils::CreateUntitledProject(createContext()); - - // unmodified project without projectDir - EXPECT_EQ(GUI::Project::Utils::ProjectWindowTitle(*project), "Untitled"); - - sample_model->insertItem<PropertyItem>(); - EXPECT_EQ(GUI::Project::Utils::ProjectWindowTitle(*project), "*Untitled"); - - // saving in a project directory - project->save(testPath()); - EXPECT_EQ(GUI::Project::Utils::ProjectWindowTitle(*project), testDir()); - - // modifying - sample_model->insertItem<PropertyItem>(); - EXPECT_EQ(GUI::Project::Utils::ProjectWindowTitle(*project), "*" + testDir()); -} - -TEST_F(ProjectUtilsTest, IsPossibleProjectDir) -{ - auto project = GUI::Project::Utils::CreateUntitledProject(createContext()); - - // empty directory can't be a project directory - auto dirname = createEmptyDir("test_IsPossibleProjectDir"); - EXPECT_FALSE(GUI::Project::Utils::IsPossibleProjectDir(dirname)); - - project->save(dirname); - EXPECT_TRUE(GUI::Project::Utils::IsPossibleProjectDir(dirname)); -} diff --git a/mvvm/tests/testmodel/reallimits.test.cpp b/mvvm/tests/testmodel/reallimits.test.cpp deleted file mode 100644 index a3ca302b792e007e8cc75832cc262519ebacda44..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/reallimits.test.cpp +++ /dev/null @@ -1,242 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/reallimits.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/utils/reallimits.h" -#include <limits> - -using namespace ModelView; - -class RealLimitsTest : public ::testing::Test { -protected: - ~RealLimitsTest(); -}; - -RealLimitsTest::~RealLimitsTest() = default; - -TEST_F(RealLimitsTest, initialState) -{ - RealLimits limits; - - EXPECT_FALSE(limits.hasLowerLimit()); - EXPECT_FALSE(limits.hasUpperLimit()); - EXPECT_FALSE(limits.hasLowerAndUpperLimits()); - EXPECT_TRUE(limits.isInRange(-std::numeric_limits<double>::infinity())); - EXPECT_TRUE(limits.isInRange(0.0)); - EXPECT_TRUE(limits.isInRange(std::numeric_limits<double>::infinity())); - - EXPECT_FALSE(limits.isPositive()); - EXPECT_FALSE(limits.isNonnegative()); - EXPECT_FALSE(limits.isLowerLimited()); - EXPECT_FALSE(limits.isUpperLimited()); - EXPECT_FALSE(limits.isLimited()); -} - -TEST_F(RealLimitsTest, lowerLimited) -{ - // [5.0, inf[ - RealLimits limits = RealLimits::lowerLimited(5.0); - EXPECT_TRUE(limits.hasLowerLimit()); - EXPECT_FALSE(limits.hasUpperLimit()); - EXPECT_FALSE(limits.hasLowerAndUpperLimits()); - - EXPECT_EQ(limits.lowerLimit(), 5.0); - EXPECT_DOUBLE_EQ(limits.upperLimit(), std::numeric_limits<double>::max()); - - EXPECT_FALSE(limits.isPositive()); - EXPECT_FALSE(limits.isNonnegative()); - EXPECT_TRUE(limits.isLowerLimited()); - EXPECT_FALSE(limits.isUpperLimited()); - EXPECT_FALSE(limits.isLimited()); -} - -TEST_F(RealLimitsTest, upperLimited) -{ - // [-inf, 5.0[ - RealLimits limits = RealLimits::upperLimited(5.0); - EXPECT_FALSE(limits.hasLowerLimit()); - EXPECT_TRUE(limits.hasUpperLimit()); - EXPECT_FALSE(limits.hasLowerAndUpperLimits()); - - EXPECT_DOUBLE_EQ(limits.lowerLimit(), std::numeric_limits<double>::lowest()); - EXPECT_EQ(5.0, limits.upperLimit()); - - EXPECT_TRUE(limits.isInRange(-std::numeric_limits<double>::infinity())); - EXPECT_TRUE(limits.isInRange(-2.0)); - EXPECT_FALSE(limits.isInRange(5.0)); - EXPECT_FALSE(limits.isInRange(std::numeric_limits<double>::infinity())); - - EXPECT_FALSE(limits.isPositive()); - EXPECT_FALSE(limits.isNonnegative()); - EXPECT_FALSE(limits.isLowerLimited()); - EXPECT_TRUE(limits.isUpperLimited()); - EXPECT_FALSE(limits.isLimited()); -} - -TEST_F(RealLimitsTest, limited) -{ - // [-10.0, 2.0[ - RealLimits limits = RealLimits::limited(-10.0, 2.0); - EXPECT_TRUE(limits.hasLowerLimit()); - EXPECT_TRUE(limits.hasUpperLimit()); - EXPECT_TRUE(limits.hasLowerAndUpperLimits()); - - EXPECT_EQ(limits.lowerLimit(), -10.0); - EXPECT_EQ(limits.upperLimit(), 2.0); - - EXPECT_FALSE(limits.isInRange(-11.0)); - EXPECT_TRUE(limits.isInRange(-9.0)); - EXPECT_TRUE(limits.isInRange(0.0)); - EXPECT_TRUE(limits.isInRange(1.0)); - EXPECT_FALSE(limits.isInRange(2.0)); - EXPECT_FALSE(limits.isInRange(3.0)); - - EXPECT_FALSE(limits.isPositive()); - EXPECT_FALSE(limits.isNonnegative()); - EXPECT_FALSE(limits.isLowerLimited()); - EXPECT_FALSE(limits.isUpperLimited()); - EXPECT_TRUE(limits.isLimited()); -} - -TEST_F(RealLimitsTest, positive) -{ - // ]0.0, 2.0[ - RealLimits limits = RealLimits::positive(); - EXPECT_TRUE(limits.hasLowerLimit()); - EXPECT_FALSE(limits.hasUpperLimit()); - EXPECT_FALSE(limits.hasLowerAndUpperLimits()); - - EXPECT_EQ(limits.lowerLimit(), std::numeric_limits<double>::min()); - EXPECT_EQ(limits.upperLimit(), std::numeric_limits<double>::max()); - - EXPECT_FALSE(limits.isInRange(-11.0)); - EXPECT_FALSE(limits.isInRange(0.0)); - EXPECT_TRUE(limits.isInRange(std::numeric_limits<double>::min())); - EXPECT_TRUE(limits.isInRange(1.0)); - - EXPECT_TRUE(limits.isPositive()); - EXPECT_FALSE(limits.isNonnegative()); - EXPECT_FALSE(limits.isLowerLimited()); - EXPECT_FALSE(limits.isUpperLimited()); - EXPECT_FALSE(limits.isLimited()); -} - -TEST_F(RealLimitsTest, nonnegative) -{ - // [0.0, 2.0[ - RealLimits limits = RealLimits::nonnegative(); - EXPECT_TRUE(limits.hasLowerLimit()); - EXPECT_FALSE(limits.hasUpperLimit()); - EXPECT_FALSE(limits.hasLowerAndUpperLimits()); - - EXPECT_EQ(limits.lowerLimit(), 0.0); - EXPECT_EQ(limits.upperLimit(), std::numeric_limits<double>::max()); - - EXPECT_FALSE(limits.isInRange(-11.0)); - EXPECT_TRUE(limits.isInRange(0.0)); - EXPECT_TRUE(limits.isInRange(std::numeric_limits<double>::min())); - EXPECT_TRUE(limits.isInRange(1.0)); - - EXPECT_FALSE(limits.isPositive()); - EXPECT_TRUE(limits.isNonnegative()); - EXPECT_FALSE(limits.isLowerLimited()); - EXPECT_FALSE(limits.isUpperLimited()); - EXPECT_FALSE(limits.isLimited()); -} - -TEST_F(RealLimitsTest, limitless) -{ - RealLimits limits = RealLimits::limitless(); - - EXPECT_FALSE(limits.hasLowerLimit()); - EXPECT_FALSE(limits.hasUpperLimit()); - EXPECT_FALSE(limits.hasLowerAndUpperLimits()); - - EXPECT_EQ(limits.lowerLimit(), std::numeric_limits<double>::lowest()); - EXPECT_EQ(limits.upperLimit(), std::numeric_limits<double>::max()); - - EXPECT_TRUE(limits.isInRange(-std::numeric_limits<double>::infinity())); - EXPECT_TRUE(limits.isInRange(0.0)); - EXPECT_TRUE(limits.isInRange(std::numeric_limits<double>::infinity())); - - EXPECT_FALSE(limits.isPositive()); - EXPECT_FALSE(limits.isNonnegative()); - EXPECT_FALSE(limits.isLowerLimited()); - EXPECT_FALSE(limits.isUpperLimited()); - EXPECT_FALSE(limits.isLimited()); -} - -TEST_F(RealLimitsTest, comparisonOperators) -{ - RealLimits lim1 = RealLimits::limited(1.0, 2.0); - RealLimits lim2 = RealLimits::limited(1.0, 2.0); - EXPECT_TRUE(lim1 == lim2); - EXPECT_FALSE(lim1 != lim2); - - RealLimits lim3 = RealLimits::limitless(); - RealLimits lim4 = RealLimits::limitless(); - EXPECT_TRUE(lim3 == lim4); - EXPECT_FALSE(lim3 != lim4); - - RealLimits lim5 = RealLimits::lowerLimited(1.0); - RealLimits lim6 = RealLimits::lowerLimited(1.0); - EXPECT_TRUE(lim5 == lim6); - EXPECT_FALSE(lim5 != lim6); - - RealLimits lim7 = RealLimits::upperLimited(1.0); - RealLimits lim8 = RealLimits::upperLimited(1.0); - EXPECT_TRUE(lim7 == lim8); - EXPECT_FALSE(lim7 != lim8); - - EXPECT_TRUE(RealLimits::positive() == RealLimits::positive()); - EXPECT_TRUE(RealLimits::nonnegative() == RealLimits::nonnegative()); - - EXPECT_FALSE(RealLimits::positive() == RealLimits::nonnegative()); -} - -TEST_F(RealLimitsTest, copyConstructor) -{ - RealLimits lim1 = RealLimits::limited(1.0, 2.0); - RealLimits lim2 = lim1; - EXPECT_TRUE(lim1 == lim2); - EXPECT_FALSE(lim1 != lim2); - - RealLimits lim3(lim1); - EXPECT_TRUE(lim1 == lim3); - EXPECT_FALSE(lim1 != lim3); -} - -TEST_F(RealLimitsTest, toVariant) -{ - RealLimits limit = RealLimits::limited(1.0, 2.0); - QVariant variant = QVariant::fromValue(limit); - - EXPECT_EQ(variant.value<RealLimits>().isLimited(), limit.isLimited()); - EXPECT_EQ(variant.value<RealLimits>().lowerLimit(), limit.lowerLimit()); - EXPECT_EQ(variant.value<RealLimits>().upperLimit(), limit.upperLimit()); -} - -TEST_F(RealLimitsTest, variantEquality) -{ - if (ModelView::Comparators::registered()) { - QVariant var1a = QVariant::fromValue(RealLimits::limited(1.0, 2.0)); - QVariant var1b = QVariant::fromValue(RealLimits::limited(1.0, 2.0)); - QVariant var2 = QVariant::fromValue(RealLimits::lowerLimited(1.0)); - - EXPECT_TRUE(var1a == var1b); - EXPECT_FALSE(var1a == var2); - EXPECT_FALSE(var1a != var1b); - EXPECT_TRUE(var1a != var2); - } -} diff --git a/mvvm/tests/testmodel/removeitemcommand.test.cpp b/mvvm/tests/testmodel/removeitemcommand.test.cpp deleted file mode 100644 index 40ba412d7006b91380a17039ce4bb29988043b9b..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/removeitemcommand.test.cpp +++ /dev/null @@ -1,181 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/removeitemcommand.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/commands/removeitemcommand.h" -#include "mvvm/model/compounditem.h" -#include "mvvm/model/itemutils.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/model/taginfo.h" - -using namespace ModelView; - -class RemoveItemCommandTest : public ::testing::Test { -public: - ~RemoveItemCommandTest(); -}; - -RemoveItemCommandTest::~RemoveItemCommandTest() = default; - -TEST_F(RemoveItemCommandTest, removeAtCommand) -{ - SessionModel model; - auto item = model.insertItem<SessionItem>(model.rootItem()); - - auto item_identifier = item->identifier(); - - // command to insert parent in the model - auto command = std::make_unique<RemoveItemCommand>(model.rootItem(), TagRow{"", 0}); - command->execute(); // removal - - EXPECT_EQ(std::get<bool>(command->result()), true); - EXPECT_EQ(model.rootItem()->childrenCount(), 0); - EXPECT_FALSE(command->isObsolete()); - - // undo command - command->undo(); - EXPECT_FALSE(command->isObsolete()); - EXPECT_EQ(model.rootItem()->childrenCount(), 1); - auto restored = Utils::ChildAt(model.rootItem(), 0); - EXPECT_EQ(restored->identifier(), item_identifier); -} - -TEST_F(RemoveItemCommandTest, removeAtCommandChild) -{ - SessionModel model; - auto parent = model.insertItem<SessionItem>(model.rootItem()); - parent->registerTag(TagInfo::universalTag("tag1"), /*set_as_default*/ true); - - auto child1 = model.insertItem<SessionItem>(parent); - child1->setData(42.0); - model.insertItem<SessionItem>(parent); - - auto child1_identifier = child1->identifier(); - - // command to remove one child - auto command = std::make_unique<RemoveItemCommand>(parent, TagRow{"", 0}); - command->execute(); // removal - - // check that one child was removed - EXPECT_FALSE(command->isObsolete()); - EXPECT_EQ(std::get<bool>(command->result()), true); - EXPECT_EQ(parent->childrenCount(), 1); - - // undo command - command->undo(); - EXPECT_FALSE(command->isObsolete()); - EXPECT_EQ(parent->childrenCount(), 2); - auto restored = Utils::ChildAt(parent, 0); - EXPECT_EQ(restored->identifier(), child1_identifier); - - // checking the data of restored item - EXPECT_EQ(restored->data<double>(), 42.0); -} - -TEST_F(RemoveItemCommandTest, removeAtCommandParentWithChild) -{ - SessionModel model; - auto parent = model.insertItem<SessionItem>(model.rootItem()); - parent->registerTag(TagInfo::universalTag("tag1"), /*set_as_default*/ true); - - auto child1 = model.insertItem<SessionItem>(parent); - child1->setData(42.0); - - auto parent_identifier = parent->identifier(); - auto child1_identifier = child1->identifier(); - - // command to remove parent - auto command = std::make_unique<RemoveItemCommand>(model.rootItem(), TagRow{"", 0}); - command->execute(); // removal - EXPECT_FALSE(command->isObsolete()); - - // check that one child was removed - EXPECT_EQ(std::get<bool>(command->result()), true); - EXPECT_EQ(model.rootItem()->childrenCount(), 0); - - // undo command - command->undo(); - EXPECT_FALSE(command->isObsolete()); - EXPECT_EQ(model.rootItem()->childrenCount(), 1); - auto restored_parent = Utils::ChildAt(model.rootItem(), 0); - auto restored_child = Utils::ChildAt(restored_parent, 0); - - EXPECT_EQ(restored_parent->identifier(), parent_identifier); - EXPECT_EQ(restored_child->identifier(), child1_identifier); - - // checking the data of restored item - EXPECT_EQ(restored_child->data<double>(), 42.0); -} - -//! RemoveAtCommand in multitag context - -TEST_F(RemoveItemCommandTest, removeAtCommandMultitag) -{ - SessionModel model; - auto parent = model.insertItem<SessionItem>(model.rootItem()); - parent->registerTag(TagInfo::universalTag("tag1")); - parent->registerTag(TagInfo::universalTag("tag2")); - - auto child1 = model.insertItem<SessionItem>(parent, "tag1"); - child1->setData(41.0); - - auto child2 = model.insertItem<SessionItem>(parent, "tag1"); - child2->setData(42.0); - - auto child3 = model.insertItem<SessionItem>(parent, "tag2"); - child3->setData(43.0); - - auto parent_identifier = parent->identifier(); - auto child1_identifier = child1->identifier(); - auto child2_identifier = child2->identifier(); - auto child3_identifier = child3->identifier(); - - // command to remove parent - auto command = std::make_unique<RemoveItemCommand>(parent, TagRow{"tag1", 1}); - command->execute(); // removal - - // check that one child was removed - EXPECT_FALSE(command->isObsolete()); - EXPECT_EQ(std::get<bool>(command->result()), true); - EXPECT_EQ(parent->childrenCount(), 2); - - // undo command - command->undo(); - EXPECT_FALSE(command->isObsolete()); - EXPECT_EQ(parent->childrenCount(), 3); - auto restored_parent = Utils::ChildAt(model.rootItem(), 0); - auto restored_child2 = Utils::ChildAt(restored_parent, 1); - - EXPECT_EQ(restored_parent->identifier(), parent_identifier); - EXPECT_EQ(restored_child2->identifier(), child2_identifier); - - // checking the data of restored item - EXPECT_EQ(restored_child2->data<double>(), 42.0); -} - -//! Attempt to remove property item. - -TEST_F(RemoveItemCommandTest, attemptToRemoveItem) -{ - SessionModel model; - auto parent = model.insertItem<CompoundItem>(model.rootItem()); - parent->addProperty("thickness", 42.0); - - auto command = std::make_unique<RemoveItemCommand>(parent, TagRow{"thickness", 0}); - command->execute(); - - EXPECT_TRUE(command->isObsolete()); - EXPECT_EQ(std::get<bool>(command->result()), false); -} diff --git a/mvvm/tests/testmodel/sessionitem.test.cpp b/mvvm/tests/testmodel/sessionitem.test.cpp deleted file mode 100644 index 43b0100ef8257220dc2d0458b49b6e1dbe11f2df..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/sessionitem.test.cpp +++ /dev/null @@ -1,722 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/sessionitem.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/model/itempool.h" -#include "mvvm/model/itemutils.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/model/sessionitemdata.h" -#include "mvvm/model/sessionitemtags.h" -#include "mvvm/model/taginfo.h" -#include "mvvm/model/variant_constants.h" -#include "test_utils.h" -#include <memory> -#include <stdexcept> - -using namespace ModelView; - -class SessionItemTest : public ::testing::Test { -public: - ~SessionItemTest(); -}; - -SessionItemTest::~SessionItemTest() = default; - -TEST_F(SessionItemTest, initialState) -{ - SessionItem item; - const int role = ItemDataRole::DATA; - - EXPECT_EQ(item.model(), nullptr); - EXPECT_EQ(item.parent(), nullptr); - EXPECT_EQ(item.childrenCount(), 0); - EXPECT_FALSE(item.data<QVariant>(role).isValid()); - EXPECT_TRUE(item.children().empty()); - EXPECT_EQ(item.modelType(), GUI::Constants::BaseType); - EXPECT_EQ(item.displayName(), GUI::Constants::BaseType); - - // Initially item has already an identifier defined. - std::vector<int> expected_roles = {ItemDataRole::IDENTIFIER, ItemDataRole::DISPLAY}; - EXPECT_EQ(item.itemData()->roles(), expected_roles); - - // Identifier is not zero - EXPECT_FALSE(item.identifier().empty()); -} - -TEST_F(SessionItemTest, modelType) -{ - SessionItem item2("Layer"); - EXPECT_EQ(item2.modelType(), "Layer"); -} - -//! Validating ::setData and appearance of roles. - -TEST_F(SessionItemTest, setData) -{ - SessionItem item; - const int role = ItemDataRole::DATA; - - EXPECT_FALSE(item.data<QVariant>(role).isValid()); - - QVariant expected(42.0); - EXPECT_TRUE(item.setData(expected, role)); - - std::vector<int> expected_roles = {ItemDataRole::IDENTIFIER, ItemDataRole::DISPLAY, - ItemDataRole::DATA}; - EXPECT_EQ(item.itemData()->roles(), expected_roles); - EXPECT_EQ(item.data<QVariant>(role), expected); - - // setting another value - EXPECT_TRUE(item.setData(43.0, role)); - EXPECT_EQ(item.itemData()->roles(), expected_roles); - EXPECT_EQ(item.data<QVariant>(role), QVariant::fromValue(43.0)); - - // setting same value - EXPECT_FALSE(item.setData(43.0, role)); - EXPECT_EQ(item.itemData()->roles(), expected_roles); - EXPECT_EQ(item.data<QVariant>(role), QVariant::fromValue(43.0)); -} - -//! Validating ::setData in the context of implicit conversion. - -TEST_F(SessionItemTest, setDataAndImplicitConversion) -{ - { - SessionItem item; - const int role = ItemDataRole::DATA; - EXPECT_TRUE(item.setData(43.0, ItemDataRole::DATA)); - EXPECT_EQ(item.data<QVariant>(role).typeName(), GUI::Constants::double_type_name); - } - - { - SessionItem item; - const int role = ItemDataRole::DATA; - EXPECT_TRUE(item.setData(43, ItemDataRole::DATA)); - EXPECT_EQ(item.data<QVariant>(role).typeName(), GUI::Constants::int_type_name); - } -} - -TEST_F(SessionItemTest, hasData) -{ - SessionItem item; - - EXPECT_FALSE(item.hasData()); - EXPECT_TRUE(item.hasData(ItemDataRole::IDENTIFIER)); - EXPECT_FALSE(item.hasData(ItemDataRole::DATA)); - EXPECT_TRUE(item.hasData(ItemDataRole::DISPLAY)); - EXPECT_FALSE(item.hasData(ItemDataRole::APPEARANCE)); - EXPECT_FALSE(item.hasData(ItemDataRole::LIMITS)); - EXPECT_FALSE(item.hasData(ItemDataRole::TOOLTIP)); - EXPECT_FALSE(item.hasData(ItemDataRole::EDITORTYPE)); - - item.setData(42.0); - EXPECT_TRUE(item.hasData()); -} - -TEST_F(SessionItemTest, setDoubleData) -{ - SessionItem item; - const double expected = 42.0; - EXPECT_TRUE(item.setData(expected)); - EXPECT_EQ(item.data<double>(), expected); -} - -TEST_F(SessionItemTest, setIntData) -{ - SessionItem item; - const int expected = 42; - EXPECT_TRUE(item.setData(expected)); - EXPECT_EQ(item.data<int>(), expected); -} - -TEST_F(SessionItemTest, setBoolData) -{ - SessionItem item; - const bool expected_true = true; - EXPECT_TRUE(item.setData(expected_true)); - EXPECT_EQ(item.data<bool>(), expected_true); - const bool expected_false = false; - EXPECT_TRUE(item.setData(expected_false)); - EXPECT_EQ(item.data<bool>(), expected_false); -} - -TEST_F(SessionItemTest, setStringData) -{ - SessionItem item; - const std::string expected{"abc"}; - EXPECT_TRUE(item.setData(expected)); - EXPECT_EQ(item.data<std::string>(), expected); -} - -//! Display role. - -TEST_F(SessionItemTest, displayName) -{ - SessionItem item("Property"); - QVariant data(42.0); - EXPECT_TRUE(item.setData(data)); - - // default display name coincide with model type - EXPECT_EQ(item.displayName(), "Property"); - - // checking setter - item.setDisplayName("width"); - EXPECT_EQ(item.displayName(), "width"); - EXPECT_EQ(item.data<double>(), 42.0); -} - -//! Attempt to set the different Variant to already existing role. - -TEST_F(SessionItemTest, variantMismatch) -{ - SessionItem item; - const int role = ItemDataRole::DATA; - QVariant expected(42.0); - - // setting data for the first time - EXPECT_TRUE(item.setData(expected, role)); - - std::vector<int> expected_roles = {ItemDataRole::IDENTIFIER, ItemDataRole::DISPLAY, - ItemDataRole::DATA}; - EXPECT_EQ(item.itemData()->roles(), expected_roles); - EXPECT_EQ(item.data<QVariant>(role), expected); - - // attempt to rewrite variant with another type - EXPECT_THROW(item.setData(std::string("abc"), role), std::runtime_error); - - // removing value by passing invalid variant - EXPECT_NO_THROW(item.setData(QVariant(), role)); - EXPECT_EQ(item.itemData()->roles().size(), 2); -} - -//! Item registration in a pool. - -TEST_F(SessionItemTest, registerItem) -{ - auto item = std::make_unique<SessionItem>(); - auto item_id = item->identifier(); - EXPECT_EQ(item->itemData()->roles().size(), 2u); - - std::shared_ptr<ItemPool> pool; - - // creating pool - pool.reset(new ItemPool); - pool->register_item(item.get(), item_id); - // registration shouldn't change item identifier - EXPECT_EQ(item->identifier(), item_id); - - // registration key should coincide with item identifier - auto key = pool->key_for_item(item.get()); - std::vector<int> expected_roles = {ItemDataRole::IDENTIFIER, ItemDataRole::DISPLAY}; - EXPECT_EQ(item->itemData()->roles(), expected_roles); - EXPECT_EQ(item_id, key); -} - -//! Item registration in a pool. - -TEST_F(SessionItemTest, defaultTag) -{ - SessionItem item; - EXPECT_EQ(item.itemTags()->defaultTag(), ""); - EXPECT_FALSE(Utils::HasTag(item, "defaultTag")); -} - -//! Registering tags - -TEST_F(SessionItemTest, registerTag) -{ - SessionItem item; - item.registerTag(TagInfo::universalTag("tagname")); - EXPECT_TRUE(Utils::HasTag(item, "tagname")); - - // registering of tag with same name forbidden - EXPECT_THROW(item.registerTag(TagInfo::universalTag("tagname")), std::runtime_error); - - // registering empty tag is forbidden - EXPECT_THROW(item.registerTag(TagInfo::universalTag("")), std::runtime_error); -} - -//! Registering tag and setting it as default - -TEST_F(SessionItemTest, registerDefaultTag) -{ - SessionItem item; - item.registerTag(TagInfo::universalTag("tagname"), /*set_as_default*/ true); - EXPECT_EQ(item.itemTags()->defaultTag(), "tagname"); -} - -//! Simple child insert. - -TEST_F(SessionItemTest, insertItem) -{ - auto parent = std::make_unique<SessionItem>(); - parent->registerTag(TagInfo::universalTag("defaultTag"), /*set_as_default*/ true); - - std::unique_ptr<SessionItem> child(new SessionItem); - - // empty parent - EXPECT_EQ(parent->childrenCount(), 0); - EXPECT_EQ(Utils::IndexOfChild(parent.get(), nullptr), -1); - EXPECT_EQ(Utils::IndexOfChild(parent.get(), child.get()), -1); - EXPECT_EQ(parent->getItem("", 0), nullptr); - EXPECT_EQ(parent->getItem("", -1), nullptr); - EXPECT_EQ(parent->getItem("", 10), nullptr); - - // inserting child - auto p_child = child.release(); - parent->insertItem(p_child, {"", 0}); - EXPECT_EQ(parent->childrenCount(), 1); - EXPECT_EQ(Utils::IndexOfChild(parent.get(), p_child), 0); - EXPECT_EQ(parent->children()[0], p_child); - EXPECT_EQ(parent->getItem("", 0), p_child); - EXPECT_EQ(p_child->parent(), parent.get()); -} - -//! Simple children insert. - -TEST_F(SessionItemTest, insertChildren) -{ - auto parent = std::make_unique<SessionItem>(); - parent->registerTag(TagInfo::universalTag("defaultTag"), /*set_as_default*/ true); - - auto child1 = new SessionItem; - auto child2 = new SessionItem; - auto child3 = new SessionItem; - auto child4 = new SessionItem; - - // inserting two items - parent->insertItem(child1, TagRow::append()); - parent->insertItem(child2, TagRow::append()); - EXPECT_EQ(Utils::IndexOfChild(parent.get(), child1), 0); - EXPECT_EQ(Utils::IndexOfChild(parent.get(), child2), 1); - EXPECT_EQ(parent->getItem("", 0), child1); - EXPECT_EQ(parent->getItem("", 1), child2); - std::vector<SessionItem*> expected = {child1, child2}; - EXPECT_EQ(parent->children(), expected); - - // inserting third item between two others - parent->insertItem(child3, {"", 1}); - expected = {child1, child3, child2}; - EXPECT_EQ(parent->children(), expected); - EXPECT_EQ(Utils::IndexOfChild(parent.get(), child1), 0); - EXPECT_EQ(Utils::IndexOfChild(parent.get(), child2), 2); - EXPECT_EQ(Utils::IndexOfChild(parent.get(), child3), 1); - EXPECT_EQ(parent->getItem("", 0), child1); - EXPECT_EQ(parent->getItem("", 1), child3); - EXPECT_EQ(parent->getItem("", 2), child2); - EXPECT_EQ(parent->getItem("", 3), nullptr); - - // inserting forth item using index equal to number of items - parent->insertItem(child4, {"", parent->childrenCount()}); - - // checking parents - EXPECT_EQ(child1->parent(), parent.get()); - EXPECT_EQ(child2->parent(), parent.get()); - EXPECT_EQ(child3->parent(), parent.get()); - EXPECT_EQ(child4->parent(), parent.get()); - - // attempt to insert same item twice - EXPECT_THROW(parent->insertItem(child2, TagRow::append()), std::runtime_error); - - // attempt to insert item using out of scope index - auto child5 = std::make_unique<SessionItem>(); - EXPECT_FALSE(parent->insertItem(child5.get(), {"", parent->childrenCount() + 1})); -} - -//! Removing (taking) item from parent. - -TEST_F(SessionItemTest, takeItem) -{ - auto parent = std::make_unique<SessionItem>(); - parent->registerTag(TagInfo::universalTag("defaultTag"), /*set_as_default*/ true); - - auto child1 = new SessionItem; - auto child2 = new SessionItem; - auto child3 = new SessionItem; - - // inserting items - parent->insertItem(child1, TagRow::append()); - parent->insertItem(child2, TagRow::append()); - parent->insertItem(child3, TagRow::append()); - - EXPECT_EQ(parent->childrenCount(), 3); - - // taking non-existing rows - EXPECT_EQ(parent->takeItem({"", -1}), nullptr); - EXPECT_EQ(parent->takeItem({"", parent->childrenCount()}), nullptr); - - // taking first row - auto taken = parent->takeItem({"", 0}); - EXPECT_EQ(taken->parent(), nullptr); - std::vector<SessionItem*> expected = {child2, child3}; - EXPECT_EQ(parent->children(), expected); - - delete taken; -} - -//! Insert and take tagged items. - -TEST_F(SessionItemTest, singleTagAndItems) -{ - const std::string tag1 = "tag1"; - - // creating parent with one tag - auto parent = std::make_unique<SessionItem>(); - parent->registerTag(TagInfo::universalTag(tag1)); - EXPECT_TRUE(Utils::HasTag(*parent, tag1)); - - // inserting two children - auto child1 = new SessionItem; - auto child2 = new SessionItem; - parent->insertItem(child1, {tag1, -1}); - parent->insertItem(child2, {tag1, -1}); - - // testing result of insertion via non-tag interface - std::vector<SessionItem*> expected = {child1, child2}; - EXPECT_EQ(parent->children(), expected); - EXPECT_EQ(Utils::IndexOfChild(parent.get(), child1), 0); - EXPECT_EQ(Utils::IndexOfChild(parent.get(), child2), 1); - - // testing single item access via tag interface - EXPECT_EQ(parent->getItem(tag1), child1); - EXPECT_EQ(parent->getItem(tag1, 0), child1); - EXPECT_EQ(parent->getItem(tag1, 1), child2); - EXPECT_EQ(parent->getItem(tag1, 2), nullptr); // wrong row - - // access to multiple items via tags interface - EXPECT_EQ(parent->getItems(tag1), expected); - - // removing first item - delete parent->takeItem({tag1, 0}); - EXPECT_EQ(parent->getItems(tag1), std::vector<SessionItem*>() = {child2}); - // removing second item - delete parent->takeItem({tag1, 0}); - EXPECT_EQ(parent->getItems(tag1), std::vector<SessionItem*>() = {}); - - // removing from already empty container - EXPECT_EQ(parent->takeItem({tag1, 0}), nullptr); -} - -//! Insert and take tagged items when two tags are present. - -TEST_F(SessionItemTest, twoTagsAndItems) -{ - const std::string tag1 = "tag1"; - const std::string tag2 = "tag2"; - - // creating parent with one tag - auto parent = std::make_unique<SessionItem>(); - parent->registerTag(TagInfo::universalTag(tag1)); - parent->registerTag(TagInfo::universalTag(tag2)); - EXPECT_TRUE(Utils::HasTag(*parent, tag1)); - EXPECT_TRUE(Utils::HasTag(*parent, tag2)); - - // inserting two children - auto child_t1_a = new SessionItem; - auto child_t1_b = new SessionItem; - auto child_t2_a = new SessionItem; - auto child_t2_b = new SessionItem; - auto child_t2_c = new SessionItem; - parent->insertItem(child_t2_a, {tag2, -1}); - parent->insertItem(child_t2_c, {tag2, -1}); - - parent->insertItem(child_t1_a, {tag1, -1}); - parent->insertItem(child_t1_b, {tag1, -1}); - - parent->insertItem(child_t2_b, {tag2, 1}); // between child_t2_a and child_t2_c - - // testing item access via non-tag interface - std::vector<SessionItem*> expected = {child_t1_a, child_t1_b, child_t2_a, child_t2_b, - child_t2_c}; - EXPECT_EQ(parent->children(), expected); - EXPECT_EQ(Utils::IndexOfChild(parent.get(), child_t1_a), 0); - EXPECT_EQ(Utils::IndexOfChild(parent.get(), child_t2_c), 4); - - // testing single item access via tag interface - EXPECT_EQ(parent->getItem(tag1), child_t1_a); - EXPECT_EQ(parent->getItem(tag1, 0), child_t1_a); - EXPECT_EQ(parent->getItem(tag1, 1), child_t1_b); - EXPECT_EQ(parent->getItem(tag2, 0), child_t2_a); - EXPECT_EQ(parent->getItem(tag2, 1), child_t2_b); - EXPECT_EQ(parent->getItem(tag2, 2), child_t2_c); - EXPECT_EQ(parent->getItem(tag2, 3), nullptr); // no items with such row - - // access to multiple items via tags interface - expected = {child_t1_a, child_t1_b}; - EXPECT_EQ(parent->getItems(tag1), expected); - expected = {child_t2_a, child_t2_b, child_t2_c}; - EXPECT_EQ(parent->getItems(tag2), expected); - - // removing item from the middle of tag2 - delete parent->takeItem({tag2, 1}); - expected = {child_t1_a, child_t1_b}; - EXPECT_EQ(parent->getItems(tag1), expected); - expected = {child_t2_a, child_t2_c}; - EXPECT_EQ(parent->getItems(tag2), expected); -} - -//! Inserting and removing items when tag has limits. - -TEST_F(SessionItemTest, tagWithLimits) -{ - const std::string tag1 = "tag1"; - const int maxItems = 3; - auto parent = std::make_unique<SessionItem>(); - parent->registerTag(TagInfo(tag1, 0, maxItems, std::vector<std::string>() = {})); - - // placing maximu allowed number of items - std::vector<SessionItem*> expected; - for (int i = 0; i < maxItems; ++i) { - auto child = new SessionItem; - expected.push_back(child); - EXPECT_TRUE(parent->insertItem(child, {tag1, -1})); - } - EXPECT_EQ(parent->getItems(tag1), expected); - - // no room for extra item - auto extra = new SessionItem; - EXPECT_FALSE(parent->insertItem(extra, {tag1, -1})); - - // removing first element - delete parent->takeItem({tag1, 0}); - expected.erase(expected.begin()); - EXPECT_EQ(parent->getItems(tag1), expected); - - // adding extra item - parent->insertItem(extra, {tag1, -1}); - expected.push_back(extra); - EXPECT_EQ(parent->getItems(tag1), expected); -} - -//! Inserting and removing items when tag has limits. - -TEST_F(SessionItemTest, tagModelTypes) -{ - const std::string tag1 = "tag1"; - const std::string tag2 = "tag2"; - const std::string modelType1 = "ModelType1"; - const std::string modelType2 = "ModelType2"; - const std::string modelType3 = "ModelType3"; - const std::string modelType4 = "ModelType4"; - - auto parent = std::make_unique<SessionItem>(); - parent->registerTag( - TagInfo(tag1, 0, -1, std::vector<std::string>() = {modelType1, modelType2})); - parent->registerTag(TagInfo(tag2, 0, -1, std::vector<std::string>() = {modelType3})); - - auto item1 = new SessionItem(modelType1); - auto item2 = new SessionItem(modelType2); - auto item3 = new SessionItem(modelType3); - - // attempt to add item not intended for tag - EXPECT_FALSE(parent->insertItem(item1, {tag2, -1})); - EXPECT_FALSE(parent->insertItem(item3, {tag1, -1})); - - // normal insert to appropriate tag - parent->insertItem(item3, {tag2, -1}); - parent->insertItem(item1, {tag1, -1}); - parent->insertItem(item2, {tag1, -1}); - - std::vector<SessionItem*> expected = {item1, item2}; - EXPECT_EQ(parent->getItems(tag1), expected); - expected = {item3}; - EXPECT_EQ(parent->getItems(tag2), expected); -} - -//! Testing method ::tag. - -TEST_F(SessionItemTest, tag) -{ - const std::string tag1 = "tag1"; - const std::string tag2 = "tag2"; - - // creating parent with one tag - auto parent = std::make_unique<SessionItem>(); - parent->registerTag(TagInfo::universalTag(tag1)); - parent->registerTag(TagInfo::universalTag(tag2)); - - // inserting two children - auto child_t1_a = new SessionItem; - auto child_t1_b = new SessionItem; - auto child_t2_a = new SessionItem; - auto child_t2_b = new SessionItem; - auto child_t2_c = new SessionItem; - parent->insertItem(child_t2_a, {tag2, -1}); - parent->insertItem(child_t2_c, {tag2, -1}); - parent->insertItem(child_t1_a, {tag1, -1}); - parent->insertItem(child_t1_b, {tag1, -1}); - parent->insertItem(child_t2_b, {tag2, 1}); // between child_t2_a and child_t2_c - - EXPECT_EQ(child_t1_a->tagRow().tag, "tag1"); - EXPECT_EQ(child_t1_b->tagRow().tag, "tag1"); - EXPECT_EQ(child_t2_a->tagRow().tag, "tag2"); - EXPECT_EQ(child_t2_b->tagRow().tag, "tag2"); - EXPECT_EQ(child_t2_c->tagRow().tag, "tag2"); - - SessionItem parentless_item; - EXPECT_EQ(parentless_item.tagRow().tag, ""); -} - -//! Checks row of item in its tag - -TEST_F(SessionItemTest, tagRow) -{ - const std::string tag1 = "tag1"; - const std::string tag2 = "tag2"; - - // creating parent with one tag - auto parent = std::make_unique<SessionItem>(); - parent->registerTag(TagInfo::universalTag(tag1)); - parent->registerTag(TagInfo::universalTag(tag2)); - - // inserting two children - auto child_t1_a = new SessionItem; - auto child_t1_b = new SessionItem; - auto child_t2_a = new SessionItem; - auto child_t2_b = new SessionItem; - auto child_t2_c = new SessionItem; - parent->insertItem(child_t2_a, {tag2, -1}); // 0 - parent->insertItem(child_t2_c, {tag2, -1}); // 2 - parent->insertItem(child_t1_a, {tag1, -1}); // 0 - parent->insertItem(child_t1_b, {tag1, -1}); // 1 - parent->insertItem(child_t2_b, {tag2, 1}); // 1 between child_t2_a and child_t2_c - - EXPECT_EQ(child_t1_a->tagRow().row, 0); - EXPECT_EQ(child_t1_b->tagRow().row, 1); - EXPECT_EQ(child_t2_a->tagRow().row, 0); - EXPECT_EQ(child_t2_b->tagRow().row, 1); - EXPECT_EQ(child_t2_c->tagRow().row, 2); - - EXPECT_EQ(child_t1_a->tagRow().tag, "tag1"); - EXPECT_EQ(child_t1_b->tagRow().tag, "tag1"); - EXPECT_EQ(child_t2_a->tagRow().tag, "tag2"); - EXPECT_EQ(child_t2_b->tagRow().tag, "tag2"); - EXPECT_EQ(child_t2_c->tagRow().tag, "tag2"); -} - -//! Checks row of item in its tag - -TEST_F(SessionItemTest, tagRowOfItem) -{ - const std::string tag1 = "tag1"; - const std::string tag2 = "tag2"; - - // creating parent with one tag - auto parent = std::make_unique<SessionItem>(); - parent->registerTag(TagInfo::universalTag(tag1)); - parent->registerTag(TagInfo::universalTag(tag2)); - - // inserting two children - auto child_t1_a = new SessionItem; - auto child_t1_b = new SessionItem; - auto child_t2_a = new SessionItem; - auto child_t2_b = new SessionItem; - auto child_t2_c = new SessionItem; - parent->insertItem(child_t2_a, {tag2, -1}); // 0 - parent->insertItem(child_t2_c, {tag2, -1}); // 2 - parent->insertItem(child_t1_a, {tag1, -1}); // 0 - parent->insertItem(child_t1_b, {tag1, -1}); // 1 - parent->insertItem(child_t2_b, {tag2, 1}); // 1 between child_t2_a and child_t2_c - - EXPECT_EQ(parent->tagRowOfItem(child_t1_a).row, 0); - EXPECT_EQ(parent->tagRowOfItem(child_t1_b).row, 1); - EXPECT_EQ(parent->tagRowOfItem(child_t2_a).row, 0); - EXPECT_EQ(parent->tagRowOfItem(child_t2_b).row, 1); - EXPECT_EQ(parent->tagRowOfItem(child_t2_c).row, 2); - - EXPECT_EQ(parent->tagRowOfItem(child_t1_a).tag, "tag1"); - EXPECT_EQ(parent->tagRowOfItem(child_t1_b).tag, "tag1"); - EXPECT_EQ(parent->tagRowOfItem(child_t2_a).tag, "tag2"); - EXPECT_EQ(parent->tagRowOfItem(child_t2_b).tag, "tag2"); - EXPECT_EQ(parent->tagRowOfItem(child_t2_c).tag, "tag2"); -} - -//! Checks item appearance (enabled/disabled and editable/readonly). - -TEST_F(SessionItemTest, appearance) -{ - SessionItem item("Model"); - - // there shouldn't be any data - auto variant = item.data<QVariant>(ItemDataRole::APPEARANCE); - EXPECT_FALSE(variant.isValid()); - - // default status - EXPECT_TRUE(item.isEnabled()); - EXPECT_TRUE(item.isEditable()); - - // disabling item - item.setEnabled(false); - EXPECT_FALSE(item.isEnabled()); - EXPECT_TRUE(item.isEditable()); - - // data should be there now - variant = item.data<QVariant>(ItemDataRole::APPEARANCE); - EXPECT_TRUE(variant.isValid()); - - // making it readonly - item.setEditable(false); - EXPECT_FALSE(item.isEnabled()); - EXPECT_FALSE(item.isEditable()); -} - -//! Checks item tooltip. - -TEST_F(SessionItemTest, tooltip) -{ - SessionItem item("Model"); - - EXPECT_EQ(item.toolTip(), ""); - EXPECT_FALSE(item.hasData(ItemDataRole::TOOLTIP)); - - EXPECT_EQ(item.setToolTip("abc"), &item); - EXPECT_TRUE(item.hasData(ItemDataRole::TOOLTIP)); - EXPECT_EQ(item.toolTip(), "abc"); -} - -//! Checks item's editor type. - -TEST_F(SessionItemTest, editorType) -{ - SessionItem item("Model"); - - EXPECT_EQ(item.editorType(), ""); - EXPECT_FALSE(item.hasData(ItemDataRole::EDITORTYPE)); - - EXPECT_EQ(item.setEditorType("abc"), &item); - EXPECT_TRUE(item.hasData(ItemDataRole::EDITORTYPE)); - EXPECT_EQ(item.editorType(), "abc"); -} - -TEST_F(SessionItemTest, itemsInTag) -{ - const std::string tag1 = "tag1"; - const std::string tag2 = "tag2"; - - // creating parent with one tag - auto parent = std::make_unique<SessionItem>(); - parent->registerTag(TagInfo::universalTag(tag1)); - parent->registerTag(TagInfo::universalTag(tag2)); - - // inserting two children - auto child_t1_a = new SessionItem; - auto child_t2_a = new SessionItem; - auto child_t2_b = new SessionItem; - parent->insertItem(child_t1_a, {tag1, -1}); - parent->insertItem(child_t2_a, {tag2, -1}); - parent->insertItem(child_t2_b, {tag2, -1}); - - EXPECT_EQ(parent->itemCount(tag1), 1); - EXPECT_EQ(parent->itemCount(tag2), 2); -} diff --git a/mvvm/tests/testmodel/sessionitemcontainer.test.cpp b/mvvm/tests/testmodel/sessionitemcontainer.test.cpp deleted file mode 100644 index 6cc147b30ad18f3193f0ecbbe85837102250b5c3..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/sessionitemcontainer.test.cpp +++ /dev/null @@ -1,305 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/sessionitemcontainer.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/model/sessionitemcontainer.h" -#include "test_utils.h" - -using namespace ModelView; - -//! Tests for TestSessionItemContainer class. - -class SessionItemContainerTest : public ::testing::Test { -public: - ~SessionItemContainerTest(); -}; - -SessionItemContainerTest::~SessionItemContainerTest() = default; - -//! Initial state of emty SessionItemTag. - -TEST_F(SessionItemContainerTest, initialState) -{ - const std::string name("tag"); - SessionItemContainer tag(TagInfo::universalTag(name)); - - EXPECT_EQ(tag.itemCount(), 0); - EXPECT_TRUE(tag.empty()); - EXPECT_EQ(tag.name(), name); - EXPECT_EQ(tag.items(), std::vector<SessionItem*>()); -} - -//! Checking ::insertItem. - -TEST_F(SessionItemContainerTest, insertItem) -{ - const std::string tag_name("tag"); - SessionItemContainer tag(TagInfo::universalTag(tag_name)); - - // inserting non-existing item is not allowed - EXPECT_FALSE(tag.insertItem(nullptr, tag.itemCount())); - EXPECT_EQ(tag.itemCount(), 0); - - // insertion at the end - SessionItem* child1 = new SessionItem; - SessionItem* child2 = new SessionItem; - EXPECT_TRUE(tag.insertItem(child1, tag.itemCount())); - EXPECT_TRUE(tag.insertItem(child2, tag.itemCount())); - EXPECT_EQ(tag.itemCount(), 2); - EXPECT_FALSE(tag.empty()); - std::vector<SessionItem*> expected = {child1, child2}; - EXPECT_EQ(tag.items(), expected); - - // insertion at the beginning - SessionItem* child3 = new SessionItem; - EXPECT_TRUE(tag.insertItem(child3, 0)); - expected = {child3, child1, child2}; - EXPECT_EQ(tag.items(), expected); - - // insertion in between - SessionItem* child4 = new SessionItem; - EXPECT_TRUE(tag.insertItem(child4, 1)); - expected = {child3, child4, child1, child2}; - EXPECT_EQ(tag.items(), expected); - - // using index equal to number of items - SessionItem* child5 = new SessionItem; - EXPECT_TRUE(tag.insertItem(child5, tag.itemCount())); - expected = {child3, child4, child1, child2, child5}; - EXPECT_EQ(tag.items(), expected); - - // insertion with wrong index - SessionItem* child6 = new SessionItem; - EXPECT_FALSE(tag.insertItem(child6, 42)); - EXPECT_EQ(tag.items(), expected); - delete child6; -} - -//! Checking ::insertItem when item has specific model type. - -TEST_F(SessionItemContainerTest, insertItemModelType) -{ - const std::string tag_name("tag"); - const std::vector<std::string> model_types = {"model_a"}; - - SessionItemContainer tag(TagInfo::universalTag(tag_name, model_types)); - - // insertion of wrong model type is not allowed - SessionItem* child1 = new SessionItem("model_a"); - SessionItem* child2 = new SessionItem("model_b"); - EXPECT_TRUE(tag.insertItem(child1, tag.itemCount())); - EXPECT_FALSE(tag.insertItem(child2, tag.itemCount())); - delete child2; - - std::vector<SessionItem*> expected = {child1}; - EXPECT_EQ(tag.items(), expected); -} - -//! Checking ::insertItem when tag is related to property tag. - -TEST_F(SessionItemContainerTest, insertItemPropertyType) -{ - const std::string name("tag"); - const std::string property_type("Property"); - - SessionItemContainer tag(TagInfo::propertyTag(name, property_type)); - - // insertion of second property item is not allowed (because of reached maximum) - SessionItem* child1 = new SessionItem(property_type); - SessionItem* child2 = new SessionItem(property_type); - EXPECT_TRUE(tag.insertItem(child1, tag.itemCount())); - EXPECT_FALSE(tag.insertItem(child2, tag.itemCount())); - delete child2; - - // insertion of wrong model type is not allowed - SessionItem* child3 = new SessionItem("another_model"); - EXPECT_FALSE(tag.insertItem(child3, tag.itemCount())); - delete child3; - std::vector<SessionItem*> expected = {child1}; - EXPECT_EQ(tag.items(), expected); -} - -//! Checking ::indexOfItem. - -TEST_F(SessionItemContainerTest, indexOfItem) -{ - const std::string tag_name("tag"); - const std::string model_type("model_a"); - - SessionItemContainer tag(TagInfo::universalTag(tag_name)); - - // index of two items - SessionItem* child1 = new SessionItem(model_type); - SessionItem* child2 = new SessionItem(model_type); - EXPECT_TRUE(tag.insertItem(child1, tag.itemCount())); - EXPECT_EQ(tag.indexOfItem(child1), 0); - EXPECT_TRUE(tag.insertItem(child2, tag.itemCount())); - EXPECT_EQ(tag.indexOfItem(child1), 0); - EXPECT_EQ(tag.indexOfItem(child2), 1); - - // not existing items - EXPECT_EQ(tag.indexOfItem(nullptr), -1); - auto child3 = std::make_unique<SessionItem>(model_type); - EXPECT_EQ(tag.indexOfItem(child3.get()), -1); -} - -//! Checking ::itemAt. - -TEST_F(SessionItemContainerTest, itemAt) -{ - const std::string tag_name("tag"); - const std::string model_type("model_a"); - - SessionItemContainer tag(TagInfo::universalTag(tag_name)); - - // items at given indices - SessionItem* child1 = new SessionItem(model_type); - SessionItem* child2 = new SessionItem(model_type); - EXPECT_TRUE(tag.insertItem(child1, tag.itemCount())); - EXPECT_TRUE(tag.insertItem(child2, tag.itemCount())); - EXPECT_EQ(tag.itemAt(0), child1); - EXPECT_EQ(tag.itemAt(1), child2); - - // non-existing indices - EXPECT_EQ(tag.itemAt(2), nullptr); - EXPECT_EQ(tag.itemAt(3), nullptr); - EXPECT_EQ(tag.itemAt(-1), nullptr); -} - -//! Checking ::takeItem. - -TEST_F(SessionItemContainerTest, takeItem) -{ - const std::string tag_name("tag"); - const std::string model_type("model_a"); - - SessionItemContainer tag(TagInfo::universalTag(tag_name)); - - // taking non existing items - EXPECT_EQ(tag.takeItem(0), nullptr); - - // inserting items - SessionItem* child1 = new SessionItem(model_type); - SessionItem* child2 = new SessionItem(model_type); - SessionItem* child3 = new SessionItem(model_type); - EXPECT_TRUE(tag.insertItem(child1, tag.itemCount())); - EXPECT_TRUE(tag.insertItem(child2, tag.itemCount())); - EXPECT_TRUE(tag.insertItem(child3, tag.itemCount())); - - // taking item in between - auto taken2 = tag.takeItem(1); - EXPECT_EQ(child2, taken2); - delete taken2; - - // order of remaining children - std::vector<SessionItem*> expected = {child1, child3}; - EXPECT_EQ(tag.items(), expected); - - // taking non existing items - EXPECT_EQ(tag.takeItem(-1), nullptr); - EXPECT_EQ(tag.takeItem(tag.itemCount()), nullptr); -} - -//! Checking ::canTakeItem. - -TEST_F(SessionItemContainerTest, canTakeItem) -{ - const std::string tag_name("tag"); - const std::string model_type("model_a"); - - SessionItemContainer tag(TagInfo::universalTag(tag_name)); - - // taking non existing items - EXPECT_FALSE(tag.canTakeItem(0)); - - // inserting items - SessionItem* child1 = new SessionItem(model_type); - EXPECT_TRUE(tag.insertItem(child1, tag.itemCount())); - EXPECT_TRUE(tag.canTakeItem(0)); - - // taking non existing items - EXPECT_FALSE(tag.canTakeItem(-1)); - EXPECT_FALSE(tag.canTakeItem(tag.itemCount())); -} - -//! Checking ::canInsertItem. - -TEST_F(SessionItemContainerTest, canInsertItem) -{ - const std::string tag_name("tag"); - const std::string model_type("model_a"); - - SessionItemContainer tag(TagInfo::universalTag(tag_name)); - - // inserting non-existing item - EXPECT_FALSE(tag.canInsertItem(nullptr, 0)); - - // we should be allowed to insert valid child - auto child1 = std::make_unique<SessionItem>(model_type); - EXPECT_TRUE(tag.canInsertItem(child1.get(), 0)); - - // wrong index is not allowed for insertion - EXPECT_FALSE(tag.canInsertItem(child1.get(), 1)); - EXPECT_FALSE(tag.canInsertItem(child1.get(), -1)); - - // inserting child - EXPECT_TRUE(tag.insertItem(child1.release(), tag.itemCount())); - - // can we insert second child? - auto child2 = std::make_unique<SessionItem>(model_type); - EXPECT_TRUE(tag.canInsertItem(child2.get(), 0)); - EXPECT_TRUE(tag.canInsertItem(child2.get(), 1)); - EXPECT_FALSE(tag.canInsertItem(child2.get(), 2)); - EXPECT_FALSE(tag.canInsertItem(child2.get(), -1)); -} - -//! Checking ::canInsertItem. - -TEST_F(SessionItemContainerTest, canInsertItemForPropertyTag) -{ - const std::string name("tag"); - const std::string property_type("Property"); - - SessionItemContainer tag(TagInfo::propertyTag(name, property_type)); - - // we should be allowed to insert valid child - auto child1 = std::make_unique<SessionItem>(property_type); - EXPECT_TRUE(tag.canInsertItem(child1.get(), 0)); - - // inserting child - EXPECT_TRUE(tag.insertItem(child1.release(), tag.itemCount())); - - // second property shouldn't be posible to insert because of exceeded maximum - auto child2 = std::make_unique<SessionItem>(property_type); - EXPECT_FALSE(tag.canInsertItem(child2.get(), 0)); -} - -//! Checking ::takeItem when tag is related to property tag. - -TEST_F(SessionItemContainerTest, takeItemPropertyType) -{ - const std::string name("tag"); - const std::string property_type("Property"); - - SessionItemContainer tag(TagInfo::propertyTag(name, property_type)); - - // insertion of second property item is not allowed (because of reached maximum) - SessionItem* child1 = new SessionItem(property_type); - EXPECT_TRUE(tag.insertItem(child1, tag.itemCount())); - - // attempt to take property item - EXPECT_FALSE(tag.canTakeItem(0)); - EXPECT_EQ(tag.takeItem(0), nullptr); -} diff --git a/mvvm/tests/testmodel/sessionitemdata.test.cpp b/mvvm/tests/testmodel/sessionitemdata.test.cpp deleted file mode 100644 index cfaad9b95bcabb10f215b96b0f213f7294bae589..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/sessionitemdata.test.cpp +++ /dev/null @@ -1,171 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/sessionitemdata.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/model/comboproperty.h" -#include "mvvm/model/mvvm_types.h" -#include "mvvm/model/sessionitemdata.h" -#include <stdexcept> - -using namespace ModelView; - -//! Test of SessionItemData. - -class SessionItemDataTest : public ::testing::Test { -public: - ~SessionItemDataTest(); -}; - -SessionItemDataTest::~SessionItemDataTest() = default; - -//! Initial state of SessionItemData object. - -TEST_F(SessionItemDataTest, initialState) -{ - SessionItemData data; - EXPECT_TRUE(data.roles().empty()); - EXPECT_FALSE(data.data(Qt::DisplayRole).isValid()); -} - -//! Basic setData, data operations. - -TEST_F(SessionItemDataTest, setDataDouble) -{ - SessionItemData data; - - const int role(ItemDataRole::DATA); - const QVariant variant(42.0); - - // setting variant for role - EXPECT_TRUE(data.setData(variant, role)); - std::vector<int> expected{role}; - EXPECT_EQ(data.roles(), expected); - EXPECT_TRUE(data.data(role) == variant); - - // setting same data twice - EXPECT_FALSE(data.setData(variant, role)); - EXPECT_EQ(data.roles(), expected); - EXPECT_TRUE(data.data(role) == variant); - - // changing the data - EXPECT_TRUE(data.setData(QVariant(43.0), role)); - EXPECT_EQ(data.roles(), expected); - EXPECT_TRUE(data.data(role) == QVariant(43.0)); - - // setting invalid variant for the role will remove data - EXPECT_TRUE(data.setData(QVariant(), role)); - EXPECT_TRUE(data.roles().empty()); - EXPECT_FALSE(data.data(role).isValid()); -} - -//! Basic setData, data operations. - -TEST_F(SessionItemDataTest, setDataComboProperty) -{ - SessionItemData data; - ComboProperty c1 = ComboProperty::createFrom({"a1", "a2"}); - ComboProperty c2 = ComboProperty::createFrom({"a1", "a2"}); - c1.setValue("a1"); - c2.setValue("a2"); - - const int role(ItemDataRole::DATA); - - // setting variant for role - EXPECT_TRUE(data.setData(QVariant::fromValue(c1), role)); - EXPECT_EQ(data.data(role).value<ComboProperty>(), c1); - - // setting same data twice - EXPECT_FALSE(data.setData(QVariant::fromValue(c1), role)); - - // setting another data - EXPECT_TRUE(data.setData(QVariant::fromValue(c2), role)); - EXPECT_EQ(data.data(role).value<ComboProperty>(), c2); -} - -//! Using different roles. - -TEST_F(SessionItemDataTest, differentRoles) -{ - SessionItemData data; - - const int role1(1); - const int role2 = role1 + 1; - - EXPECT_TRUE(data.setData(QVariant::fromValue(42.0), role1)); - EXPECT_TRUE(data.setData(QVariant::fromValue(std::string("str")), role2)); - - std::vector<int> expected{role1, role2}; - EXPECT_EQ(data.roles(), expected); - - EXPECT_TRUE(data.data(role1) == QVariant(42.0)); - EXPECT_TRUE(data.data(role2) == QVariant::fromValue(std::string("str"))); - EXPECT_FALSE(data.data(role2) == QVariant(42.0)); - EXPECT_FALSE(data.data(role1) == QVariant::fromValue(std::string("str"))); -} - -//! Changing type of variant for role should not be allowed. - -TEST_F(SessionItemDataTest, changingRole) -{ - SessionItemData data; - - const int role(1); - const QVariant variant(42.0); - - // setting variant for role - EXPECT_TRUE(data.setData(variant, role)); - std::vector<int> expected{role}; - EXPECT_EQ(data.roles(), expected); - EXPECT_TRUE(data.data(role) == variant); - - QVariant s = QVariant::fromValue(std::string("str")); - EXPECT_THROW(data.setData(s, role), std::runtime_error); -} - -TEST_F(SessionItemDataTest, rangeLoop) -{ - SessionItemData data; - const std::vector<double> expected_values = {1.2, 1.3}; - const std::vector<int> expected_roles = {1, 2}; - - for (size_t i = 0; i < expected_values.size(); ++i) { - data.setData(QVariant::fromValue(expected_values[i]), expected_roles[i]); - } - - std::vector<double> values; - std::vector<int> roles; - - for (const auto& x : data) { - values.push_back(x.m_data.value<double>()); - roles.push_back(x.m_role); - } - - EXPECT_EQ(values, expected_values); - EXPECT_EQ(roles, expected_roles); -} - -TEST_F(SessionItemDataTest, hasRole) -{ - SessionItemData data; - EXPECT_FALSE(data.hasData(0)); - EXPECT_FALSE(data.hasData(1)); - - const int role = 99; - data.setData(QVariant::fromValue(42), role); - EXPECT_TRUE(data.hasData(role)); - EXPECT_FALSE(data.hasData(1)); - - data.setData(QVariant(), role); - EXPECT_FALSE(data.hasData(role)); -} diff --git a/mvvm/tests/testmodel/sessionitemtags.test.cpp b/mvvm/tests/testmodel/sessionitemtags.test.cpp deleted file mode 100644 index 1a794b313199567967ddb000d31ac79bdaef850b..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/sessionitemtags.test.cpp +++ /dev/null @@ -1,227 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/sessionitemtags.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/model/sessionitemtags.h" -#include "mvvm/model/taginfo.h" -#include "test_utils.h" -#include <stdexcept> - -using namespace ModelView; - -//! Tests for SessionItemTags class. - -class SessionItemTagsTest : public ::testing::Test { -public: - ~SessionItemTagsTest(); -}; - -SessionItemTagsTest::~SessionItemTagsTest() = default; - -//! Initial state of emty SessionItemTags. - -TEST_F(SessionItemTagsTest, initialState) -{ - const std::string name("tag"); - SessionItemTags tag; - EXPECT_EQ(tag.defaultTag(), ""); - - EXPECT_FALSE(tag.isTag("abc")); - - EXPECT_EQ(tag.tagsCount(), 0); -} - -//! Registering tags. - -TEST_F(SessionItemTagsTest, registerTag) -{ - const std::string name("tag"); - SessionItemTags tag; - - tag.registerTag(TagInfo::universalTag("abc")); - EXPECT_TRUE(tag.isTag("abc")); - EXPECT_EQ(tag.defaultTag(), ""); - EXPECT_EQ(tag.tagsCount(), 1); - - // registering default tag - tag.registerTag(TagInfo::universalTag("abc2"), /*set_as_default*/ true); - EXPECT_TRUE(tag.isTag("abc2")); - EXPECT_EQ(tag.defaultTag(), "abc2"); - - // registering tag with same name is not allowed - EXPECT_THROW(tag.registerTag(TagInfo::universalTag("abc")), std::runtime_error); -} - -//! Insert item. - -TEST_F(SessionItemTagsTest, insertItem) -{ - const std::string tag1 = "tag1"; - const std::string tag2 = "tag2"; - - SessionItemTags tag; - - // inserting items without tags defined - auto item = std::make_unique<SessionItem>(); - EXPECT_THROW(tag.insertItem(item.get(), TagRow::append()), std::runtime_error); - - // registering tags - tag.registerTag(TagInfo::universalTag(tag1)); - tag.registerTag(TagInfo::universalTag(tag2)); - - EXPECT_EQ(tag.tagsCount(), 2); - - // inserting items - auto child_t1_a = new SessionItem; - auto child_t1_b = new SessionItem; - auto child_t2_a = new SessionItem; - auto child_t2_b = new SessionItem; - auto child_t2_c = new SessionItem; - EXPECT_TRUE(tag.insertItem(child_t2_a, TagRow::append(tag2))); - EXPECT_TRUE(tag.insertItem(child_t2_c, TagRow::append(tag2))); - EXPECT_TRUE(tag.insertItem(child_t1_a, TagRow::append(tag1))); - EXPECT_TRUE(tag.insertItem(child_t1_b, TagRow::append(tag1))); - EXPECT_TRUE(tag.insertItem(child_t2_b, {tag2, 1})); // between child_t2_a and child_t2_c - - // checking item order in containers - std::vector<SessionItem*> expected = {child_t1_a, child_t1_b}; - EXPECT_EQ(tag.getItems(tag1), expected); - expected = {child_t2_a, child_t2_b, child_t2_c}; - EXPECT_EQ(tag.getItems(tag2), expected); - - // checking allitems order - expected = {child_t1_a, child_t1_b, child_t2_a, child_t2_b, child_t2_c}; - EXPECT_EQ(tag.allitems(), expected); -} - -//! Testing method tagRowOfItem. - -TEST_F(SessionItemTagsTest, tagRowOfItem) -{ - const std::string tag1 = "tag1"; - const std::string tag2 = "tag2"; - - // creating parent with one tag - SessionItemTags tag; - tag.registerTag(TagInfo::universalTag(tag1), /*set_as_default*/ true); - tag.registerTag(TagInfo::universalTag(tag2)); - - // inserting children - auto child_t1_a = new SessionItem; - auto child_t1_b = new SessionItem; - auto child_t2_a = new SessionItem; - tag.insertItem(child_t1_a, TagRow::append()); // 0 - tag.insertItem(child_t1_b, TagRow::append()); // 1 - tag.insertItem(child_t2_a, {tag2, 0}); // 0 - - // checking children tag and row - EXPECT_EQ(tag.tagRowOfItem(child_t1_a).tag, tag1); - EXPECT_EQ(tag.tagRowOfItem(child_t1_b).tag, tag1); - EXPECT_EQ(tag.tagRowOfItem(child_t2_a).tag, tag2); - EXPECT_EQ(tag.tagRowOfItem(child_t1_a).row, 0); - EXPECT_EQ(tag.tagRowOfItem(child_t1_b).row, 1); - EXPECT_EQ(tag.tagRowOfItem(child_t2_a).row, 0); - - // alien item has no tag and -1 row - auto alien = std::make_unique<SessionItem>(); - EXPECT_EQ(tag.tagRowOfItem(alien.get()).tag, ""); - EXPECT_EQ(tag.tagRowOfItem(alien.get()).row, -1); - - // the same for nullptr - EXPECT_EQ(tag.tagRowOfItem(nullptr).tag, ""); - EXPECT_EQ(tag.tagRowOfItem(nullptr).row, -1); -} - -//! Testing method getItem. - -TEST_F(SessionItemTagsTest, getItem) -{ - const std::string tag1 = "tag1"; - const std::string tag2 = "tag2"; - - // creating parent with one tag - SessionItemTags tag; - tag.registerTag(TagInfo::universalTag(tag1), /*set_as_default*/ true); - tag.registerTag(TagInfo::universalTag(tag2)); - - // inserting children - auto child_t1_a = new SessionItem; - auto child_t1_b = new SessionItem; - auto child_t2_a = new SessionItem; - tag.insertItem(child_t1_a, TagRow::append()); // 0 - tag.insertItem(child_t1_b, TagRow::append()); // 1 - tag.insertItem(child_t2_a, {tag2, 0}); // 0 - - EXPECT_EQ(tag.getItem({tag1, 0}), child_t1_a); - EXPECT_EQ(tag.getItem({tag1, 1}), child_t1_b); - EXPECT_EQ(tag.getItem({tag2, 0}), child_t2_a); - EXPECT_EQ(tag.getItem({tag2, 2}), nullptr); -} - -//! Testing method getItem. - -TEST_F(SessionItemTagsTest, takeItem) -{ - const std::string tag1 = "tag1"; - const std::string tag2 = "tag2"; - const std::string model_type("model"); - - SessionItemTags tag; - tag.registerTag(TagInfo::universalTag(tag1), /*set_as_default*/ true); - tag.registerTag(TagInfo::universalTag(tag2)); - - // taking non existing items - EXPECT_EQ(tag.takeItem({"", 0}), nullptr); - - // inserting items - auto child1 = new SessionItem(model_type); - auto child2 = new SessionItem(model_type); - auto child3 = new SessionItem(model_type); - auto child4 = new SessionItem(model_type); - EXPECT_TRUE(tag.insertItem(child1, TagRow::append())); - EXPECT_TRUE(tag.insertItem(child2, TagRow::append())); - EXPECT_TRUE(tag.insertItem(child3, TagRow::append())); - EXPECT_TRUE(tag.insertItem(child4, TagRow::append(tag2))); - - // taking item in between - EXPECT_TRUE(tag.canTakeItem({"", 1})); - auto taken2 = tag.takeItem({"", 1}); - EXPECT_EQ(child2, taken2); - delete taken2; - - // order of remaining children - std::vector<SessionItem*> expected = {child1, child3}; - EXPECT_EQ(tag.getItems(tag1), expected); - expected = {child4}; - EXPECT_EQ(tag.getItems(tag2), expected); - - // taking non existing items - EXPECT_FALSE(tag.canTakeItem({"", -1})); - EXPECT_EQ(tag.takeItem({"", -1}), nullptr); -} - -//! Testing isSinglePropertyTag. - -TEST_F(SessionItemTagsTest, isSinglePropertyTag) -{ - SessionItemTags tag; - tag.registerTag(TagInfo::universalTag("universal"), /*set_as_default*/ true); - EXPECT_FALSE(tag.isSinglePropertyTag("universal")); - - tag.registerTag(TagInfo::propertyTag("property_tag", "Vector")); - EXPECT_TRUE(tag.isSinglePropertyTag("property_tag")); - - EXPECT_FALSE(tag.isSinglePropertyTag("unexisting tag")); -} diff --git a/mvvm/tests/testmodel/sessionmodel.test.cpp b/mvvm/tests/testmodel/sessionmodel.test.cpp deleted file mode 100644 index 70038bd1a45be6eb896e88a4e32b476ec5fcfa28..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/sessionmodel.test.cpp +++ /dev/null @@ -1,467 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/sessionmodel.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/model/compounditem.h" -#include "mvvm/model/itempool.h" -#include "mvvm/model/itemutils.h" -#include "mvvm/model/propertyitem.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/model/taginfo.h" -#include <memory> -#include <stdexcept> - -using namespace ModelView; - -class SessionModelTest : public ::testing::Test { -public: - ~SessionModelTest(); - - class TestItem : public SessionItem { - public: - TestItem() : SessionItem("TestItemType"){}; - }; -}; - -SessionModelTest::~SessionModelTest() = default; - -TEST_F(SessionModelTest, initialState) -{ - SessionModel model; - EXPECT_EQ(model.rootItem()->model(), &model); - EXPECT_EQ(model.rootItem()->parent(), nullptr); -} - -TEST_F(SessionModelTest, insertItem) -{ - auto pool = std::make_shared<ItemPool>(); - SessionModel model("Test", pool); - - const model_type modelType = GUI::Constants::BaseType; - - // inserting single item - auto item = model.insertItem<SessionItem>(); - EXPECT_TRUE(item != nullptr); - EXPECT_EQ(item->parent(), model.rootItem()); - EXPECT_EQ(item->model(), &model); - EXPECT_EQ(item->modelType(), modelType); - - // checking registration - auto item_key = item->identifier(); - EXPECT_EQ(pool->item_for_key(item_key), item); - - // registering tag - item->registerTag(TagInfo::universalTag("defaultTag"), /*set_as_default*/ true); - - // adding child to it - auto child = model.insertItem<SessionItem>(item); - auto child_key = child->identifier(); - EXPECT_EQ(pool->item_for_key(child_key), child); - - EXPECT_TRUE(child != nullptr); - EXPECT_EQ(child->parent(), item); - EXPECT_EQ(child->model(), &model); - EXPECT_EQ(child->modelType(), modelType); - - // taking child back - auto taken = item->takeItem({"", 0}); - EXPECT_EQ(taken, child); - EXPECT_EQ(child->model(), nullptr); - - // childitem not registered anymore - EXPECT_EQ(pool->item_for_key(child_key), nullptr); - - delete taken; -} - -TEST_F(SessionModelTest, insertNewItem) -{ - auto pool = std::make_shared<ItemPool>(); - SessionModel model("Test", pool); - - const model_type modelType = GUI::Constants::BaseType; - - // inserting single item - auto item = model.insertNewItem(modelType); - EXPECT_TRUE(item != nullptr); - EXPECT_EQ(item->parent(), model.rootItem()); - EXPECT_EQ(item->model(), &model); - EXPECT_EQ(item->modelType(), modelType); - - // checking registration - auto item_key = item->identifier(); - EXPECT_EQ(pool->item_for_key(item_key), item); - - // registering tag - item->registerTag(TagInfo::universalTag("defaultTag"), /*set_as_default*/ true); - - // adding child to it - auto child = model.insertNewItem(modelType, item); - auto child_key = child->identifier(); - EXPECT_EQ(pool->item_for_key(child_key), child); - - EXPECT_TRUE(child != nullptr); - EXPECT_EQ(child->parent(), item); - EXPECT_EQ(child->model(), &model); - EXPECT_EQ(child->modelType(), modelType); - - // taking child back - auto taken = item->takeItem({"", 0}); - EXPECT_EQ(taken, child); - EXPECT_EQ(child->model(), nullptr); - - // childitem not registered anymore - EXPECT_EQ(pool->item_for_key(child_key), nullptr); - - delete taken; -} - -TEST_F(SessionModelTest, insertNewItemWithTag) -{ - const std::string tag1("tag1"); - SessionModel model; - auto parent = model.insertItem<SessionItem>(); - parent->registerTag(TagInfo::universalTag(tag1)); - auto child1 = model.insertItem<PropertyItem>(parent, {tag1, -1}); - - EXPECT_EQ(parent->tagRowOfItem(child1).tag, tag1); - EXPECT_EQ(Utils::IndexOfChild(parent, child1), 0); - - // adding second child - auto child2 = model.insertItem<PropertyItem>(parent, {tag1, 0}); - - EXPECT_EQ(parent->tagRowOfItem(child2).tag, tag1); - EXPECT_EQ(Utils::IndexOfChild(parent, child1), 1); - EXPECT_EQ(Utils::IndexOfChild(parent, child2), 0); -} - -TEST_F(SessionModelTest, setData) -{ - SessionModel model; - - // inserting single item - auto item = model.insertItem<SessionItem>(); - EXPECT_TRUE(model.data(item, ItemDataRole::DISPLAY).isValid()); - - // setting wrong type of data - QVariant value(42.0); - EXPECT_THROW(model.setData(item, value, ItemDataRole::DISPLAY), std::runtime_error); - - // setting new data - EXPECT_TRUE(model.setData(item, value, ItemDataRole::DATA)); - EXPECT_EQ(model.data(item, ItemDataRole::DATA), value); - - // setting same data twice should return false - EXPECT_FALSE(model.setData(item, value, ItemDataRole::DATA)); -} - -TEST_F(SessionModelTest, removeItem) -{ - auto pool = std::make_shared<ItemPool>(); - SessionModel model("Test", pool); - - auto parent = model.insertItem<SessionItem>(); - parent->registerTag(TagInfo::universalTag("defaultTag"), /*set_as_default*/ true); - - auto child1 = model.insertItem<SessionItem>(parent); - auto child2 = model.insertItem<SessionItem>(parent, {"", 0}); // before child1 - Q_UNUSED(child2) - - // removing child2 - model.removeItem(parent, {"", 0}); // removing child2 - EXPECT_EQ(parent->childrenCount(), 1); - EXPECT_EQ(Utils::ChildAt(parent, 0), child1); - - // child2 shouldn't be registered anymore - EXPECT_EQ(pool->key_for_item(child2), ""); -} - -TEST_F(SessionModelTest, removeNonExistingItem) -{ - auto pool = std::make_shared<ItemPool>(); - SessionModel model("Test", pool); - - auto parent = model.insertItem<SessionItem>(); - parent->registerTag(TagInfo::universalTag("defaultTag"), /*set_as_default*/ true); - - // removing non existing child - EXPECT_NO_THROW(model.removeItem(parent, {"", 0})); -} - -TEST_F(SessionModelTest, takeRowFromRootItem) -{ - auto pool = std::make_shared<ItemPool>(); - SessionModel model("Test", pool); - - auto parent = model.insertItem<SessionItem>(); - parent->registerTag(TagInfo::universalTag("defaultTag"), /*set_as_default*/ true); - auto parent_key = parent->identifier(); - - auto child = model.insertItem<SessionItem>(parent); - auto child_key = child->identifier(); - - EXPECT_EQ(pool->item_for_key(parent_key), parent); - EXPECT_EQ(pool->item_for_key(child_key), child); - - // taking parent - auto taken = model.rootItem()->takeItem({"", 0}); - EXPECT_EQ(pool->item_for_key(parent_key), nullptr); - EXPECT_EQ(pool->item_for_key(child_key), nullptr); - delete taken; -} - -TEST_F(SessionModelTest, moveItem) -{ - SessionModel model; - - // parent with child - auto parent0 = model.insertItem<SessionItem>(); - parent0->registerTag(TagInfo::universalTag("defaultTag"), /*set_as_default*/ true); - auto child0 = model.insertItem<PropertyItem>(parent0); - - // another parent with child - auto parent1 = model.insertItem<SessionItem>(); - parent1->registerTag(TagInfo::universalTag("defaultTag"), /*set_as_default*/ true); - auto child1 = model.insertItem<PropertyItem>(parent1); - - // moving child0 from parent0 to parent 1 - model.moveItem(child0, parent1, {"", 0}); - - std::vector<SessionItem*> expected = {child0, child1}; - EXPECT_EQ(parent1->children(), expected); - EXPECT_EQ(parent0->children().size(), 0); -} - -TEST_F(SessionModelTest, clearModel) -{ - auto pool = std::make_shared<ItemPool>(); - SessionModel model("test", pool); - - EXPECT_EQ(pool->size(), 1); - - auto first_root = model.rootItem(); - - EXPECT_EQ(model.rootItem()->childrenCount(), 0); - model.insertItem<SessionItem>(); - model.insertItem<SessionItem>(); - EXPECT_EQ(model.rootItem()->childrenCount(), 2); - - model.clear(); - EXPECT_EQ(model.rootItem()->childrenCount(), 0); - EXPECT_FALSE(model.rootItem() == first_root); - EXPECT_EQ(pool->key_for_item(first_root), ""); - EXPECT_EQ(pool->size(), 1); -} - -TEST_F(SessionModelTest, clearRebuildModel) -{ - auto pool = std::make_shared<ItemPool>(); - SessionModel model("test", pool); - - EXPECT_EQ(pool->size(), 1); - - auto first_root = model.rootItem(); - - EXPECT_EQ(model.rootItem()->childrenCount(), 0); - model.insertItem<SessionItem>(); - model.insertItem<SessionItem>(); - EXPECT_EQ(model.rootItem()->childrenCount(), 2); - - auto new_item = new SessionItem; - auto rebuild = [new_item](auto parent) { parent->insertItem(new_item, TagRow::append()); }; - - model.clear(rebuild); - EXPECT_EQ(model.rootItem()->childrenCount(), 1); - EXPECT_FALSE(model.rootItem() == first_root); - EXPECT_EQ(pool->key_for_item(first_root), ""); - EXPECT_EQ(pool->size(), 2); - EXPECT_EQ(pool->key_for_item(new_item), new_item->identifier()); -} - -//! Tests item copy when from root item to root item. - -TEST_F(SessionModelTest, copyModelItemRootContext) -{ - SessionModel model; - - // create single item with value - auto item = model.insertItem<SessionItem>(); - item->setData(42.0); - - // copying to root item - auto copy = model.copyItem(item, model.rootItem()); - - // checking copy - ASSERT_TRUE(copy != nullptr); - ASSERT_TRUE(copy != item); - EXPECT_FALSE(copy->identifier().empty()); - EXPECT_TRUE(copy->identifier() != item->identifier()); - EXPECT_EQ(copy->data<double>(), 42.0); - EXPECT_EQ(model.rootItem()->children().size(), 2); - EXPECT_TRUE(item != copy); - std::vector<SessionItem*> expected = {item, copy}; - EXPECT_EQ(model.rootItem()->children(), expected); -} - -//! Tests item copy from parent to root item. - -TEST_F(SessionModelTest, copyParentWithProperty) -{ - SessionModel model; - - // parent with single child and data on ite - auto parent0 = model.insertItem<SessionItem>(); - parent0->registerTag(TagInfo::universalTag("defaultTag"), /*set_as_default*/ true); - auto child0 = model.insertItem<SessionItem>(parent0); - child0->setData(42.0); - - // copying whole parent to root - auto copy = model.copyItem(parent0, model.rootItem()); - auto copy_child = copy->getItem("defaultTag"); - - ASSERT_TRUE(copy != nullptr); - ASSERT_TRUE(copy_child != nullptr); - EXPECT_FALSE(copy->identifier().empty()); - EXPECT_TRUE(copy->identifier() != parent0->identifier()); - EXPECT_EQ(copy_child->data<double>(), 42.0); -} - -//! Tests item copy for property item. - -TEST_F(SessionModelTest, copyFreeItem) -{ - SessionModel model; - - // single parent in a model - auto parent0 = model.insertItem<SessionItem>(); - parent0->registerTag(TagInfo::universalTag("defaultTag"), /*set_as_default*/ true); - - // free item - auto item = std::make_unique<PropertyItem>(); - item->setData(42.0); - - // copying to parent - auto copy = model.copyItem(item.get(), parent0); - EXPECT_EQ(copy->data<double>(), 42.0); -} - -//! Attempt to copy property item into the same tag. - -TEST_F(SessionModelTest, forbiddenCopy) -{ - SessionModel model; - - // single parent in a model - auto parent0 = model.insertItem<SessionItem>(); - parent0->registerTag(TagInfo::propertyTag("property", "Property")); - auto property = model.insertItem<PropertyItem>(parent0, "property"); - - // copying property to same property tag is not allowed - auto copy = model.copyItem(property, parent0, {"property", -1}); - EXPECT_EQ(parent0->childrenCount(), 1); - EXPECT_EQ(copy, nullptr); -} - -//! Test item find using identifier. - -TEST_F(SessionModelTest, findItem) -{ - SessionModel model; - auto parent = model.insertItem<SessionItem>(); - - // check that we can find item using its own identofoer - const identifier_type id = parent->identifier(); - EXPECT_EQ(model.findItem(id), parent); - - // check that we can't find deleted item. - model.removeItem(model.rootItem(), {"", 0}); - EXPECT_EQ(model.findItem(id), nullptr); -} - -//! Test items in different models. - -TEST_F(SessionModelTest, findItemInAlienModel) -{ - // two models with common pool - auto pool = std::make_shared<ItemPool>(); - SessionModel model1("Test1", pool); - SessionModel model2("Test2", pool); - - // inserting items in both models - auto parent1 = model1.insertItem<SessionItem>(); - auto parent2 = model2.insertItem<SessionItem>(); - const identifier_type id1 = parent1->identifier(); - const identifier_type id2 = parent2->identifier(); - - // checking that we can access items from both models - EXPECT_EQ(model1.findItem(id1), parent1); - EXPECT_EQ(model2.findItem(id1), parent1); - EXPECT_EQ(model1.findItem(id2), parent2); - EXPECT_EQ(model2.findItem(id2), parent2); - - // check that we can't find deleted item. - model1.removeItem(model1.rootItem(), {"", 0}); - EXPECT_EQ(model1.findItem(id1), nullptr); - EXPECT_EQ(model2.findItem(id1), nullptr); - EXPECT_EQ(model1.findItem(id2), parent2); - EXPECT_EQ(model2.findItem(id2), parent2); -} - -TEST_F(SessionModelTest, topItem) -{ - SessionModel model; - EXPECT_EQ(model.topItem<>(), nullptr); - EXPECT_EQ(model.topItem(), nullptr); - - auto property = model.insertItem<PropertyItem>(); - auto compound = model.insertItem<CompoundItem>(); - EXPECT_EQ(model.topItem<>(), property); - EXPECT_EQ(model.topItem(), property); - EXPECT_EQ(model.topItem<CompoundItem>(), compound); -} - -TEST_F(SessionModelTest, topItems) -{ - std::vector<SessionItem*> expected; - - SessionModel model; - EXPECT_EQ(model.topItems<>(), expected); - EXPECT_EQ(model.topItems(), expected); - - auto property1 = model.insertItem<PropertyItem>(); - auto compound1 = model.insertItem<CompoundItem>(); - auto property2 = model.insertItem<PropertyItem>(); - auto compound2 = model.insertItem<CompoundItem>(); - - expected = {property1, compound1, property2, compound2}; - EXPECT_EQ(model.topItems<>(), expected); - EXPECT_EQ(model.topItems(), expected); - - std::vector<CompoundItem*> expected2 = {compound1, compound2}; - EXPECT_EQ(model.topItems<CompoundItem>(), expected2); -} - -TEST_F(SessionModelTest, registerItem) -{ - const std::string expectedModelType("TestItemType"); - - SessionModel model; - model.registerItem<TestItem>(); - - auto item = model.insertNewItem(expectedModelType); - ASSERT_TRUE(item != nullptr); - ASSERT_TRUE(dynamic_cast<TestItem*>(item) != nullptr); - EXPECT_EQ(item->modelType(), expectedModelType); -} diff --git a/mvvm/tests/testmodel/setvaluecommand.test.cpp b/mvvm/tests/testmodel/setvaluecommand.test.cpp deleted file mode 100644 index c78ff2de826ab316970038d1007d78c8a50d6095..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/setvaluecommand.test.cpp +++ /dev/null @@ -1,80 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/setvaluecommand.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/commands/setvaluecommand.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/model/sessionmodel.h" -#include <stdexcept> - -using namespace ModelView; - -class SetValueCommandTest : public ::testing::Test { -public: - ~SetValueCommandTest(); -}; - -SetValueCommandTest::~SetValueCommandTest() = default; - -//! Set item value through SetValueCommand command. - -TEST_F(SetValueCommandTest, setValueCommand) -{ - SessionModel model; - const int role = ItemDataRole::DATA; - - // inserting single item - auto item = model.insertItem<SessionItem>(); - EXPECT_FALSE(model.data(item, role).isValid()); - - QVariant expected(42.0); - auto command = std::make_unique<SetValueCommand>(item, expected, role); - - // executing command - command->execute(); - EXPECT_TRUE(std::get<bool>(command->result())); // value was changed - EXPECT_EQ(command->isObsolete(), false); - EXPECT_EQ(model.data(item, role), expected); - - // undoing command - command->undo(); - EXPECT_TRUE(std::get<bool>(command->result())); // value was changed - EXPECT_FALSE(model.data(item, role).isValid()); - EXPECT_EQ(command->isObsolete(), false); -} - -//! Set same item value through SetValueCommand command. - -TEST_F(SetValueCommandTest, setSameValueCommand) -{ - SessionModel model; - const int role = ItemDataRole::DATA; - - // inserting single item - auto item = model.insertItem<SessionItem>(); - QVariant expected(42.0); - item->setData(expected, role); - - // command to set same value - auto command = std::make_unique<SetValueCommand>(item, expected, role); - - // executing command - command->execute(); - EXPECT_FALSE(std::get<bool>(command->result())); // value wasn't changed - EXPECT_EQ(model.data(item, role), expected); - EXPECT_EQ(command->isObsolete(), true); - - // undoing command which is in isObsolete state is not possible - EXPECT_THROW(command->undo(), std::runtime_error); -} diff --git a/mvvm/tests/testmodel/stringutils.test.cpp b/mvvm/tests/testmodel/stringutils.test.cpp deleted file mode 100644 index e45ab06702e78656c22428776ffdd896dd7c3a85..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/stringutils.test.cpp +++ /dev/null @@ -1,188 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/stringutils.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/utils/stringutils.h" -#include "test_utils.h" - -using namespace ModelView; -using namespace TestUtils; - -class StringUtilsTest : public ::testing::Test { -public: - ~StringUtilsTest(); -}; - -StringUtilsTest::~StringUtilsTest() = default; - -TEST_F(StringUtilsTest, ScientificDoubleToString) -{ - using Utils::ScientificDoubleToString; - const int precision = 6; - EXPECT_EQ(ScientificDoubleToString(0.0, precision), "0.0e+00"); - EXPECT_EQ(ScientificDoubleToString(1.0, precision), "1.0e+00"); - EXPECT_EQ(ScientificDoubleToString(3.0 / 4.0, precision), "7.5e-01"); - EXPECT_EQ(ScientificDoubleToString(4.0 / 3.0, precision), "1.333333e+00"); - EXPECT_EQ(ScientificDoubleToString(1000000., precision), "1.0e+06"); -} - -TEST_F(StringUtilsTest, DoubleToString) -{ - using Utils::DoubleToString; - const int precision = 4; - EXPECT_EQ(DoubleToString(0.0, precision), "0.0"); - EXPECT_EQ(DoubleToString(1.001, precision), "1.001"); - EXPECT_EQ(DoubleToString(1.0001, precision), "1.0"); -} - -//! Testing function TrimWhitespace - -TEST_F(StringUtilsTest, TrimWhiteSpace) -{ - using Utils::TrimWhitespace; - EXPECT_EQ(TrimWhitespace(""), ""); - EXPECT_EQ(TrimWhitespace(" "), ""); - EXPECT_EQ(TrimWhitespace("abc"), std::string("abc")); - EXPECT_EQ(TrimWhitespace(" \t\n abc cde\n"), std::string("abc cde")); -} - -TEST_F(StringUtilsTest, RemoveRepeatedSpaces) -{ - using Utils::RemoveRepeatedSpaces; - EXPECT_EQ(RemoveRepeatedSpaces(std::string{}), std::string{}); - EXPECT_EQ(RemoveRepeatedSpaces(" "), std::string{" "}); - EXPECT_EQ(RemoveRepeatedSpaces("a"), std::string{"a"}); - EXPECT_EQ(RemoveRepeatedSpaces(" a "), std::string{" a "}); - EXPECT_EQ(RemoveRepeatedSpaces(" a "), std::string{" a "}); - EXPECT_EQ(RemoveRepeatedSpaces("a bb ccc "), std::string{"a bb ccc "}); -} - -//! Testing function StringToDouble. - -TEST_F(StringUtilsTest, StringToDouble) -{ - using Utils::StringToDouble; - - // not a double - EXPECT_FALSE(StringToDouble("").has_value()); - EXPECT_FALSE(StringToDouble(" ").has_value()); - EXPECT_FALSE(StringToDouble("a").has_value()); - EXPECT_FALSE(StringToDouble("a b").has_value()); - - // not a double: some mixture present - EXPECT_FALSE(StringToDouble("42a").has_value()); - EXPECT_FALSE(StringToDouble("42.5.5").has_value()); - - // not a double: more than one double - EXPECT_FALSE(StringToDouble("42.5 52").has_value()); - - // valid double - EXPECT_TRUE(StringToDouble("42").has_value()); - EXPECT_TRUE(StringToDouble(" 42").has_value()); - EXPECT_TRUE(StringToDouble(" 42 ").has_value()); - EXPECT_DOUBLE_EQ(StringToDouble("42").value(), 42.0); - EXPECT_TRUE(StringToDouble("42.5").has_value()); - EXPECT_DOUBLE_EQ(StringToDouble("42.5").value(), 42.5); - EXPECT_TRUE(StringToDouble("-1.12e-06").has_value()); - EXPECT_DOUBLE_EQ(StringToDouble("-1.12e-06").value(), -1.12e-06); -} - -//! Testing function StringToDouble. - -TEST_F(StringUtilsTest, StringToInteger) -{ - using Utils::StringToInteger; - - // not an int - EXPECT_FALSE(StringToInteger("").has_value()); - EXPECT_FALSE(StringToInteger(" ").has_value()); - EXPECT_FALSE(StringToInteger("a").has_value()); - EXPECT_FALSE(StringToInteger("a b").has_value()); - - // not an int: some mixture present - EXPECT_FALSE(StringToInteger("42a").has_value()); - EXPECT_FALSE(StringToInteger("42.5").has_value()); - - // not an int: more than one number - EXPECT_FALSE(StringToInteger("42.5 52").has_value()); - - // valid int - EXPECT_TRUE(StringToInteger("42").has_value()); - EXPECT_TRUE(StringToInteger(" 42").has_value()); - EXPECT_TRUE(StringToInteger(" 42 ").has_value()); - EXPECT_EQ(StringToInteger("42").value(), 42); -} - -//! Testing SplitString method. -//! Carefully checking that it is reproduces Python behavior, as promised in comments to the method. - -TEST_F(StringUtilsTest, SplitString) -{ - using Utils::SplitString; - - EXPECT_THROW(SplitString("", ""), std::runtime_error); - EXPECT_EQ(SplitString("", " "), toVector<std::string>()); - EXPECT_EQ(SplitString("", ","), toVector<std::string>()); - EXPECT_EQ(SplitString(" ", " "), toVector<std::string>("", "")); - EXPECT_EQ(SplitString("a", " "), toVector<std::string>("a")); - EXPECT_EQ(SplitString("a ", " "), toVector<std::string>("a", "")); - - EXPECT_EQ(SplitString("a b", " "), toVector<std::string>("a", "b")); - EXPECT_EQ(SplitString("a b", " "), toVector<std::string>("a", "", "b")); - - EXPECT_EQ(SplitString("a", "-"), toVector<std::string>("a")); - - EXPECT_EQ(SplitString("aa", "a"), toVector<std::string>("", "", "")); - - EXPECT_EQ(SplitString("a,b", ","), toVector<std::string>("a", "b")); - EXPECT_EQ(SplitString("a, b", ","), toVector<std::string>("a", " b")); - - EXPECT_EQ(SplitString("a,b,", ","), toVector<std::string>("a", "b", "")); - EXPECT_EQ(SplitString(",a,b,", ","), toVector<std::string>("", "a", "b", "")); - EXPECT_EQ(SplitString("aabbcc", "bb"), toVector<std::string>("aa", "cc")); - EXPECT_EQ(SplitString("aabbcc", "bb"), toVector<std::string>("aa", "cc")); -} - -//! Testing ParseSpaceSeparatedDoubles. - -TEST_F(StringUtilsTest, ParseSpaceSeparatedDoubles) -{ - using Utils::ParseSpaceSeparatedDoubles; - std::vector<double> data; - - EXPECT_TRUE(ParseSpaceSeparatedDoubles("").empty()); - EXPECT_TRUE(ParseSpaceSeparatedDoubles(" ").empty()); - EXPECT_TRUE(ParseSpaceSeparatedDoubles("a").empty()); - EXPECT_TRUE(ParseSpaceSeparatedDoubles("a b").empty()); - - ASSERT_EQ(ParseSpaceSeparatedDoubles("4.02").size(), 1u); - EXPECT_DOUBLE_EQ(ParseSpaceSeparatedDoubles("42")[0], 42.0); - - // this tests failing under MacOS - // ASSERT_EQ(ParseSpaceSeparatedDoubles("42aaa").size(), 1u); - // EXPECT_DOUBLE_EQ(ParseSpaceSeparatedDoubles("42aaa")[0], 42.0); - - EXPECT_EQ(ParseSpaceSeparatedDoubles("42,").size(), 1u); - EXPECT_DOUBLE_EQ(ParseSpaceSeparatedDoubles("42,")[0], 42.0); - - EXPECT_EQ(ParseSpaceSeparatedDoubles("42,43").size(), 1u); - EXPECT_DOUBLE_EQ(ParseSpaceSeparatedDoubles("42,43")[0], 42.0); - - EXPECT_EQ(ParseSpaceSeparatedDoubles("42 ,43").size(), 1u); - EXPECT_DOUBLE_EQ(ParseSpaceSeparatedDoubles("42 ,43")[0], 42.0); - - EXPECT_EQ(ParseSpaceSeparatedDoubles("42 43").size(), 2u); - EXPECT_DOUBLE_EQ(ParseSpaceSeparatedDoubles("42 43")[0], 42.0); - EXPECT_DOUBLE_EQ(ParseSpaceSeparatedDoubles("42 43")[1], 43.0); -} diff --git a/mvvm/tests/testmodel/taginfo.test.cpp b/mvvm/tests/testmodel/taginfo.test.cpp deleted file mode 100644 index 5a530244f6a98bca581de9135b913cc6d9948784..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/taginfo.test.cpp +++ /dev/null @@ -1,95 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/taginfo.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/model/taginfo.h" - -using namespace ModelView; - -//! Tests of TagInfo class. - -class TagInfoTest : public ::testing::Test { -public: - ~TagInfoTest(); -}; - -TagInfoTest::~TagInfoTest() = default; - -TEST_F(TagInfoTest, initialState) -{ - TagInfo tag; - EXPECT_EQ(tag.name(), ""); - EXPECT_EQ(tag.min(), 0); - EXPECT_EQ(tag.max(), -1); - EXPECT_FALSE(tag.isSinglePropertyTag()); - EXPECT_TRUE(tag.isValidChild("")); - EXPECT_TRUE(tag.isValidChild("abc")); -} - -//! Testing default tag intended for storing unlimited amount of items of any type. - -TEST_F(TagInfoTest, defaultTag) -{ - // initial state - TagInfo tag = TagInfo::universalTag("name"); - EXPECT_EQ(tag.name(), std::string("name")); - EXPECT_EQ(tag.min(), 0); - EXPECT_EQ(tag.max(), -1); - EXPECT_FALSE(tag.isSinglePropertyTag()); - EXPECT_TRUE(tag.isValidChild("")); - EXPECT_TRUE(tag.isValidChild("abc")); -} - -//! Testing property tag intended for storing single PropertyItem. - -TEST_F(TagInfoTest, propertyTag) -{ - // initial state - TagInfo tag = TagInfo::propertyTag("name", "model_type"); - - EXPECT_EQ(tag.name(), std::string("name")); - EXPECT_EQ(tag.min(), 1); - EXPECT_EQ(tag.max(), 1); - EXPECT_TRUE(tag.isSinglePropertyTag()); - EXPECT_TRUE(tag.isValidChild("model_type")); - EXPECT_FALSE(tag.isValidChild("abc")); -} - -//! Testing equality operators. - -TEST_F(TagInfoTest, equalityOperator) -{ - // default constructor - TagInfo tag1, tag2; - EXPECT_TRUE(tag1 == tag2); - EXPECT_FALSE(tag1 != tag2); - - // same property tag - TagInfo tag3 = TagInfo::propertyTag("name", "model_type"); - TagInfo tag4 = TagInfo::propertyTag("name", "model_type"); - EXPECT_TRUE(tag3 == tag4); - EXPECT_FALSE(tag3 != tag4); - - // same universal tag - TagInfo tag5 = TagInfo::universalTag("name"); - TagInfo tag6 = TagInfo::universalTag("name"); - EXPECT_TRUE(tag5 == tag6); - EXPECT_FALSE(tag5 != tag6); - - // different tag - TagInfo tag7("tag7", 0, 1, std::vector<std::string>()); - TagInfo tag8("tag8", 0, 1, std::vector<std::string>()); - EXPECT_FALSE(tag7 == tag8); - EXPECT_TRUE(tag7 != tag8); -} diff --git a/mvvm/tests/testmodel/tagrow.test.cpp b/mvvm/tests/testmodel/tagrow.test.cpp deleted file mode 100644 index 3e9c9d33ed0a6dfe945965cc9f29b44c72d05890..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/tagrow.test.cpp +++ /dev/null @@ -1,141 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/tagrow.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/model/tagrow.h" - -using namespace ModelView; - -//! Testing AxisItems. - -class TagRowTest : public ::testing::Test { -public: - ~TagRowTest(); - - TagRow test_method(const TagRow& input) { return input; } -}; - -TagRowTest::~TagRowTest() = default; - -//! Initial state. - -TEST_F(TagRowTest, initialState) -{ - TagRow tagrow; - EXPECT_EQ(tagrow.tag, ""); - EXPECT_EQ(tagrow.row, -1); -} - -//! Brace initializer. - -TEST_F(TagRowTest, braceInitializer) -{ - TagRow tagrow{"abc", 42}; - EXPECT_EQ(tagrow.tag, "abc"); - EXPECT_EQ(tagrow.row, 42); - - tagrow = {}; - EXPECT_EQ(tagrow.tag, ""); - EXPECT_EQ(tagrow.row, -1); - - tagrow = {"cde", 43}; - EXPECT_EQ(tagrow.tag, "cde"); - EXPECT_EQ(tagrow.row, 43); - - TagRow tagrow2 = {"cde"}; - EXPECT_EQ(tagrow2.tag, "cde"); - EXPECT_EQ(tagrow2.row, -1); -} - -//! Equality operators. - -TEST_F(TagRowTest, equalityOperators) -{ - TagRow tag1; - TagRow tag2; - EXPECT_TRUE(tag1 == tag2); - EXPECT_FALSE(tag1 != tag2); - - TagRow tag3 = {"abc", 42}; - TagRow tag4 = {"abc", 42}; - EXPECT_TRUE(tag3 == tag4); - EXPECT_FALSE(tag3 != tag4); - - TagRow tag5 = {"abc", 42}; - TagRow tag6 = {"abc", 43}; - EXPECT_FALSE(tag5 == tag6); - EXPECT_TRUE(tag5 != tag6); - - TagRow tag7 = {"a", 42}; - TagRow tag8 = {"b", 42}; - EXPECT_FALSE(tag7 == tag8); - EXPECT_TRUE(tag7 != tag8); -} - -//! Assignment operators. - -TEST_F(TagRowTest, assignmentOperator) -{ - TagRow tag1; - TagRow tag2{"abc", 42}; - - tag1 = tag2; - EXPECT_EQ(tag1.row, 42); - EXPECT_EQ(tag1.tag, "abc"); -} - -//! Factory methods. - -TEST_F(TagRowTest, factoryMethods) -{ - auto tagrow = TagRow::append(); - EXPECT_EQ(tagrow.tag, ""); - EXPECT_EQ(tagrow.row, -1); - - const std::string expected_name("tag"); - tagrow = TagRow::append(expected_name); - EXPECT_EQ(tagrow.tag, expected_name); - EXPECT_EQ(tagrow.row, -1); - - tagrow = TagRow::prepend(expected_name); - EXPECT_EQ(tagrow.tag, expected_name); - EXPECT_EQ(tagrow.row, 0); -} - -//! Implicit type convertion - -TEST_F(TagRowTest, implicitConvertion) -{ - auto tagrow = test_method("abc"); - EXPECT_EQ(tagrow.tag, "abc"); - EXPECT_EQ(tagrow.row, -1); -} - -//! Find next tagrow. - -TEST_F(TagRowTest, next) -{ - TagRow tagrow{"tag", 0}; - EXPECT_EQ(tagrow.next().tag, "tag"); - EXPECT_EQ(tagrow.next().row, 1); -} - -//! Find previous tagrow. - -TEST_F(TagRowTest, prev) -{ - TagRow tagrow{"tag", 1}; - EXPECT_EQ(tagrow.prev().tag, "tag"); - EXPECT_EQ(tagrow.prev().row, 0); -} diff --git a/mvvm/tests/testmodel/test_utils.test.cpp b/mvvm/tests/testmodel/test_utils.test.cpp deleted file mode 100644 index e87874c32ac71c4692e63016e7a37b5fb67417c9..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/test_utils.test.cpp +++ /dev/null @@ -1,41 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/test_utils.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "test_utils.h" - -using TestUtils::toVector; - -//! Testing functions in test_utils. - -class TestUtilsTest : public ::testing::Test { -public: - ~TestUtilsTest(); -}; - -TestUtilsTest::~TestUtilsTest() = default; - -//! Testing toVector function. - -TEST_F(TestUtilsTest, toVector) -{ - std::vector<int> expected_int = {1, 2, 3}; - EXPECT_EQ(toVector<int>(1, 2, 3), expected_int); - - std::vector<double> expected_double = {1.1, 2.2, 3.3}; - EXPECT_EQ(toVector<double>(1.1, 2.2, 3.3), expected_double); - - std::vector<std::string> expected_string = {"a", "bb", "ccc"}; - EXPECT_EQ(toVector<std::string>("a", "bb", "ccc"), expected_string); -} diff --git a/mvvm/tests/testmodel/threadsafestack.test.cpp b/mvvm/tests/testmodel/threadsafestack.test.cpp deleted file mode 100644 index 79c014d771f0b3ae495b958af545d0884f8a663b..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/threadsafestack.test.cpp +++ /dev/null @@ -1,163 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/threadsafestack.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/utils/threadsafestack.h" -#include <future> - -using namespace ModelView; - -//! Testing AxisItems. - -class ThreadSafeStackTest : public ::testing::Test { -public: - ~ThreadSafeStackTest(); -}; - -ThreadSafeStackTest::~ThreadSafeStackTest() = default; - -//! Checking stack initial state (single thread mode). - -TEST_F(ThreadSafeStackTest, initialState) -{ - threadsafe_stack<int> stack; - EXPECT_TRUE(stack.empty()); - int value; - EXPECT_FALSE(stack.try_pop(value)); - - auto sh_value = stack.try_pop(); - EXPECT_FALSE(sh_value); -} - -//! Push and then pop (single thread mode). - -TEST_F(ThreadSafeStackTest, pushAndPop) -{ - threadsafe_stack<int> stack; - - stack.push(42); - EXPECT_FALSE(stack.empty()); - int value(0); - EXPECT_TRUE(stack.try_pop(value)); - EXPECT_EQ(value, 42); - - stack.push(43); - auto result = stack.wait_and_pop(); - EXPECT_EQ(*result.get(), 43); -} - -//! Update top value (single thread mode). - -TEST_F(ThreadSafeStackTest, updateTop) -{ - threadsafe_stack<int> stack; - - // update of empty stack means simple appearance of value - stack.update_top(42); - EXPECT_FALSE(stack.empty()); - int value(0); - EXPECT_TRUE(stack.try_pop(value)); - EXPECT_EQ(value, 42); - - // updating value - stack.push(43); - stack.update_top(44); - auto result = stack.wait_and_pop(); - EXPECT_EQ(*result.get(), 44); - - // shouldn't be more values - auto sh_value = stack.try_pop(); - EXPECT_FALSE(sh_value); -} - -//! Push and pop in concurrent mode. -//! Test is borrowed from Anthony Williams, C++ Concurrency in Action, Second edition. - -TEST_F(ThreadSafeStackTest, concurentPushAndPop) -{ - threadsafe_stack<int> stack; - std::promise<void> go, push_ready_for_test, pop_ready_for_test; - std::shared_future<void> ready(go.get_future()); - std::future<void> push_done; - std::future<std::shared_ptr<int>> pop_done; - - try { - // starting pushing thread - push_done = std::async(std::launch::async, [&stack, ready, &push_ready_for_test]() { - push_ready_for_test.set_value(); - ready.wait(); - stack.push(42); - }); - - // starting pop thread - pop_done = std::async(std::launch::async, [&stack, ready, &pop_ready_for_test]() { - pop_ready_for_test.set_value(); - ready.wait(); - return stack.wait_and_pop(); - }); - - // waiting for threads being prepared for racing - push_ready_for_test.get_future().wait(); - pop_ready_for_test.get_future().wait(); - - // starting concurrent push and pop - go.set_value(); - - // checking result - push_done.get(); // making sure pushing thread has finished - - EXPECT_EQ(*pop_done.get(), 42); - EXPECT_TRUE(stack.empty()); - - } catch (...) { - go.set_value(); - throw; - } -} - -//! Explicitly terminate waiting (concurrent mode). - -TEST_F(ThreadSafeStackTest, concurentStopWaiting) -{ - threadsafe_stack<int> stack; - std::promise<void> go, pop_ready_for_test; - std::shared_future<void> ready(go.get_future()); - std::future<std::shared_ptr<int>> pop_done; - - try { - // starting pop thread - pop_done = std::async(std::launch::async, [&stack, ready, &pop_ready_for_test]() { - pop_ready_for_test.set_value(); - ready.wait(); - return stack.wait_and_pop(); - }); - - // waiting for threads being prepared for racing - pop_ready_for_test.get_future().wait(); - - // starting waiting on empty stack - go.set_value(); - - // stopping waiting - stack.stop(); - - // stopping stack will raise exception - EXPECT_THROW(*pop_done.get(), empty_stack); - EXPECT_TRUE(stack.empty()); - - } catch (...) { - go.set_value(); - throw; - } -} diff --git a/mvvm/tests/testmodel/undostack.test.cpp b/mvvm/tests/testmodel/undostack.test.cpp deleted file mode 100644 index 6cee0b90856b333acea8a4e5664c80e3ad332345..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/undostack.test.cpp +++ /dev/null @@ -1,919 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/undostack.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/commands/commandadapter.h" -#include "mvvm/commands/setvaluecommand.h" -#include "mvvm/commands/undostack.h" -#include "mvvm/interfaces/undostackinterface.h" -#include "mvvm/model/itemutils.h" -#include "mvvm/model/propertyitem.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/model/taginfo.h" -#include "mvvm/standarditems/axisitems.h" -#include "mvvm/standarditems/data1ditem.h" -#include "mvvm/standarditems/graphitem.h" -#include "toyitems.h" -#include "toymodel.h" - -using namespace ModelView; - -class UndoStackTest : public ::testing::Test { -public: - ~UndoStackTest(); -}; - -UndoStackTest::~UndoStackTest() = default; - -//! Checking time of life of the command during undo/redo. -//! This is connected with the fact, that Qt takes ownership of the command and we have to use -//! our own wrapper. - -TEST_F(UndoStackTest, commandTimeOfLife) -{ - SessionModel model; - auto item = model.insertItem<PropertyItem>(); - item->setData(42); - - std::weak_ptr<SetValueCommand> pw_command; // to trace command time of life - - UndoStack stack; - - { - // creating command - auto command = - std::make_shared<SetValueCommand>(item, QVariant::fromValue(43), ItemDataRole::DATA); - pw_command = command; - EXPECT_EQ(pw_command.use_count(), 1); - - // checking state of item, stack and command - EXPECT_EQ(item->data<int>(), 42); - EXPECT_FALSE(stack.canRedo()); - EXPECT_FALSE(stack.canUndo()); - EXPECT_EQ(stack.index(), 0); - EXPECT_EQ(stack.count(), 0); - EXPECT_EQ(command->isObsolete(), false); - EXPECT_FALSE(std::get<bool>(command->result())); - - // adding command to the stack, it will lead to command execution - stack.execute(command); - EXPECT_EQ(pw_command.use_count(), 2); - - // checking state of item, stack and command - EXPECT_EQ(item->data<int>(), 43); - EXPECT_FALSE(stack.canRedo()); - EXPECT_TRUE(stack.canUndo()); - EXPECT_EQ(stack.index(), 1); - EXPECT_EQ(stack.count(), 1); - EXPECT_EQ(command->isObsolete(), false); - EXPECT_TRUE(std::get<bool>(command->result())); - - // undoing - stack.undo(); - EXPECT_EQ(item->data<int>(), 42); - EXPECT_TRUE(stack.canRedo()); - EXPECT_FALSE(stack.canUndo()); - EXPECT_EQ(stack.index(), 0); - EXPECT_EQ(stack.count(), 1); - EXPECT_EQ(command->isObsolete(), false); - EXPECT_TRUE(std::get<bool>(command->result())); - - // redoing - stack.redo(); - EXPECT_EQ(item->data<int>(), 43); - EXPECT_FALSE(stack.canRedo()); - EXPECT_TRUE(stack.canUndo()); - EXPECT_EQ(stack.index(), 1); - EXPECT_EQ(stack.count(), 1); - EXPECT_EQ(command->isObsolete(), false); - EXPECT_TRUE(std::get<bool>(command->result())); - } - - EXPECT_EQ(pw_command.use_count(), 1); - if (auto command = pw_command.lock()) { - EXPECT_EQ(command->isObsolete(), false); - EXPECT_TRUE(std::get<bool>(command->result())); - } -} - -//! Checking time of life of the command during undo/redo. -//! Same as above, but command is trying to set same value. It makes it "expired" and it should -//! be removed from the stack. - -TEST_F(UndoStackTest, expiredCommandTimeOfLife) -{ - SessionModel model; - auto item = model.insertItem<PropertyItem>(); - item->setData(42); - - std::weak_ptr<SetValueCommand> pw_command; // to trace command time of life - - UndoStack stack; - - { - // creating command which sets the same value - auto command = - std::make_shared<SetValueCommand>(item, QVariant::fromValue(42), ItemDataRole::DATA); - pw_command = command; - EXPECT_EQ(pw_command.use_count(), 1); - - // checking state of item, stack and command - EXPECT_EQ(item->data<int>(), 42); - EXPECT_FALSE(stack.canRedo()); - EXPECT_FALSE(stack.canUndo()); - EXPECT_EQ(stack.index(), 0); - EXPECT_EQ(stack.count(), 0); - EXPECT_EQ(command->isObsolete(), false); - EXPECT_FALSE(std::get<bool>(command->result())); - - // adding command to the stack, it will lead to command execution - stack.execute(command); - EXPECT_EQ(pw_command.use_count(), 1); // was already deleted from the stack - - // checking state of item, stack and command - EXPECT_EQ(item->data<int>(), 42); - EXPECT_FALSE(stack.canRedo()); - EXPECT_FALSE(stack.canUndo()); - EXPECT_EQ(stack.index(), 0); - EXPECT_EQ(stack.count(), 0); - EXPECT_EQ(command->isObsolete(), true); - EXPECT_FALSE(std::get<bool>(command->result())); - } - - EXPECT_EQ(pw_command.use_count(), 0); - EXPECT_EQ(pw_command.lock(), nullptr); -} - -TEST_F(UndoStackTest, initialState) -{ - SessionModel model; - - // no undo/redo stack by default - EXPECT_TRUE(model.undoStack() == nullptr); - - // switching undo/redo on - model.setUndoRedoEnabled(true); - auto stack = model.undoStack(); - EXPECT_TRUE(stack != nullptr); - - // initial state of undo redo stack - EXPECT_TRUE(stack->isActive()); - EXPECT_FALSE(stack->canRedo()); - EXPECT_FALSE(stack->canUndo()); - EXPECT_EQ(stack->index(), 0); -} - -TEST_F(UndoStackTest, insertNewItem) -{ - const model_type modelType(GUI::Constants::BaseType); - SessionModel model; - model.setUndoRedoEnabled(true); - auto stack = model.undoStack(); - - // inserting single item - auto item = model.insertItem<SessionItem>(); - EXPECT_TRUE(item != nullptr); - EXPECT_EQ(item->modelType(), GUI::Constants::BaseType); - EXPECT_EQ(model.rootItem()->childrenCount(), 1); - EXPECT_EQ(stack->index(), 1); - EXPECT_EQ(stack->count(), 1); - EXPECT_FALSE(stack->canRedo()); - EXPECT_TRUE(stack->canUndo()); - - // undoing item insertion - stack->undo(); - EXPECT_EQ(model.rootItem()->childrenCount(), 0); - EXPECT_EQ(stack->index(), 0); - EXPECT_EQ(stack->count(), 1); - EXPECT_TRUE(stack->canRedo()); - EXPECT_FALSE(stack->canUndo()); - - // redoing item insertion - stack->redo(); - EXPECT_EQ(model.rootItem()->childrenCount(), 1); - EXPECT_EQ(Utils::ChildAt(model.rootItem(), 0)->modelType(), modelType); - EXPECT_EQ(stack->index(), 1); - EXPECT_FALSE(stack->canRedo()); - EXPECT_TRUE(stack->canUndo()); - - // clearing stack - stack->clear(); - EXPECT_EQ(stack->index(), 0); - EXPECT_FALSE(stack->canRedo()); - EXPECT_FALSE(stack->canUndo()); - EXPECT_EQ(model.rootItem()->childrenCount(), 1); - EXPECT_EQ(Utils::ChildAt(model.rootItem(), 0)->modelType(), modelType); -} - -//! Insert property item, unto, redo, and checking that identifier is preserved. - -TEST_F(UndoStackTest, insertPropertyItemID) -{ - SessionModel model; - model.setUndoRedoEnabled(true); - auto stack = model.undoStack(); - - auto item = model.insertItem<PropertyItem>(); - auto original_id = item->identifier(); - - EXPECT_EQ(stack->index(), 1); - EXPECT_EQ(stack->count(), 1); - - model.undoStack()->undo(); - EXPECT_EQ(model.rootItem()->childrenCount(), 0); - - model.undoStack()->redo(); - EXPECT_EQ(model.rootItem()->childrenCount(), 1); - - auto restored_property_item = Utils::ChildAt(model.rootItem(), 0); - EXPECT_EQ(restored_property_item->modelType(), GUI::Constants::PropertyType); - EXPECT_EQ(restored_property_item->identifier(), original_id); -} - -//! Undo/redo scenario when few items inserted. - -TEST_F(UndoStackTest, insertParentAndChild) -{ - SessionModel model; - model.setUndoRedoEnabled(true); - auto stack = model.undoStack(); - - auto parent = model.insertItem<SessionItem>(); - parent->registerTag(TagInfo::universalTag("defaultTag"), /*set_as_default*/ true); - - model.insertItem<PropertyItem>(parent); - model.insertItem<PropertyItem>(parent); - - // state of the stack after insertion of 3 items - EXPECT_EQ(stack->count(), 3); - EXPECT_EQ(stack->index(), 3); - EXPECT_EQ(model.rootItem()->childrenCount(), 1); - EXPECT_EQ(parent->childrenCount(), 2); - - // undoing two last insertions - stack->undo(); - stack->undo(); - EXPECT_EQ(stack->count(), 3); - EXPECT_EQ(stack->index(), 1); - EXPECT_EQ(model.rootItem()->childrenCount(), 1); - EXPECT_EQ(parent->childrenCount(), 0); - - // redoing once - stack->redo(); - EXPECT_EQ(stack->count(), 3); - EXPECT_EQ(stack->index(), 2); - EXPECT_EQ(model.rootItem()->childrenCount(), 1); - EXPECT_EQ(parent->childrenCount(), 1); - EXPECT_EQ(Utils::ChildAt(parent, 0)->modelType(), GUI::Constants::PropertyType); -} - -//! Undo/redo scenario when item inserted and data set few times. - -TEST_F(UndoStackTest, setData) -{ - const int role = ItemDataRole::DATA; - SessionModel model; - model.setUndoRedoEnabled(true); - auto stack = model.undoStack(); - - // creating item - auto item = model.insertItem<SessionItem>(); - EXPECT_FALSE(model.data(item, role).isValid()); - - // setting new data - QVariant value(42.0); - model.setData(item, value, role); - EXPECT_EQ(model.data(item, role), value); - - EXPECT_EQ(stack->index(), 2); // insert and setData commands - EXPECT_FALSE(model.undoStack()->canRedo()); - EXPECT_TRUE(model.undoStack()->canUndo()); - - // undoing and checking - stack->undo(); - EXPECT_EQ(stack->index(), 1); - EXPECT_FALSE(model.data(item, role).isValid()); - - // setting data three times - model.setData(item, QVariant::fromValue(42.0), role); - model.setData(item, QVariant::fromValue(43.0), role); - model.setData(item, QVariant::fromValue(44.0), role); - EXPECT_EQ(stack->index(), 4); - EXPECT_EQ(model.data(item, role).value<double>(), 44.0); - stack->undo(); - stack->undo(); - EXPECT_EQ(model.data(item, role).value<double>(), 42.0); - stack->redo(); - stack->redo(); - EXPECT_EQ(model.data(item, role).value<double>(), 44.0); -} - -//! Undo/redo scenario when item data changed through item and not the model. - -TEST_F(UndoStackTest, setDataThroughItem) -{ - const int role = ItemDataRole::DATA; - const QVariant value(42.0); - - SessionModel model; - model.setUndoRedoEnabled(true); - auto stack = model.undoStack(); - - // creating item - auto item = model.insertItem<SessionItem>(); - EXPECT_FALSE(model.data(item, role).isValid()); - - // setting new data through item (and not through model) - item->setData(value, role); - EXPECT_EQ(item->data<QVariant>(role), value); - - EXPECT_EQ(stack->index(), 2); // insert and setData commands - EXPECT_FALSE(model.undoStack()->canRedo()); - EXPECT_TRUE(model.undoStack()->canUndo()); - - // undoing and checking - stack->undo(); - EXPECT_EQ(stack->index(), 1); - EXPECT_FALSE(model.data(item, role).isValid()); -} - -//! Undo/redo scenario when we set same data. Undo stack should be empty. - -TEST_F(UndoStackTest, setSameData) -{ - SessionModel model; - auto item = model.insertItem<PropertyItem>(); - item->setData(42.0); - - model.setUndoRedoEnabled(true); - auto stack = model.undoStack(); - EXPECT_EQ(stack->index(), 0); - EXPECT_FALSE(model.undoStack()->canRedo()); - EXPECT_FALSE(model.undoStack()->canUndo()); - - // setting same data should not lead to appearance of command in a stack - item->setData(42.0); - EXPECT_EQ(stack->index(), 0); - EXPECT_FALSE(model.undoStack()->canRedo()); - EXPECT_FALSE(model.undoStack()->canUndo()); -} - -//! Checks if we insert item, set data and undo everything we can get back to the data. - -TEST_F(UndoStackTest, insertAndSetData) -{ - const int role = ItemDataRole::DATA; - SessionModel model; - model.setUndoRedoEnabled(true); - auto stack = model.undoStack(); - - // creating item - auto item = model.insertItem<SessionItem>(); - EXPECT_FALSE(model.data(item, role).isValid()); - - // setting new data - QVariant value(42.0); - model.setData(item, value, role); - EXPECT_EQ(model.data(item, role), value); - - EXPECT_EQ(stack->index(), 2); // insert and setData commands - EXPECT_FALSE(model.undoStack()->canRedo()); - EXPECT_TRUE(model.undoStack()->canUndo()); - - // undoing twice and checking - stack->undo(); - stack->undo(); - EXPECT_EQ(stack->index(), 0); - EXPECT_EQ(model.rootItem()->childrenCount(), 0); - - // returning all back - stack->redo(); - stack->redo(); - EXPECT_EQ(stack->index(), 2); - EXPECT_EQ(model.rootItem()->childrenCount(), 1); - item = Utils::ChildAt(model.rootItem(), 0); - EXPECT_EQ(model.data(item, role).value<double>(), 42.0); -} - -//! Inserting item, setting the data, removing row, undoing, checking item and data. - -TEST_F(UndoStackTest, removeRow) -{ - const int role = ItemDataRole::DATA; - const QVariant data(42); - - SessionModel model; - model.setUndoRedoEnabled(true); - auto stack = model.undoStack(); - - auto item = model.insertItem<SessionItem>(); - item->setData(data, role); - - // initial state before removing the row - EXPECT_EQ(stack->count(), 2); // insert and setData commands - EXPECT_EQ(stack->index(), 2); // insert and setData commands - EXPECT_FALSE(model.undoStack()->canRedo()); - EXPECT_TRUE(model.undoStack()->canUndo()); - EXPECT_EQ(item->data<QVariant>(role), data); - EXPECT_EQ(model.rootItem()->childrenCount(), 1); - - // removing the row - model.removeItem(model.rootItem(), {"", 0}); - EXPECT_EQ(stack->count(), 3); - EXPECT_EQ(stack->index(), 3); - EXPECT_EQ(model.rootItem()->childrenCount(), 0); - - // undoing and checking the data - stack->undo(); - EXPECT_EQ(stack->count(), 3); - EXPECT_EQ(stack->index(), 2); - EXPECT_EQ(model.rootItem()->childrenCount(), 1); - item = Utils::ChildAt(model.rootItem(), 0); - EXPECT_EQ(model.data(item, role).value<double>(), 42.0); - EXPECT_EQ(item->modelType(), GUI::Constants::BaseType); -} - -//! Inserting parent and child, setting data to them, removing parent, undoing and checking. - -TEST_F(UndoStackTest, removeParentAndChild) -{ - const int role1(ItemDataRole::DATA), role2(ItemDataRole::DISPLAY); - const QVariant data1(42); - const QVariant data2 = QVariant::fromValue(std::string("abc")); - - SessionModel model; - model.setUndoRedoEnabled(true); - auto stack = model.undoStack(); - - auto parent = model.insertItem<SessionItem>(); - parent->registerTag(TagInfo::universalTag("defaultTag"), /*set_as_default*/ true); - - parent->setData(data1, role1); - auto child = model.insertItem<PropertyItem>(parent); - child->setData(data2, role2); - - EXPECT_EQ(stack->count(), 4); - EXPECT_EQ(stack->index(), 4); - - // removing parent - model.removeItem(model.rootItem(), {"", 0}); - EXPECT_EQ(stack->count(), 5); - EXPECT_EQ(stack->index(), 5); - EXPECT_EQ(model.rootItem()->childrenCount(), 0); - - // undoing - stack->undo(); - EXPECT_EQ(stack->count(), 5); - EXPECT_EQ(stack->index(), 4); - EXPECT_EQ(model.rootItem()->childrenCount(), 1); - auto parent_at = Utils::ChildAt(model.rootItem(), 0); - auto child_at = Utils::ChildAt(parent_at, 0); - - EXPECT_EQ(parent_at->modelType(), GUI::Constants::BaseType); - EXPECT_EQ(child_at->modelType(), GUI::Constants::PropertyType); - - EXPECT_EQ(parent_at->data<QVariant>(role1), data1); - EXPECT_EQ(child_at->data<QVariant>(role2), data2); -} - -//! Insert item, remove row, undo and check item id. - -TEST_F(UndoStackTest, itemIdentifierOnRemove) -{ - SessionModel model; - model.setUndoRedoEnabled(true); - auto stack = model.undoStack(); - - auto parent = model.insertItem<SessionItem>(); - parent->registerTag(TagInfo::universalTag("defaultTag"), /*set_as_default*/ true); - - identifier_type parent_id = parent->identifier(); - auto child = model.insertItem<PropertyItem>(parent); - identifier_type child_id = child->identifier(); - - // removing parent - model.removeItem(model.rootItem(), {"", 0}); - EXPECT_EQ(stack->count(), 3); - EXPECT_EQ(stack->index(), 3); - EXPECT_EQ(model.rootItem()->childrenCount(), 0); - - stack->undo(); - auto parent_at = Utils::ChildAt(model.rootItem(), 0); - auto child_at = Utils::ChildAt(parent_at, 0); - identifier_type parent_id2 = parent_at->identifier(); - identifier_type child_id2 = child_at->identifier(); - - EXPECT_EQ(parent_id, parent_id2); - EXPECT_EQ(child_id, child_id2); -} - -//! Create multilayer, add two layers, remove everything and undo. -//! Toy models are used here. - -TEST_F(UndoStackTest, multiLayer) -{ - auto pool = std::make_shared<ItemPool>(); - - ToyItems::SampleModel model(pool); - model.setUndoRedoEnabled(true); - auto stack = model.undoStack(); - - // creating multi layer - auto parent = model.insertItem<ToyItems::MultiLayerItem>(); - EXPECT_TRUE(dynamic_cast<ToyItems::MultiLayerItem*>(parent) != nullptr); - EXPECT_EQ(parent->modelType(), ToyItems::GUI::Constants::MultiLayerItemType); - - // inserting two layers - auto layer0 = model.insertItem<ToyItems::LayerItem>(parent); - auto layer1 = model.insertItem<ToyItems::LayerItem>(parent); - - // saving identifiers for further reference - identifier_type id_parent = parent->identifier(); - identifier_type id_layer0 = layer0->identifier(); - identifier_type id_layer1 = layer1->identifier(); - - // checking status of unddo stack - EXPECT_EQ(stack->count(), 3); - EXPECT_EQ(stack->index(), 3); - - // removing multi layer completely - model.removeItem(model.rootItem(), {"", 0}); - EXPECT_EQ(stack->count(), 4); - EXPECT_EQ(stack->index(), 4); - EXPECT_EQ(model.rootItem()->childrenCount(), 0); - - // multilayer and its two layers should gone from registration - EXPECT_TRUE(pool->item_for_key(id_parent) == nullptr); - EXPECT_TRUE(pool->item_for_key(id_layer0) == nullptr); - EXPECT_TRUE(pool->item_for_key(id_layer1) == nullptr); - - // undoing multilayer removal - stack->undo(); - EXPECT_EQ(stack->count(), 4); - EXPECT_EQ(stack->index(), 3); - - // restoring pointers back - auto parent_at = Utils::ChildAt(model.rootItem(), 0); - auto layer0_at = Utils::ChildAt(parent_at, 0); - auto layer1_at = Utils::ChildAt(parent_at, 1); - - // checking that restored item has corrrect identifiers - EXPECT_EQ(parent_at->identifier(), id_parent); - EXPECT_EQ(layer0_at->identifier(), id_layer0); - EXPECT_EQ(layer1_at->identifier(), id_layer1); - - // checking tag - EXPECT_EQ(layer0_at->tagRow().tag, ToyItems::MultiLayerItem::T_LAYERS); - EXPECT_EQ(layer1_at->tagRow().tag, ToyItems::MultiLayerItem::T_LAYERS); - std::vector<SessionItem*> expected = {layer0_at, layer1_at}; - EXPECT_EQ(parent_at->getItems(ToyItems::MultiLayerItem::T_LAYERS), expected); -} - -//! Move single layer from multilayer to another empty multilayer. - -TEST_F(UndoStackTest, moveLayerFromMultiLayer) -{ - auto pool = std::make_shared<ItemPool>(); - - ToyItems::SampleModel model(pool); - model.setUndoRedoEnabled(true); - auto stack = model.undoStack(); - - // creating multi layer with 3 layers - auto multilayer0 = model.insertItem<ToyItems::MultiLayerItem>(); - auto layer0 = model.insertItem<ToyItems::LayerItem>(multilayer0); - auto multilayer1 = model.insertItem<ToyItems::MultiLayerItem>(); - - // saving identifiers for further reference - identifier_type id_multilayer0 = multilayer0->identifier(); - identifier_type id_layer0 = layer0->identifier(); - identifier_type id_multilayer1 = multilayer1->identifier(); - - // moving layer from multilayer - model.moveItem(layer0, multilayer1, {"", 0}); - - // checking results - std::vector<SessionItem*> expected = {layer0}; - EXPECT_EQ(multilayer0->children().size(), 0); - EXPECT_EQ(multilayer1->children(), expected); - EXPECT_EQ(pool->item_for_key(id_layer0), layer0); - - // undoing - stack->undo(); - EXPECT_EQ(multilayer0->children(), expected); - EXPECT_EQ(multilayer1->children().size(), 0); - EXPECT_EQ(pool->item_for_key(id_layer0), layer0); -} - -//! Move single layer from multilayer to another empty multilayer. -//! Delete second multilayer and undo. - -TEST_F(UndoStackTest, moveLayerFromMLDeleteSecond) -{ - auto pool = std::make_shared<ItemPool>(); - - ToyItems::SampleModel model(pool); - model.setUndoRedoEnabled(true); - auto stack = model.undoStack(); - - // creating multi layer with 3 layers - auto multilayer0 = model.insertItem<ToyItems::MultiLayerItem>(); - auto layer0 = model.insertItem<ToyItems::LayerItem>(multilayer0); - auto multilayer1 = model.insertItem<ToyItems::MultiLayerItem>(); - - // saving identifiers for further reference - identifier_type id_multilayer0 = multilayer0->identifier(); - identifier_type id_layer0 = layer0->identifier(); - identifier_type id_multilayer1 = multilayer1->identifier(); - - // moving layer from multilayer - model.moveItem(layer0, multilayer1, {"", 0}); - - // checking results - std::vector<SessionItem*> expected = {layer0}; - EXPECT_EQ(multilayer0->children().size(), 0); - EXPECT_EQ(multilayer1->children(), expected); - EXPECT_EQ(pool->item_for_key(id_layer0), layer0); - - // deleting second multilayer - model.removeItem(model.rootItem(), {"", 1}); - - // undoing deletion - stack->undo(); - - // restoring ponters - auto layer0_at = pool->item_for_key(id_layer0); - auto multilayer1_at = pool->item_for_key(id_multilayer1); - - expected = {layer0_at}; - EXPECT_EQ(multilayer0->children().size(), 0); - EXPECT_EQ(multilayer1_at->children(), expected); - - // unoing move - stack->undo(); - - EXPECT_EQ(multilayer0->children(), expected); - EXPECT_EQ(multilayer1_at->children().size(), 0); -} - -//! Create 2 multilayers, 3 layers each. Move layer from one multilayer to another. -//! Deleting everything and undoing. - -TEST_F(UndoStackTest, moveLayerFromMLDeleteAll) -{ - auto pool = std::make_shared<ItemPool>(); - - ToyItems::SampleModel model(pool); - model.setUndoRedoEnabled(true); - auto stack = model.undoStack(); - - // creating multi layer with 3 layers - auto multilayer0 = model.insertItem<ToyItems::MultiLayerItem>(); - auto layer0 = model.insertItem<ToyItems::LayerItem>(multilayer0); - auto layer1 = model.insertItem<ToyItems::LayerItem>(multilayer0); - auto layer2 = model.insertItem<ToyItems::LayerItem>(multilayer0); - - // saving identifiers for further reference - identifier_type id_multilayer0 = multilayer0->identifier(); - identifier_type id_layer0 = layer0->identifier(); - identifier_type id_layer1 = layer1->identifier(); - identifier_type id_layer2 = layer2->identifier(); - - // creating another multi layer with 3 layers - auto multilayer1 = model.insertItem<ToyItems::MultiLayerItem>(); - auto layer3 = model.insertItem<ToyItems::LayerItem>(multilayer1); - auto layer4 = model.insertItem<ToyItems::LayerItem>(multilayer1); - auto layer5 = model.insertItem<ToyItems::LayerItem>(multilayer1); - - // saving identifiers for further reference - identifier_type id_multilayer1 = multilayer1->identifier(); - identifier_type id_layer3 = layer3->identifier(); - identifier_type id_layer4 = layer4->identifier(); - identifier_type id_layer5 = layer5->identifier(); - - // checking status of unddo stack - EXPECT_EQ(stack->count(), 8); - EXPECT_EQ(stack->index(), 8); - - // moving layer1 to second multilayer - model.moveItem(layer1, multilayer1, {ToyItems::MultiLayerItem::T_LAYERS, 0}); - - // removing multilayers - model.removeItem(model.rootItem(), {"", 1}); - model.removeItem(model.rootItem(), {"", 0}); - - // checking status of unddo stack - EXPECT_EQ(stack->count(), 11); - EXPECT_EQ(stack->index(), 11); - - // undoing thrice - stack->undo(); - stack->undo(); - stack->undo(); - - // restoring pointers - auto multilayer0_r = pool->item_for_key(id_multilayer0); - auto layer0_r = pool->item_for_key(id_layer0); - auto layer1_r = pool->item_for_key(id_layer1); - auto layer2_r = pool->item_for_key(id_layer2); - auto multilayer1_r = pool->item_for_key(id_multilayer1); - auto layer3_r = pool->item_for_key(id_layer3); - auto layer4_r = pool->item_for_key(id_layer4); - auto layer5_r = pool->item_for_key(id_layer5); - - // checking layers - std::vector<SessionItem*> expected = {layer0_r, layer1_r, layer2_r}; - EXPECT_EQ(multilayer0_r->children(), expected); - - expected = {layer3_r, layer4_r, layer5_r}; - EXPECT_EQ(multilayer1_r->children(), expected); -} - -//! Creating two multilayers. Copying layer from one multilayer to another. - -TEST_F(UndoStackTest, copyLayerFromMultilayer) -{ - auto pool = std::make_shared<ItemPool>(); - ToyItems::SampleModel model(pool); - model.setUndoRedoEnabled(true); - auto stack = model.undoStack(); - - const double expected_thickness = 55.0; - - // creating multi layer with 3 layers - auto multilayer0 = model.insertItem<ToyItems::MultiLayerItem>(); - auto layer0 = model.insertItem<ToyItems::LayerItem>(multilayer0); - layer0->setProperty(ToyItems::LayerItem::P_THICKNESS, expected_thickness); - auto multilayer1 = model.insertItem<ToyItems::MultiLayerItem>(); - - // copying layer - auto layer_copy = dynamic_cast<ToyItems::LayerItem*>(model.copyItem(layer0, multilayer1)); - EXPECT_EQ(multilayer1->itemCount(ToyItems::MultiLayerItem::T_LAYERS), 1); - EXPECT_EQ(layer_copy->property<double>(ToyItems::LayerItem::P_THICKNESS), expected_thickness); - EXPECT_TRUE(layer0->identifier() != layer_copy->identifier()); - - auto id = layer_copy->identifier(); - EXPECT_EQ(pool->item_for_key(layer_copy->identifier()), layer_copy); - - // undoing - stack->undo(); - EXPECT_EQ(multilayer1->itemCount(ToyItems::MultiLayerItem::T_LAYERS), 0); - - // redoing - stack->redo(); - EXPECT_EQ(multilayer1->itemCount(ToyItems::MultiLayerItem::T_LAYERS), 1); - EXPECT_EQ(multilayer1->getItems(ToyItems::MultiLayerItem::T_LAYERS)[0]->identifier(), id); -} - -//! Add item and changing its data from macros. - -TEST_F(UndoStackTest, beginMacrosEndMacros) -{ - const int role = ItemDataRole::DATA; - const QVariant data(42); - - SessionModel model; - model.setUndoRedoEnabled(true); - auto stack = model.undoStack(); - - stack->beginMacro("macro1"); - auto item = model.insertItem<SessionItem>(); - item->setData(data, role); - stack->endMacro(); - - // initial state before removing the row - EXPECT_EQ(stack->count(), 1); // insert and setData commands - EXPECT_EQ(stack->index(), 1); // insert and setData commands - EXPECT_FALSE(model.undoStack()->canRedo()); - EXPECT_TRUE(model.undoStack()->canUndo()); - EXPECT_EQ(item->data<QVariant>(role), data); - EXPECT_EQ(model.rootItem()->childrenCount(), 1); - - // undoing and checking the data - stack->undo(); - EXPECT_EQ(stack->count(), 1); - EXPECT_EQ(stack->index(), 0); - EXPECT_EQ(model.rootItem()->childrenCount(), 0); - - // redoing - stack->redo(); - EXPECT_EQ(stack->count(), 1); - EXPECT_EQ(stack->index(), 1); - EXPECT_EQ(model.rootItem()->childrenCount(), 1); - item = Utils::ChildAt(model.rootItem(), 0); - EXPECT_EQ(model.data(item, role).value<double>(), 42.0); -} - -//! Add GraphItem and Data1DItem, addisgn data to graph, undo, then redo. -//! GraphItem should be pointing again to Data1DItem. -//! This is real bug case. - -TEST_F(UndoStackTest, insertDataAndGraph) -{ - // constructing model with pool, enabling undo/redo - auto pool = std::make_shared<ItemPool>(); - SessionModel model("Model", pool); - model.setUndoRedoEnabled(true); - EXPECT_EQ(model.undoStack()->index(), 0); - EXPECT_EQ(model.undoStack()->count(), 0); - - auto dataItem = model.insertItem<Data1DItem>(); - auto graphItem = model.insertItem<GraphItem>(); - graphItem->setDataItem(dataItem); - - auto data_item_identifier = dataItem->identifier(); - auto graph_item_identifier = graphItem->identifier(); - - // model has two elements, graph is pointing to the data - EXPECT_EQ(model.undoStack()->index(), 3); - EXPECT_EQ(model.undoStack()->count(), 3); - EXPECT_EQ(model.rootItem()->childrenCount(), 2); - EXPECT_EQ(graphItem->dataItem(), dataItem); - - // checking pool - EXPECT_EQ(pool->item_for_key(data_item_identifier), dataItem); - EXPECT_EQ(pool->item_for_key(graph_item_identifier), graphItem); - - // undoing once (setDataItem operation) - model.undoStack()->undo(); - EXPECT_EQ(model.undoStack()->index(), 2); - EXPECT_EQ(model.undoStack()->count(), 3); - EXPECT_EQ(model.rootItem()->childrenCount(), 2); - EXPECT_EQ(graphItem->dataItem(), nullptr); - - // undoing two more times item - model.undoStack()->undo(); - model.undoStack()->undo(); - EXPECT_EQ(model.undoStack()->index(), 0); - EXPECT_EQ(model.undoStack()->count(), 3); - EXPECT_EQ(model.rootItem()->childrenCount(), 0); - - // redoing (dataItem is back) - model.undoStack()->redo(); - EXPECT_EQ(model.undoStack()->index(), 1); - EXPECT_EQ(model.rootItem()->childrenCount(), 1); - auto restoredDataItem = model.topItem<Data1DItem>(); - EXPECT_EQ(restoredDataItem->identifier(), data_item_identifier); - EXPECT_EQ(pool->item_for_key(data_item_identifier), restoredDataItem); - - // redoing (GraphItem) is back - model.undoStack()->redo(); - EXPECT_EQ(model.undoStack()->index(), 2); - EXPECT_EQ(model.rootItem()->childrenCount(), 2); - auto restoredGraphItem = model.topItem<GraphItem>(); - EXPECT_EQ(restoredGraphItem->identifier(), graph_item_identifier); - EXPECT_EQ(restoredGraphItem->dataItem(), nullptr); - - // redoing (graph is linked with data gaian) - model.undoStack()->redo(); - EXPECT_EQ(model.undoStack()->index(), 3); - EXPECT_EQ(model.rootItem()->childrenCount(), 2); - EXPECT_EQ(restoredGraphItem->dataItem(), restoredDataItem); -} - -//! Setup Data1DItem via macro. Undo, then redo. -//! Add GraphItem and Data1DItem, addisgn data to graph, undo, then redo. -//! GraphItem should be pointing again to Data1DItem. -//! This is real bug case. - -TEST_F(UndoStackTest, insertDataItemViaMacro) -{ - SessionModel model; - model.setUndoRedoEnabled(true); - EXPECT_EQ(model.undoStack()->index(), 0); - EXPECT_EQ(model.undoStack()->count(), 0); - - // setting up single data item via macro - model.undoStack()->beginMacro("AddDataItem"); - auto dataItem = model.insertItem<Data1DItem>(); - const std::vector<double> expected_values = {1.0, 2.0, 3.0}; - const std::vector<double> expected_centers = {0.5, 1.5, 2.5}; - dataItem->setAxis<FixedBinAxisItem>(3, 0.0, 3.0); - dataItem->setValues(expected_values); - model.undoStack()->endMacro(); - - EXPECT_EQ(model.undoStack()->index(), 1); - EXPECT_EQ(model.undoStack()->count(), 1); - - // undoing and returning back - model.undoStack()->undo(); - model.undoStack()->redo(); - EXPECT_EQ(model.undoStack()->index(), 1); - EXPECT_EQ(model.undoStack()->count(), 1); - - auto restoredDataItem = model.topItem<Data1DItem>(); - EXPECT_EQ(restoredDataItem->binCenters(), expected_centers); - EXPECT_EQ(restoredDataItem->binValues(), expected_values); -} diff --git a/mvvm/tests/testmodel/vectoritem.test.cpp b/mvvm/tests/testmodel/vectoritem.test.cpp deleted file mode 100644 index 55eb57155a0bbc5707f52b7af4243a3f16458f3f..0000000000000000000000000000000000000000 --- a/mvvm/tests/testmodel/vectoritem.test.cpp +++ /dev/null @@ -1,68 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testmodel/vectoritem.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/model/itemutils.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/standarditems/vectoritem.h" - -using namespace ModelView; - -//! VectorItem tests. - -class VectorItemTest : public ::testing::Test { -public: - ~VectorItemTest(); -}; - -VectorItemTest::~VectorItemTest() = default; - -//! Initial state of item when it is created outside of model context. - -TEST_F(VectorItemTest, initialState) -{ - VectorItem item; - - EXPECT_TRUE(Utils::IsSinglePropertyTag(item, VectorItem::P_X)); - EXPECT_TRUE(Utils::IsSinglePropertyTag(item, VectorItem::P_Y)); - EXPECT_TRUE(Utils::IsSinglePropertyTag(item, VectorItem::P_Z)); - - EXPECT_FALSE(item.isEditable()); - - EXPECT_EQ(item.property<double>(VectorItem::P_X), 0.0); - EXPECT_EQ(item.property<double>(VectorItem::P_Y), 0.0); - EXPECT_EQ(item.property<double>(VectorItem::P_Z), 0.0); - - // default label - EXPECT_EQ(item.data<std::string>(), "(0, 0, 0)"); -} - -//! Initial state of item in model context - -TEST_F(VectorItemTest, initialStateFromModel) -{ - SessionModel model; - auto item = model.insertItem<VectorItem>(); - - EXPECT_EQ(item->property<double>(VectorItem::P_X), 0.0); - EXPECT_EQ(item->property<double>(VectorItem::P_Y), 0.0); - EXPECT_EQ(item->property<double>(VectorItem::P_Z), 0.0); - - // default label - EXPECT_EQ(item->data<std::string>(), "(0, 0, 0)"); - - // changing vector component - item->setProperty(VectorItem::P_X, 1.0); - EXPECT_EQ(item->data<std::string>(), "(1, 0, 0)"); -} diff --git a/mvvm/tests/testview/CMakeLists.txt b/mvvm/tests/testview/CMakeLists.txt deleted file mode 100644 index fcd20d0b2a37cc994bb775e1476de3201c2aeb36..0000000000000000000000000000000000000000 --- a/mvvm/tests/testview/CMakeLists.txt +++ /dev/null @@ -1,20 +0,0 @@ -set(test testview) - -file(GLOB source_files "*.cpp") -file(GLOB include_files "*.h") - -find_package(Qt5Core REQUIRED) -find_package(Qt5Test REQUIRED) - -# necessary for Qt creator and clang code model -include_directories(${gtest_SOURCE_DIR}/include ${gtest_SOURCE_DIR}) - -set(CMAKE_AUTOMOC ON) -add_executable(${test} ${source_files} ${include_files}) -target_link_libraries(${test} gtest gmock Qt5::Core Qt5::Test mvvm_view testmachinery qcustomplot) - -if (MVVM_DISCOVER_TESTS) - gtest_discover_tests(${test}) -else() - add_custom_target(${test}_run ALL DEPENDS ${test} COMMAND ${test}) -endif() diff --git a/mvvm/tests/testview/TestAll.cpp b/mvvm/tests/testview/TestAll.cpp deleted file mode 100644 index ac7bb375367e15adff63b4ddc9398da09c2bec57..0000000000000000000000000000000000000000 --- a/mvvm/tests/testview/TestAll.cpp +++ /dev/null @@ -1,37 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testview/TestAll.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "customplot_test_utils.h" -#include "google_test.h" -#include "qcustomplot.h" -#include <QApplication> -#include <QStandardItem> -#include <gmock/gmock.h> - -int main(int argc, char** argv) -{ - ::testing::InitGoogleTest(&argc, argv); - ::testing::InitGoogleMock(&argc, argv); - - ModelView::Comparators::registerComparators(); - qRegisterMetaType<QStandardItem*>("QStandardItem*"); - qRegisterMetaType<QCPRange>("QCPRange"); - - // FIXME find the way not to run app for all tests which doesn't use QWidget. - // The problem here is because of ctest autodiscovery which runs given main at every test. - QApplication app(argc, argv); - Q_UNUSED(app) - - return RUN_ALL_TESTS(); -} diff --git a/mvvm/tests/testview/axistitlecontroller.test.cpp b/mvvm/tests/testview/axistitlecontroller.test.cpp deleted file mode 100644 index 8ff34faf0d274dc6c7f943585213d2b8348aff7c..0000000000000000000000000000000000000000 --- a/mvvm/tests/testview/axistitlecontroller.test.cpp +++ /dev/null @@ -1,100 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testview/axistitlecontroller.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/plotting/axistitlecontroller.h" -#include "mvvm/standarditems/plottableitems.h" -#include "qcustomplot.h" -#include <QFont> - -using namespace ModelView; - -//! Testing AxisTitleControllers. - -class AxisTitleControllerTest : public ::testing::Test { -public: - ~AxisTitleControllerTest(); -}; - -AxisTitleControllerTest::~AxisTitleControllerTest() = default; - -//! Initial state. - -TEST_F(AxisTitleControllerTest, initialState) -{ - auto custom_plot = std::make_unique<QCustomPlot>(); - - auto axis = custom_plot->xAxis; - - // controller shouldn''t change axis range - AxisTitleController controller(axis); - EXPECT_EQ(controller.currentItem(), nullptr); - - EXPECT_EQ(axis->label(), QString()); -} - -TEST_F(AxisTitleControllerTest, setTextItem) -{ - auto custom_plot = std::make_unique<QCustomPlot>(); - - SessionModel model; - auto textItem = model.insertItem<TextItem>(); - - auto axis = custom_plot->xAxis; - // auto expected_pointSize = axis->labelFont().pointSize(); - // auto expected_family = axis->labelFont().family(); - - // this a values hardcoded in plottableitems.cpp. Shell we provide some customized way to create - // TextItem with font/size suitable for QCPAxis ? - const int expected_pointSize = 10; - const std::string expected_family = "Noto Sans"; - - // controller shouldn''t change axis range - AxisTitleController controller(axis); - controller.setItem(textItem); - EXPECT_EQ(controller.currentItem(), textItem); - - EXPECT_EQ(axis->label(), QString()); - EXPECT_EQ(axis->labelFont().family().toStdString(), expected_family); - EXPECT_EQ(axis->labelFont().pointSize(), expected_pointSize); -} - -TEST_F(AxisTitleControllerTest, setFont) -{ - auto custom_plot = std::make_unique<QCustomPlot>(); - - SessionModel model; - auto textItem = model.insertItem<TextItem>(); - - auto axis = custom_plot->xAxis; - - // controller shouldn''t change axis range - AxisTitleController controller(axis); - controller.setItem(textItem); - EXPECT_EQ(controller.currentItem(), textItem); - - // setting new label - const QString expected_text("abc"); - const QString expected_family("Helvetica"); - const int expected_size = 42; - textItem->setProperty(TextItem::P_TEXT, expected_text.toStdString()); - textItem->setProperty(TextItem::P_SIZE, expected_size); - textItem->setProperty(TextItem::P_FONT, expected_family.toStdString()); - - // checking that label has updated - EXPECT_EQ(axis->label(), expected_text); - EXPECT_EQ(axis->labelFont().family(), expected_family); - EXPECT_EQ(axis->labelFont().pointSize(), expected_size); -} diff --git a/mvvm/tests/testview/colormapplotcontroller.test.cpp b/mvvm/tests/testview/colormapplotcontroller.test.cpp deleted file mode 100644 index c60d15babcea437ff95f1295ff721f754d944f9d..0000000000000000000000000000000000000000 --- a/mvvm/tests/testview/colormapplotcontroller.test.cpp +++ /dev/null @@ -1,214 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testview/colormapplotcontroller.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "customplot_test_utils.h" -#include "google_test.h" -#include "mvvm/model/comboproperty.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/plotting/colormapplotcontroller.h" -#include "mvvm/standarditems/axisitems.h" -#include "mvvm/standarditems/colormapitem.h" -#include "mvvm/standarditems/data2ditem.h" -#include "qcustomplot.h" -#include <QSignalSpy> - -using namespace ModelView; - -//! Testing ColorMapPlotController. - -class ColorMapPlotControllerTest : public ::testing::Test { -public: - ~ColorMapPlotControllerTest(); -}; - -ColorMapPlotControllerTest::~ColorMapPlotControllerTest() = default; - -//! Initial state. - -TEST_F(ColorMapPlotControllerTest, initialState) -{ - auto custom_plot = std::make_unique<QCustomPlot>(); - ColorMapPlotController controller(custom_plot.get()); - EXPECT_EQ(controller.currentItem(), nullptr); - - // creation of controller leads to the creation of QCPColorMap - auto color_map = TestUtils::GetPlottable<QCPColorMap>(custom_plot.get()); - ASSERT_TRUE(color_map != nullptr); -} - -//! Setting ColorMapItem with data and checking that QCPColorMap appeared among plottables. - -TEST_F(ColorMapPlotControllerTest, setItem) -{ - auto custom_plot = std::make_unique<QCustomPlot>(); - ColorMapPlotController controller(custom_plot.get()); - - // creating data item - SessionModel model; - auto data_item = model.insertItem<Data2DItem>(); - const int nx = 3, ny = 2; - data_item->setAxes(FixedBinAxisItem::create(nx, 0.0, 3.0), - FixedBinAxisItem::create(ny, 0.0, 2.0)); - std::vector<double> expected = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0}; - data_item->setContent(expected); - - // creating colormap item - auto colormap_item = model.insertItem<ColorMapItem>(); - colormap_item->setDataItem(data_item); - - // initializing controller - controller.setItem(colormap_item); - - // checking that QCPColorMap has been created - EXPECT_EQ(custom_plot->plottableCount(), 1); - auto color_map = TestUtils::GetPlottable<QCPColorMap>(custom_plot.get()); - ASSERT_TRUE(color_map != nullptr); - EXPECT_EQ(color_map->data()->keySize(), nx); - EXPECT_EQ(color_map->data()->valueSize(), ny); - EXPECT_EQ(color_map->data()->cell(0, 0), 1.0); - EXPECT_EQ(color_map->data()->cell(nx - 1, ny - 1), 6.0); - - // checking interpolation flag - EXPECT_TRUE(color_map->interpolate()); -} - -//! Setting data to graph after. - -TEST_F(ColorMapPlotControllerTest, setDataAfter) -{ - auto custom_plot = std::make_unique<QCustomPlot>(); - ColorMapPlotController controller(custom_plot.get()); - - SessionModel model; - auto colormap_item = model.insertItem<ColorMapItem>(); - - controller.setItem(colormap_item); - - // without data QCustomPlot has QCPColorMap without default settings - EXPECT_EQ(custom_plot->plottableCount(), 1); - auto color_map = TestUtils::GetPlottable<QCPColorMap>(custom_plot.get()); - ASSERT_TRUE(color_map != nullptr); - const int qcpmap_internal_default(10); - EXPECT_EQ(color_map->data()->keySize(), qcpmap_internal_default); - EXPECT_EQ(color_map->data()->valueSize(), qcpmap_internal_default); - - // setup Data2DItem and assign to ColorMapItem - auto data_item = model.insertItem<Data2DItem>(); - const int nx = 3, ny = 2; - data_item->setAxes(FixedBinAxisItem::create(nx, 0.0, 3.0), - FixedBinAxisItem::create(ny, 0.0, 2.0)); - std::vector<double> expected = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0}; - data_item->setContent(expected); - - colormap_item->setDataItem(data_item); - - // colormap should get the shape of Data2DItem - EXPECT_EQ(color_map->data()->keySize(), nx); - EXPECT_EQ(color_map->data()->valueSize(), ny); - EXPECT_EQ(color_map->data()->cell(0, 0), 1.0); - EXPECT_EQ(color_map->data()->cell(nx - 1, ny - 1), 6.0); -} - -//! Unlinking from Data2DItem or ColorMapItem. - -TEST_F(ColorMapPlotControllerTest, unlinkFromItem) -{ - auto custom_plot = std::make_unique<QCustomPlot>(); - ColorMapPlotController controller(custom_plot.get()); - - // setup model and single data item in it - SessionModel model; - auto data_item = model.insertItem<Data2DItem>(); - const int nx = 3, ny = 2; - data_item->setAxes(FixedBinAxisItem::create(nx, 0.0, 3.0), - FixedBinAxisItem::create(ny, 0.0, 2.0)); - std::vector<double> expected = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0}; - data_item->setContent(expected); - - // creating colormap item - auto colormap_item = model.insertItem<ColorMapItem>(); - colormap_item->setDataItem(data_item); - - controller.setItem(colormap_item); - - auto color_map = TestUtils::GetPlottable<QCPColorMap>(custom_plot.get()); - EXPECT_EQ(color_map->data()->keySize(), nx); - EXPECT_EQ(color_map->data()->valueSize(), ny); - - // unlinking from data item - colormap_item->setDataItem(nullptr); - - EXPECT_EQ(custom_plot->plottableCount(), 1); - - // QCPColorMap should be there, but its shapre should be (0,0) - EXPECT_EQ(color_map->data()->keySize(), 0); - EXPECT_EQ(color_map->data()->valueSize(), 0); - - // unlinking from ColorMapItem leave QCPColorMap intact - controller.setItem(nullptr); - EXPECT_EQ(custom_plot->plottableCount(), 1); - EXPECT_EQ(color_map->data()->keySize(), 0); - EXPECT_EQ(color_map->data()->valueSize(), 0); -} - -//! Deletion of controller should lead to graph removal. - -TEST_F(ColorMapPlotControllerTest, controllerDelete) -{ - auto custom_plot = std::make_unique<QCustomPlot>(); - auto controller = std::make_unique<ColorMapPlotController>(custom_plot.get()); - - // setup model and single data item in it - SessionModel model; - auto data_item = model.insertItem<Data2DItem>(); - - // setup graph item - auto colormap_item = model.insertItem<ColorMapItem>(); - colormap_item->setDataItem(data_item); - - // initializing controller - controller->setItem(colormap_item); - EXPECT_EQ(custom_plot->plottableCount(), 1); - - // deleting controller should lead to QCPColorMap removal - controller.reset(); - EXPECT_EQ(custom_plot->plottableCount(), 0); -} - -//! Deletion of controller should lead to graph removal. - -TEST_F(ColorMapPlotControllerTest, setGradient) -{ - auto custom_plot = std::make_unique<QCustomPlot>(); - auto controller = std::make_unique<ColorMapPlotController>(custom_plot.get()); - - // setup model and single data item in it - SessionModel model; - auto data_item = model.insertItem<Data2DItem>(); - - // creating colormap item - auto colormap_item = model.insertItem<ColorMapItem>(); - colormap_item->setDataItem(data_item); - - controller->setItem(colormap_item); - - auto color_map = TestUtils::GetPlottable<QCPColorMap>(custom_plot.get()); - - EXPECT_EQ(color_map->gradient(), QCPColorGradient::gpPolar); - - auto combo = colormap_item->property<ComboProperty>(ColorMapItem::P_GRADIENT); - combo.setValue("Hot"); - colormap_item->setProperty(ColorMapItem::P_GRADIENT, combo); - EXPECT_EQ(color_map->gradient(), QCPColorGradient::gpHot); -} diff --git a/mvvm/tests/testview/colormapviewportplotcontroller.test.cpp b/mvvm/tests/testview/colormapviewportplotcontroller.test.cpp deleted file mode 100644 index 7bb0891f8f0be8efab64599dc266d5fe3476e372..0000000000000000000000000000000000000000 --- a/mvvm/tests/testview/colormapviewportplotcontroller.test.cpp +++ /dev/null @@ -1,142 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testview/colormapviewportplotcontroller.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "customplot_test_utils.h" -#include "google_test.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/plotting/colormapviewportplotcontroller.h" -#include "mvvm/standarditems/axisitems.h" -#include "mvvm/standarditems/colormapitem.h" -#include "mvvm/standarditems/colormapviewportitem.h" -#include "mvvm/standarditems/data1ditem.h" -#include "mvvm/standarditems/data2ditem.h" -#include "qcustomplot.h" -#include <qcustomplot.h> - -using namespace ModelView; - -//! Testing ColorMapViewportPlotController. - -class ColorMapViewportPlotControllerTest : public ::testing::Test { -public: - ~ColorMapViewportPlotControllerTest(); -}; - -ColorMapViewportPlotControllerTest::~ColorMapViewportPlotControllerTest() = default; - -//! Initial state. - -TEST_F(ColorMapViewportPlotControllerTest, initialState) -{ - auto custom_plot = std::make_unique<QCustomPlot>(); - ColorMapViewportPlotController controller(custom_plot.get()); - EXPECT_EQ(controller.currentItem(), nullptr); - EXPECT_TRUE(TestUtils::GetPlottable<QCPColorMap>(custom_plot.get()) != nullptr); - - const double customplot_default_lower(0.0), customplot_default_upper(5.0); - EXPECT_DOUBLE_EQ(custom_plot->xAxis->range().lower, customplot_default_lower); - EXPECT_DOUBLE_EQ(custom_plot->xAxis->range().upper, customplot_default_upper); - EXPECT_DOUBLE_EQ(custom_plot->yAxis->range().lower, customplot_default_lower); - EXPECT_DOUBLE_EQ(custom_plot->yAxis->range().upper, customplot_default_upper); -} - -//! Check ::setItem() method when no colormaps exist. - -TEST_F(ColorMapViewportPlotControllerTest, setEmptyViewport) -{ - auto custom_plot = std::make_unique<QCustomPlot>(); - ColorMapViewportPlotController controller(custom_plot.get()); - - SessionModel model; - auto viewport_item = model.insertItem<ColorMapViewportItem>(); - - controller.setItem(viewport_item); - - auto color_map = TestUtils::GetPlottable<QCPColorMap>(custom_plot.get()); - EXPECT_TRUE(color_map != nullptr); - - const double default_lower(0.0), default_upper(1.0); - EXPECT_DOUBLE_EQ(custom_plot->xAxis->range().lower, default_lower); - EXPECT_DOUBLE_EQ(custom_plot->xAxis->range().upper, default_upper); - EXPECT_DOUBLE_EQ(custom_plot->yAxis->range().lower, default_lower); - EXPECT_DOUBLE_EQ(custom_plot->yAxis->range().upper, default_upper); - - const int qcpmap_internal_default(10); - EXPECT_EQ(color_map->data()->keySize(), qcpmap_internal_default); - EXPECT_EQ(color_map->data()->valueSize(), qcpmap_internal_default); -} - -//! Check ::setItem() method when data 2d is fully set up. - -TEST_F(ColorMapViewportPlotControllerTest, setItem) -{ - auto custom_plot = std::make_unique<QCustomPlot>(); - ColorMapViewportPlotController controller(custom_plot.get()); - - SessionModel model; - auto data_item = model.insertItem<Data2DItem>(); - const int nx = 3, ny = 2; - data_item->setAxes(FixedBinAxisItem::create(nx, 0.0, 3.0), - FixedBinAxisItem::create(ny, 0.0, 2.0)); - std::vector<double> expected = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0}; - data_item->setContent(expected); - - // creating colormap item - auto viewport_item = model.insertItem<ColorMapViewportItem>(); - auto colormap_item = model.insertItem<ColorMapItem>(viewport_item); - colormap_item->setDataItem(data_item); - - // setting up the controller - controller.setItem(viewport_item); - - auto color_map = TestUtils::GetPlottable<QCPColorMap>(custom_plot.get()); - EXPECT_EQ(color_map->data()->keySize(), nx); - EXPECT_EQ(color_map->data()->valueSize(), ny); - EXPECT_EQ(color_map->data()->cell(0, 0), 1.0); - EXPECT_EQ(color_map->data()->cell(nx - 1, ny - 1), 6.0); -} - -//! Consequitive setup. - -TEST_F(ColorMapViewportPlotControllerTest, setupConsequitive) -{ - auto custom_plot = std::make_unique<QCustomPlot>(); - ColorMapViewportPlotController controller(custom_plot.get()); - - SessionModel model; - auto viewport_item = model.insertItem<ColorMapViewportItem>(); - - controller.setItem(viewport_item); - - auto color_map = TestUtils::GetPlottable<QCPColorMap>(custom_plot.get()); - EXPECT_TRUE(color_map != nullptr); - - // setting up data - auto data_item = model.insertItem<Data2DItem>(); - const int nx = 3, ny = 2; - data_item->setAxes(FixedBinAxisItem::create(nx, 0.0, 3.0), - FixedBinAxisItem::create(ny, 0.0, 2.0)); - std::vector<double> expected = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0}; - data_item->setContent(expected); - - // creating colormap item - auto colormap_item = model.insertItem<ColorMapItem>(viewport_item); - colormap_item->setDataItem(data_item); - - // checking that QCPColorMap has good shape - EXPECT_EQ(color_map->data()->keySize(), nx); - EXPECT_EQ(color_map->data()->valueSize(), ny); - EXPECT_EQ(color_map->data()->cell(0, 0), 1.0); - EXPECT_EQ(color_map->data()->cell(nx - 1, ny - 1), 6.0); -} diff --git a/mvvm/tests/testview/customplot_test_utils.cpp b/mvvm/tests/testview/customplot_test_utils.cpp deleted file mode 100644 index b4afc717bcc8a1a057ceb06c621db849311cebdb..0000000000000000000000000000000000000000 --- a/mvvm/tests/testview/customplot_test_utils.cpp +++ /dev/null @@ -1,37 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testview/customplot_test_utils.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "customplot_test_utils.h" -#include <qcustomplot.h> - -std::vector<double> TestUtils::binCenters(const QCPGraph* graph) -{ - return get_values(graph, [](auto x) { return x.key; }); -} - -std::vector<double> TestUtils::binValues(const QCPGraph* graph) -{ - return get_values(graph, [](auto x) { return x.value; }); -} - -std::vector<double> TestUtils::binErrors(const QCPGraph* graph) -{ - std::vector<double> result; - if (auto errorBars = GetPlottable<QCPErrorBars>(graph->parentPlot()); errorBars) { - auto container = errorBars->data(); - std::transform(container->begin(), container->end(), std::back_inserter(result), - [](auto x) { return x.errorPlus; }); - }; - return result; -} diff --git a/mvvm/tests/testview/customplot_test_utils.h b/mvvm/tests/testview/customplot_test_utils.h deleted file mode 100644 index e2e9dbaa0680d0cb8d23bad3e1c21d69caf0ad61..0000000000000000000000000000000000000000 --- a/mvvm/tests/testview/customplot_test_utils.h +++ /dev/null @@ -1,59 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testview/customplot_test_utils.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_TESTS_TESTVIEW_CUSTOMPLOT_TEST_UTILS_H -#define BORNAGAIN_MVVM_TESTS_TESTVIEW_CUSTOMPLOT_TEST_UTILS_H - -#include <algorithm> -#include <qcustomplot.h> -#include <vector> - -//! Various common utils for unit tests. - -namespace TestUtils { - -//! Returns vector representing bin centers/values on QCPGraph. - -template <typename G, typename T> std::vector<double> get_values(const G* graph, T operand) -{ - std::vector<double> result; - auto graph_data = *graph->data(); - std::transform(std::begin(graph_data), std::end(graph_data), std::back_inserter(result), - [operand](const auto& point) { return operand(point); }); - return result; -} - -//! Returns vector representing bin centers on QCPgraph. -std::vector<double> binCenters(const QCPGraph* graph); - -//! Returns vector representing y-values on QCPgraph. -std::vector<double> binValues(const QCPGraph* graph); - -//! Returns vector representing bin errors of QCPGraph. -std::vector<double> binErrors(const QCPGraph* graph); - -//! Finds and returns specific plottable in QCustomPlot canvas. -template <typename T> T* GetPlottable(QCustomPlot* custom_plot) -{ - for (int i = 0; i < custom_plot->plottableCount(); ++i) { - if (auto plottable = dynamic_cast<T*>(custom_plot->plottable()); plottable) - return plottable; - } - return nullptr; -} -} // namespace TestUtils - -Q_DECLARE_METATYPE(QCPRange) - -#endif // BORNAGAIN_MVVM_TESTS_TESTVIEW_CUSTOMPLOT_TEST_UTILS_H diff --git a/mvvm/tests/testview/customplot_test_utils.test.cpp b/mvvm/tests/testview/customplot_test_utils.test.cpp deleted file mode 100644 index 29846682f052c061be6a27d0f938744e2804331a..0000000000000000000000000000000000000000 --- a/mvvm/tests/testview/customplot_test_utils.test.cpp +++ /dev/null @@ -1,60 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testview/customplot_test_utils.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "customplot_test_utils.h" -#include "google_test.h" -#include "qcustomplot.h" - -using namespace ModelView; - -//! Testing "utilr for testing" defined in TestUtils namespace. - -class CustomplotTestUtilsTest : public ::testing::Test { -public: - ~CustomplotTestUtilsTest(); -}; - -CustomplotTestUtilsTest::~CustomplotTestUtilsTest() = default; - -//! Check methods to access graph bin centers and values. - -TEST_F(CustomplotTestUtilsTest, binCentersbinValues) -{ - QCustomPlot custom_plot; - - auto graph = custom_plot.addGraph(); - graph->setData(QVector<double>({1, 2, 3}), QVector<double>({10, 20, 30})); - - EXPECT_EQ(TestUtils::binCenters(graph), std::vector<double>({1, 2, 3})); - EXPECT_EQ(TestUtils::binValues(graph), std::vector<double>({10, 20, 30})); -} - -//! Check methods to access graph errors. - -TEST_F(CustomplotTestUtilsTest, binErrors) -{ - QCustomPlot custom_plot; - - auto graph = custom_plot.addGraph(); - graph->setData(QVector<double>({1, 2, 3}), QVector<double>({10, 20, 30})); - - EXPECT_EQ(TestUtils::binErrors(graph), std::vector<double>()); - - QCPErrorBars* errorBars = new QCPErrorBars(custom_plot.xAxis, custom_plot.yAxis); - errorBars->removeFromLegend(); - errorBars->setDataPlottable(graph); - errorBars->setData(QVector<double>({0.1, 0.2, 0.3})); - - EXPECT_EQ(TestUtils::binErrors(graph), std::vector<double>({0.1, 0.2, 0.3})); -} diff --git a/mvvm/tests/testview/customplotsceneadapter.test.cpp b/mvvm/tests/testview/customplotsceneadapter.test.cpp deleted file mode 100644 index 94ff73b6a387af342d1640a8a3386a6707550313..0000000000000000000000000000000000000000 --- a/mvvm/tests/testview/customplotsceneadapter.test.cpp +++ /dev/null @@ -1,53 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testview/customplotsceneadapter.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/plotting/customplotsceneadapter.h" -#include "qcustomplot.h" - -using namespace ModelView; - -//! Testing CustomPlotSceneAdapter. - -class CustomPlotSceneAdapterTest : public ::testing::Test { -public: - ~CustomPlotSceneAdapterTest(); -}; - -CustomPlotSceneAdapterTest::~CustomPlotSceneAdapterTest() = default; - -//! Scenario when QCustomPlot destroyed before adapter. - -TEST_F(CustomPlotSceneAdapterTest, customPlotBeforeAdapter) -{ - auto custom_plot = std::make_unique<QCustomPlot>(); - auto adapter = std::make_unique<CustomPlotSceneAdapter>(custom_plot.get()); - - // destroying QCustomPlot - custom_plot.reset(); - - EXPECT_EQ(42, adapter->toSceneX(42)); - EXPECT_EQ(42, adapter->toSceneY(42)); - EXPECT_EQ(42, adapter->fromSceneX(42)); - EXPECT_EQ(42, adapter->fromSceneY(42)); -} - -TEST_F(CustomPlotSceneAdapterTest, adapterBeforeCustomPlot) -{ - auto custom_plot = std::make_unique<QCustomPlot>(); - auto adapter = std::make_unique<CustomPlotSceneAdapter>(custom_plot.get()); - - adapter.reset(); - custom_plot.reset(); // would cause SEGFAULT if connection to adapter still exists -} diff --git a/mvvm/tests/testview/data1dplotcontroller.test.cpp b/mvvm/tests/testview/data1dplotcontroller.test.cpp deleted file mode 100644 index 1995c70f3ac7e0668b040e8cd063f9295a1fea3b..0000000000000000000000000000000000000000 --- a/mvvm/tests/testview/data1dplotcontroller.test.cpp +++ /dev/null @@ -1,181 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testview/data1dplotcontroller.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "customplot_test_utils.h" -#include "google_test.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/plotting/data1dplotcontroller.h" -#include "mvvm/standarditems/axisitems.h" -#include "mvvm/standarditems/data1ditem.h" -#include "qcustomplot.h" -#include <algorithm> -#include <stdexcept> - -using namespace ModelView; - -//! Testing Data1DPlotController. - -class Data1DPlotControllerTest : public ::testing::Test { -public: - ~Data1DPlotControllerTest(); -}; - -Data1DPlotControllerTest::~Data1DPlotControllerTest() = default; - -//! Initial state. - -TEST_F(Data1DPlotControllerTest, initialState) -{ - // Constructor accept valid QCPGraph - EXPECT_THROW(Data1DPlotController(nullptr), std::runtime_error); - - auto custom_plot = std::make_unique<QCustomPlot>(); - auto graph = custom_plot->addGraph(); - - Data1DPlotController controller(graph); - EXPECT_EQ(controller.currentItem(), nullptr); - - // no points have been added to graph - EXPECT_EQ(std::vector<double>(), TestUtils::binCenters(graph)); - EXPECT_EQ(std::vector<double>(), TestUtils::binValues(graph)); -} - -//! Testing controller when Data1DItem is not initialized properly. - -TEST_F(Data1DPlotControllerTest, dataItemInInitialState) -{ - // creating custom plot and empty graph on it - auto custom_plot = std::make_unique<QCustomPlot>(); - auto graph = custom_plot->addGraph(); - - // creating data item with single point - SessionModel model; - auto data_item = model.insertItem<Data1DItem>(); - - // creating controller and point it to Data1DItem - Data1DPlotController controller(graph); - controller.setItem(data_item); - - EXPECT_EQ(std::vector<double>(), TestUtils::binCenters(graph)); - EXPECT_EQ(std::vector<double>(), TestUtils::binValues(graph)); - EXPECT_EQ(std::vector<double>(), TestUtils::binErrors(graph)); -} - -//! Testing controller when Data1DItem get it's axis after controller setup. - -TEST_F(Data1DPlotControllerTest, axisAfter) -{ - // creating custom plot and empty graph on it - auto custom_plot = std::make_unique<QCustomPlot>(); - auto graph = custom_plot->addGraph(); - - // creating data item with single point - SessionModel model; - auto data_item = model.insertItem<Data1DItem>(); - - // creating controller and point it to Data1DItem - Data1DPlotController controller(graph); - controller.setItem(data_item); - - // setting correct axis - data_item->setAxis<FixedBinAxisItem>(1, 1.0, 2.0); - EXPECT_EQ(data_item->binCenters(), TestUtils::binCenters(graph)); - EXPECT_EQ(data_item->binValues(), TestUtils::binValues(graph)); - EXPECT_EQ(std::vector<double>(), TestUtils::binErrors(graph)); -} - -//! Testing graph points update. - -TEST_F(Data1DPlotControllerTest, dataPoints) -{ - // creating custom plot and empty graph on it - auto custom_plot = std::make_unique<QCustomPlot>(); - auto graph = custom_plot->addGraph(); - - // creating data item with single point - SessionModel model; - auto data_item = model.insertItem<Data1DItem>(); - data_item->setAxis<FixedBinAxisItem>(1, 1.0, 2.0); - - // creating controller and point it to Data1DItem - Data1DPlotController controller(graph); - controller.setItem(data_item); - - // checking that QCPGraph now has data points as in Data1DItem - EXPECT_EQ(data_item->binCenters(), TestUtils::binCenters(graph)); - EXPECT_EQ(data_item->binValues(), TestUtils::binValues(graph)); - EXPECT_EQ(data_item->binErrors(), TestUtils::binErrors(graph)); - - // Setting item to nullptr. Current convention is that graph stays intact, but points disappear. - controller.setItem(nullptr); - EXPECT_EQ(std::vector<double>(), TestUtils::binCenters(graph)); - EXPECT_EQ(std::vector<double>(), TestUtils::binValues(graph)); - EXPECT_EQ(std::vector<double>(), TestUtils::binErrors(graph)); -} - -//! Testing graph errors update. - -TEST_F(Data1DPlotControllerTest, errorBars) -{ - // creating custom plot and empty graph on it - auto custom_plot = std::make_unique<QCustomPlot>(); - auto graph = custom_plot->addGraph(); - - // creating data item with single point - SessionModel model; - auto data_item = model.insertItem<Data1DItem>(); - data_item->setAxis<FixedBinAxisItem>(2, 1.0, 2.0); - - // creating controller and point it to Data1DItem - Data1DPlotController controller(graph); - controller.setItem(data_item); - - std::vector<double> expected_errors = {0.1, 0.2}; - data_item->setErrors(expected_errors); - EXPECT_EQ(TestUtils::binErrors(graph), expected_errors); - - // setting new errors - expected_errors = {0.3, 0.4}; - data_item->setErrors(expected_errors); - EXPECT_EQ(TestUtils::binErrors(graph), expected_errors); -} - -//! Testing two graph scenario. - -TEST_F(Data1DPlotControllerTest, twoDataItems) -{ - // creating custom plot and empty graph on it - auto custom_plot = std::make_unique<QCustomPlot>(); - auto graph = custom_plot->addGraph(); - - // creating two data items - SessionModel model; - auto data_item1 = model.insertItem<Data1DItem>(); - data_item1->setAxis<FixedBinAxisItem>(1, 1.0, 2.0); - auto data_item2 = model.insertItem<Data1DItem>(); - data_item2->setAxis<FixedBinAxisItem>(2, 0.0, 2.0); - - // creating controller and point it to first item - Data1DPlotController controller(graph); - controller.setItem(data_item1); - - // checking that QCPGraph now has data points as in first data item - EXPECT_EQ(data_item1->binCenters(), TestUtils::binCenters(graph)); - EXPECT_EQ(data_item1->binValues(), TestUtils::binValues(graph)); - - // pointing controller to the second item - controller.setItem(data_item2); - EXPECT_EQ(data_item2->binCenters(), TestUtils::binCenters(graph)); - EXPECT_EQ(data_item2->binValues(), TestUtils::binValues(graph)); -} diff --git a/mvvm/tests/testview/data2dplotcontroller.test.cpp b/mvvm/tests/testview/data2dplotcontroller.test.cpp deleted file mode 100644 index 26648489ca3dab90148457341ce714fd5c566c61..0000000000000000000000000000000000000000 --- a/mvvm/tests/testview/data2dplotcontroller.test.cpp +++ /dev/null @@ -1,207 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testview/data2dplotcontroller.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "customplot_test_utils.h" -#include "google_test.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/plotting/data2dplotcontroller.h" -#include "mvvm/standarditems/axisitems.h" -#include "mvvm/standarditems/data2ditem.h" -#include "qcustomplot.h" -#include <QSignalSpy> -#include <stdexcept> - -using namespace ModelView; - -//! Testing Data1DPlotController. - -class Data2DPlotControllerTest : public ::testing::Test { -public: - ~Data2DPlotControllerTest(); -}; - -Data2DPlotControllerTest::~Data2DPlotControllerTest() = default; - -//! Initial state. - -TEST_F(Data2DPlotControllerTest, initialState) -{ - // Constructor accept valid QCPColorMap - EXPECT_THROW(Data2DPlotController(nullptr), std::runtime_error); - - auto custom_plot = std::make_unique<QCustomPlot>(); - auto color_map = new QCPColorMap(custom_plot->xAxis, custom_plot->yAxis); - color_map->data()->clear(); // to remove default values defined in QCPColorMap - - Data2DPlotController controller(color_map); - EXPECT_EQ(controller.currentItem(), nullptr); - - EXPECT_EQ(color_map->data()->keySize(), 0); - EXPECT_EQ(color_map->data()->valueSize(), 0); -} - -//! Testing controller when Data2DItem is not initialized properly. - -TEST_F(Data2DPlotControllerTest, dataItemInInitialState) -{ - // creating custom plot and empty graph on it - auto custom_plot = std::make_unique<QCustomPlot>(); - auto color_map = new QCPColorMap(custom_plot->xAxis, custom_plot->yAxis); - - // creating data item with single point - SessionModel model; - auto data_item = model.insertItem<Data2DItem>(); - - // creating controller and point it to Data2DItem - Data2DPlotController controller(color_map); - EXPECT_NO_THROW(controller.setItem(data_item)); - - // Since data item doesn't contain axes defined, should be no points on colormap. - EXPECT_EQ(color_map->data()->keySize(), 0); - EXPECT_EQ(color_map->data()->valueSize(), 0); -} - -//! Testing controller when Data2DItem got it's axes after controller was set. - -TEST_F(Data2DPlotControllerTest, setAxesAfter) -{ - // creating custom plot and empty graph on it - auto custom_plot = std::make_unique<QCustomPlot>(); - auto color_map = new QCPColorMap(custom_plot->xAxis, custom_plot->yAxis); - - // creating data item with single point - SessionModel model; - auto data_item = model.insertItem<Data2DItem>(); - - // creating controller and point it to Data2DItem - Data2DPlotController controller(color_map); - EXPECT_NO_THROW(controller.setItem(data_item)); - - // setting axes after - const int nx = 3, ny = 2; - data_item->setAxes(FixedBinAxisItem::create(nx, 0.0, 3.0), - FixedBinAxisItem::create(ny, 0.0, 2.0)); - - // color map should get shape of axes - EXPECT_EQ(color_map->data()->keySize(), nx); - EXPECT_EQ(color_map->data()->valueSize(), ny); - EXPECT_EQ(color_map->data()->cell(0, 0), 0.0); - EXPECT_EQ(color_map->data()->cell(nx - 1, ny - 1), 0.0); -} - -//! Testing data points. - -TEST_F(Data2DPlotControllerTest, dataPoints) -{ - // creating custom plot and empty graph on it - auto custom_plot = std::make_unique<QCustomPlot>(); - auto color_map = new QCPColorMap(custom_plot->xAxis, custom_plot->yAxis); - - // creating data item with single point - SessionModel model; - auto data_item = model.insertItem<Data2DItem>(); - const int nx = 3, ny = 2; - data_item->setAxes(FixedBinAxisItem::create(nx, 0.0, 3.0), - FixedBinAxisItem::create(ny, 0.0, 2.0)); - - // creating controller and point it to Data2DItem - Data2DPlotController controller(color_map); - controller.setItem(data_item); - - EXPECT_EQ(color_map->data()->keySize(), nx); - EXPECT_EQ(color_map->data()->valueSize(), ny); - EXPECT_EQ(color_map->data()->cell(0, 0), 0.0); - EXPECT_EQ(color_map->data()->cell(nx - 1, ny - 1), 0.0); - - // setting data points - std::vector<double> expected = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0}; - data_item->setContent(expected); - EXPECT_EQ(color_map->data()->cell(0, 0), 1.0); - EXPECT_EQ(color_map->data()->cell(nx - 1, ny - 1), 6.0); - - // Setting item to nullptr. Current convention is that QCPColorMap loses its data. - controller.setItem(nullptr); - EXPECT_EQ(color_map->data()->keySize(), 0); - EXPECT_EQ(color_map->data()->valueSize(), 0); -} - -//! Testing two colormap scenario. - -TEST_F(Data2DPlotControllerTest, twoDataItems) -{ - // creating custom plot and empty graph on it - auto custom_plot = std::make_unique<QCustomPlot>(); - auto color_map = new QCPColorMap(custom_plot->xAxis, custom_plot->yAxis); - - // creating data item with single point - SessionModel model; - auto data_item1 = model.insertItem<Data2DItem>(); - const int nx1 = 3, ny1 = 2; - std::vector<double> expected1 = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0}; - data_item1->setAxes(FixedBinAxisItem::create(nx1, 0.0, 3.0), - FixedBinAxisItem::create(ny1, 0.0, 2.0)); - data_item1->setContent(expected1); - auto data_item2 = model.insertItem<Data2DItem>(); - const int nx2 = 2, ny2 = 1; - std::vector<double> expected2 = {10.0, 20.0}; - data_item2->setAxes(FixedBinAxisItem::create(nx2, 0.0, 3.0), - FixedBinAxisItem::create(ny2, 0.0, 2.0)); - data_item2->setContent(expected2); - - // creating controller and point it to first Data2DItem - Data2DPlotController controller(color_map); - controller.setItem(data_item1); - - EXPECT_EQ(color_map->data()->keySize(), nx1); - EXPECT_EQ(color_map->data()->valueSize(), ny1); - EXPECT_EQ(color_map->data()->cell(0, 0), 1.0); - EXPECT_EQ(color_map->data()->cell(nx1 - 1, ny1 - 1), 6.0); - - // pointing controller to the second Data2DItem - controller.setItem(data_item2); - - EXPECT_EQ(color_map->data()->keySize(), nx2); - EXPECT_EQ(color_map->data()->valueSize(), ny2); - EXPECT_EQ(color_map->data()->cell(0, 0), 10.0); - EXPECT_EQ(color_map->data()->cell(nx2 - 1, ny2 - 1), 20.0); -} - -//! Testing data range. - -TEST_F(Data2DPlotControllerTest, dataRange) -{ - // creating custom plot and empty graph on it - auto custom_plot = std::make_unique<QCustomPlot>(); - auto color_map = new QCPColorMap(custom_plot->xAxis, custom_plot->yAxis); - - // creating data item with single point - SessionModel model; - auto data_item = model.insertItem<Data2DItem>(); - const int nx = 3, ny = 2; - data_item->setAxes(FixedBinAxisItem::create(nx, 0.0, 3.0), - FixedBinAxisItem::create(ny, 0.0, 2.0)); - std::vector<double> expected = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0}; - data_item->setContent(expected); - - // creating controller and point it to Data2DItem - Data2DPlotController controller(color_map); - controller.setItem(data_item); - - QSignalSpy spy(color_map, &QCPColorMap::dataRangeChanged); - - auto range = color_map->dataRange(); - EXPECT_EQ(spy.count(), 0); - EXPECT_EQ(range.lower, 1.0); - EXPECT_EQ(range.upper, 6.0); -} diff --git a/mvvm/tests/testview/graphplotcontroller.test.cpp b/mvvm/tests/testview/graphplotcontroller.test.cpp deleted file mode 100644 index cf3d9b023fc5708a56b3fe21e410adae0597cc14..0000000000000000000000000000000000000000 --- a/mvvm/tests/testview/graphplotcontroller.test.cpp +++ /dev/null @@ -1,267 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testview/graphplotcontroller.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "customplot_test_utils.h" -#include "google_test.h" -#include "mvvm/model/comboproperty.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/plotting/graphplotcontroller.h" -#include "mvvm/standarditems/axisitems.h" -#include "mvvm/standarditems/data1ditem.h" -#include "mvvm/standarditems/graphitem.h" -#include "mvvm/standarditems/plottableitems.h" -#include "qcustomplot.h" -#include <QSignalSpy> - -using namespace ModelView; - -//! Testing GraphPlotController. - -class GraphPlotControllerTest : public ::testing::Test { -public: - ~GraphPlotControllerTest(); -}; - -GraphPlotControllerTest::~GraphPlotControllerTest() = default; - -//! Initial state. - -TEST_F(GraphPlotControllerTest, initialState) -{ - auto custom_plot = std::make_unique<QCustomPlot>(); - GraphPlotController controller(custom_plot.get()); - EXPECT_EQ(controller.currentItem(), nullptr); - EXPECT_EQ(custom_plot->graphCount(), 0); -} - -//! Setting GraphItem with data and checking that plottable contains correct data. - -TEST_F(GraphPlotControllerTest, setItem) -{ - auto custom_plot = std::make_unique<QCustomPlot>(); - GraphPlotController controller(custom_plot.get()); - - // setup model and single data item in it - SessionModel model; - auto data_item = model.insertItem<Data1DItem>(); - data_item->setAxis<FixedBinAxisItem>(2, 0.0, 2.0); - std::vector<double> expected_centers = {0.5, 1.5}; - std::vector<double> expected_values = {42.0, 43.0}; - data_item->setValues(expected_values); - - // setup graph item - auto graph_item = model.insertItem<GraphItem>(); - graph_item->setDataItem(data_item); - - // initializing controller - controller.setItem(graph_item); - - // Checking resulting plottables - EXPECT_EQ(custom_plot->graphCount(), 1); - auto graph = custom_plot->graph(); - EXPECT_EQ(TestUtils::binCenters(graph), expected_centers); - EXPECT_EQ(TestUtils::binValues(graph), expected_values); - EXPECT_EQ(graph->pen().color(), QColor(Qt::black)); - EXPECT_EQ(graph->pen().style(), Qt::SolidLine); - EXPECT_EQ(graph->pen().width(), 1); -} - -TEST_F(GraphPlotControllerTest, changeGraphAppearance) -{ - auto custom_plot = std::make_unique<QCustomPlot>(); - GraphPlotController controller(custom_plot.get()); - - // setup model and single data item in it - SessionModel model; - auto data_item = model.insertItem<Data1DItem>(); - data_item->setAxis<FixedBinAxisItem>(2, 0.0, 2.0); - std::vector<double> expected_centers = {0.5, 1.5}; - std::vector<double> expected_values = {42.0, 43.0}; - data_item->setValues(expected_values); - - // setup graph item - auto graph_item = model.insertItem<GraphItem>(); - graph_item->setDataItem(data_item); - - // initializing controller - controller.setItem(graph_item); - - // changing appearance properties - auto pen_item = graph_item->penItem(); - pen_item->setProperty(PenItem::P_COLOR, QColor(Qt::red)); - - auto styleCombo = pen_item->property<ComboProperty>(PenItem::P_STYLE); - styleCombo.setCurrentIndex(2); - pen_item->setProperty(PenItem::P_STYLE, styleCombo); - pen_item->setProperty(PenItem::P_WIDTH, 2); - - auto graph = custom_plot->graph(); - EXPECT_EQ(graph->pen().color(), QColor(Qt::red)); - EXPECT_EQ(graph->pen().style(), Qt::DashLine); - EXPECT_EQ(graph->pen().width(), 2); -} - -//! Setting GraphItem with data and checking that plottable contains correct data. -//! Same as aboe, except that the data is based on PointWiseAxis. - -TEST_F(GraphPlotControllerTest, setPointwiseItem) -{ - auto custom_plot = std::make_unique<QCustomPlot>(); - GraphPlotController controller(custom_plot.get()); - - // setup model and single data item in it - const std::vector<double> expected_centers = {1.0, 2.0, 3.0}; - const std::vector<double> expected_values = {42.0, 43.0, 44.0}; - - SessionModel model; - auto data_item = model.insertItem<Data1DItem>(); - data_item->setAxis<PointwiseAxisItem>(expected_centers); - data_item->setValues(expected_values); - - // setup graph item - auto graph_item = model.insertItem<GraphItem>(); - auto pen_item = graph_item->penItem(); - pen_item->setProperty(PenItem::P_COLOR, QColor(Qt::red)); - graph_item->setDataItem(data_item); - - // initializing controller - controller.setItem(graph_item); - - // Checking resulting plottables - EXPECT_EQ(custom_plot->graphCount(), 1); - auto graph = custom_plot->graph(); - EXPECT_EQ(TestUtils::binCenters(graph), expected_centers); - EXPECT_EQ(TestUtils::binValues(graph), expected_values); - EXPECT_EQ(graph->pen().color(), QColor(Qt::red)); -} - -//! Setting data to graph after. - -TEST_F(GraphPlotControllerTest, setDataAfter) -{ - auto custom_plot = std::make_unique<QCustomPlot>(); - GraphPlotController controller(custom_plot.get()); - - SessionModel model; - auto graph_item = model.insertItem<GraphItem>(); - - controller.setItem(graph_item); - - // without data QCustomPlot has a graph without points - EXPECT_EQ(custom_plot->graphCount(), 1); - auto graph = custom_plot->graph(); - EXPECT_EQ(TestUtils::binCenters(graph), std::vector<double>()); - EXPECT_EQ(TestUtils::binValues(graph), std::vector<double>()); - - // setup Data1DItem and assign to GraphItem - auto data_item = model.insertItem<Data1DItem>(); - data_item->setAxis<FixedBinAxisItem>(2, 0.0, 2.0); - std::vector<double> expected_centers = {0.5, 1.5}; - std::vector<double> expected_values = {42.0, 43.0}; - data_item->setValues(expected_values); - - graph_item->setDataItem(data_item); - - // Checking resulting plottables - EXPECT_EQ(custom_plot->graphCount(), 1); - EXPECT_EQ(TestUtils::binCenters(graph), expected_centers); - EXPECT_EQ(TestUtils::binValues(graph), expected_values); -} - -//! Unlinking from Data1DItem or GraphItem. - -TEST_F(GraphPlotControllerTest, unlinkFromItem) -{ - auto custom_plot = std::make_unique<QCustomPlot>(); - GraphPlotController controller(custom_plot.get()); - - // setup model and single data item in it - SessionModel model; - auto data_item = model.insertItem<Data1DItem>(); - data_item->setAxis<FixedBinAxisItem>(2, 0.0, 2.0); - std::vector<double> expected_centers = {0.5, 1.5}; - std::vector<double> expected_values = {42.0, 43.0}; - data_item->setValues(expected_values); - - // setup graph item - auto graph_item = model.insertItem<GraphItem>(); - auto pen_item = graph_item->penItem(); - pen_item->setProperty(PenItem::P_COLOR, QColor(Qt::red)); - graph_item->setDataItem(data_item); - - // initializing controller - controller.setItem(graph_item); - - // unlinking from data item - graph_item->setDataItem(nullptr); - - // Checking resulting plottables - // Current convention is that graph stays intact, but points disappear. - EXPECT_EQ(custom_plot->graphCount(), 1); - auto graph = custom_plot->graph(); - EXPECT_EQ(TestUtils::binCenters(graph), std::vector<double>()); - EXPECT_EQ(TestUtils::binValues(graph), std::vector<double>()); - EXPECT_EQ(graph->pen().color(), QColor(Qt::red)); - - // unlinking from graph item should remove Graph from CustomPlot - controller.setItem(nullptr); - EXPECT_EQ(custom_plot->graphCount(), 0); -} - -//! Deletion of controller should lead to graph removal. - -TEST_F(GraphPlotControllerTest, controllerDelete) -{ - auto custom_plot = std::make_unique<QCustomPlot>(); - auto controller = std::make_unique<GraphPlotController>(custom_plot.get()); - - // setup model and single data item in it - SessionModel model; - auto data_item = model.insertItem<Data1DItem>(); - - // setup graph item - auto graph_item = model.insertItem<GraphItem>(); - graph_item->setDataItem(data_item); - - // initializing controller - controller->setItem(graph_item); - EXPECT_EQ(custom_plot->graphCount(), 1); - - // deleting controller should lead to graph removal - controller.reset(); - EXPECT_EQ(custom_plot->graphCount(), 0); -} - -//! Deletion of graphItem should lead to the dissapearance of graph. - -TEST_F(GraphPlotControllerTest, graphDelete) -{ - auto custom_plot = std::make_unique<QCustomPlot>(); - auto controller = std::make_unique<GraphPlotController>(custom_plot.get()); - - // setup model and single data item in it - SessionModel model; - auto data_item = model.insertItem<Data1DItem>(); - - // setup graph item - auto graph_item = model.insertItem<GraphItem>(); - graph_item->setDataItem(data_item); - - // initializing controller - controller->setItem(graph_item); - EXPECT_EQ(custom_plot->graphCount(), 1); - - model.removeItem(graph_item->parent(), graph_item->tagRow()); - EXPECT_EQ(custom_plot->graphCount(), 0); -} diff --git a/mvvm/tests/testview/graphviewportplotcontroller.test.cpp b/mvvm/tests/testview/graphviewportplotcontroller.test.cpp deleted file mode 100644 index 382348f3998a4c2275270a365de811aa755d0f20..0000000000000000000000000000000000000000 --- a/mvvm/tests/testview/graphviewportplotcontroller.test.cpp +++ /dev/null @@ -1,388 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testview/graphviewportplotcontroller.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "customplot_test_utils.h" -#include "google_test.h" -#include "mvvm/interfaces/undostackinterface.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/plotting/graphviewportplotcontroller.h" -#include "mvvm/standarditems/axisitems.h" -#include "mvvm/standarditems/data1ditem.h" -#include "mvvm/standarditems/graphitem.h" -#include "mvvm/standarditems/graphviewportitem.h" -#include "qcustomplot.h" - -using namespace ModelView; - -//! Testing GraphViewportPlotController. - -class GraphViewportPlotControllerTest : public ::testing::Test { -public: - ~GraphViewportPlotControllerTest(); -}; - -GraphViewportPlotControllerTest::~GraphViewportPlotControllerTest() = default; - -//! Initial state. - -TEST_F(GraphViewportPlotControllerTest, initialState) -{ - auto custom_plot = std::make_unique<QCustomPlot>(); - GraphViewportPlotController controller(custom_plot.get()); - EXPECT_EQ(custom_plot->graphCount(), 0); -} - -//! Check ::setItem() method when no graphs exist. - -TEST_F(GraphViewportPlotControllerTest, setItem) -{ - auto custom_plot = std::make_unique<QCustomPlot>(); - GraphViewportPlotController controller(custom_plot.get()); - - // setting up controller with viewport item - SessionModel model; - auto item = model.insertItem<GraphViewportItem>(); - controller.setItem(item); - - // no graphs in empty GraphViewportItem - EXPECT_EQ(custom_plot->graphCount(), 0); - - // axis should be [0, 1] as in defaule ViewportAxisItem - EXPECT_DOUBLE_EQ(custom_plot->xAxis->range().lower, 0.0); - EXPECT_DOUBLE_EQ(custom_plot->xAxis->range().upper, 1.0); - EXPECT_DOUBLE_EQ(custom_plot->yAxis->range().lower, 0.0); - EXPECT_DOUBLE_EQ(custom_plot->yAxis->range().upper, 1.0); -} - -//! Check ::setItem() method when ViewPortItem contains graphs. - -TEST_F(GraphViewportPlotControllerTest, addGraphAndSetItem) -{ - auto custom_plot = std::make_unique<QCustomPlot>(); - GraphViewportPlotController controller(custom_plot.get()); - - // setting up controller with viewport item - SessionModel model; - auto viewport_item = model.insertItem<GraphViewportItem>(); - - auto data_item = model.insertItem<Data1DItem>(); - const std::vector<double> expected_values = {1.0, 2.0, 3.0}; - const std::vector<double> expected_centers = {0.5, 1.5, 2.5}; - data_item->setAxis<FixedBinAxisItem>(3, 0.0, 3.0); - data_item->setValues(expected_values); - - auto graph_item = model.insertItem<GraphItem>(viewport_item); - graph_item->setDataItem(data_item); - controller.setItem(viewport_item); - - // single graph on custom plot. - EXPECT_EQ(custom_plot->graphCount(), 1); - - // QCustomPlot axis should correspond to - EXPECT_DOUBLE_EQ(custom_plot->xAxis->range().lower, expected_centers[0]); - EXPECT_DOUBLE_EQ(custom_plot->xAxis->range().upper, expected_centers[2]); - EXPECT_DOUBLE_EQ(custom_plot->yAxis->range().lower, expected_values[0]); - EXPECT_DOUBLE_EQ(custom_plot->yAxis->range().upper, expected_values[2]); -} - -//! Checks consequitive graph adding/removal - -TEST_F(GraphViewportPlotControllerTest, addAndRemoveGraphs) -{ - auto custom_plot = std::make_unique<QCustomPlot>(); - GraphViewportPlotController controller(custom_plot.get()); - - // setting up controller with viewport item - SessionModel model; - auto viewport_item = model.insertItem<GraphViewportItem>(); - controller.setItem(viewport_item); - - // No graphs yet. - EXPECT_EQ(custom_plot->graphCount(), 0); - - // Populating with data items - auto data1 = model.insertItem<Data1DItem>(); - const std::vector<double> expected_values1 = {1.0, 2.0, 3.0}; - const std::vector<double> expected_centers = {0.5, 1.5, 2.5}; - data1->setAxis<FixedBinAxisItem>(3, 0.0, 3.0); - data1->setValues(expected_values1); - - auto data2 = model.insertItem<Data1DItem>(); - const std::vector<double> expected_values2 = {4.0, 5.0, 6.0}; - data2->setAxis<FixedBinAxisItem>(3, 0.0, 3.0); - data2->setValues(expected_values2); - - // adding graph item to viewport - auto graph_item1 = model.insertItem<GraphItem>(viewport_item, {"", 0}); - - // check that QCustomPlot knows about graph - EXPECT_EQ(custom_plot->graphCount(), 1); - - graph_item1->setDataItem(data1); - - // check that QCustomPlot knows about graph - EXPECT_EQ(custom_plot->graphCount(), 1); - - // adding secong graph - auto graph_item2 = model.insertItem<GraphItem>(viewport_item, {"", 1}); - graph_item2->setDataItem(data2); - - // check that QCustomPlot knows about two graph - EXPECT_EQ(custom_plot->graphCount(), 2); - - // Checking that viewport min, max adjusted to both graphs when manually call update_viewport() - viewport_item->setViewportToContent(); - EXPECT_DOUBLE_EQ(custom_plot->xAxis->range().lower, expected_centers[0]); - EXPECT_DOUBLE_EQ(custom_plot->xAxis->range().upper, expected_centers[2]); - EXPECT_DOUBLE_EQ(custom_plot->yAxis->range().lower, expected_values1[0]); - EXPECT_DOUBLE_EQ(custom_plot->yAxis->range().upper, expected_values2[2]); - - // removing one GraphItem - model.removeItem(viewport_item, {ViewportItem::T_ITEMS, 1}); - - // only single graph should remain on QCustomPlot3 - EXPECT_EQ(custom_plot->graphCount(), 1); -} - -//! Checks consequitive graph adding/removal - -TEST_F(GraphViewportPlotControllerTest, addMoreGraphs) -{ - auto custom_plot = std::make_unique<QCustomPlot>(); - GraphViewportPlotController controller(custom_plot.get()); - - // setting up controller with viewport item - SessionModel model; - auto viewport_item = model.insertItem<GraphViewportItem>(); - controller.setItem(viewport_item); - - // No graphs yet. - EXPECT_EQ(custom_plot->graphCount(), 0); - - // adding graph item to viewport - model.insertItem<GraphItem>(viewport_item); - EXPECT_EQ(custom_plot->graphCount(), 1); - - model.insertItem<GraphItem>(viewport_item); - EXPECT_EQ(custom_plot->graphCount(), 2); - - model.insertItem<GraphItem>(viewport_item); - EXPECT_EQ(custom_plot->graphCount(), 3); -} - -//! Checks The fucntionality of selection in the viewport - -TEST_F(GraphViewportPlotControllerTest, checkVisible) -{ - // Convenience - struct FindVisible { - static std::vector<QCPAbstractPlottable*> findVisible(const QCustomPlot* custom_plot) - { - std::vector<QCPAbstractPlottable*> output; - for (int i = 0; i < custom_plot->graphCount(); ++i) { - if (custom_plot->graph(i)->visible()) - output.push_back(custom_plot->graph(i)); - } - return output; - } - }; - - // custom plot setup - auto custom_plot = std::make_unique<QCustomPlot>(); - GraphViewportPlotController controller(custom_plot.get()); - - // setting up controller with viewport item - SessionModel model; - auto viewport_item = model.insertItem<GraphViewportItem>(); - controller.setItem(viewport_item); - - // adding graph item to viewport - auto first_plot = model.insertItem<GraphItem>(viewport_item); - auto second_plot = model.insertItem<GraphItem>(viewport_item); - auto third_plot = model.insertItem<GraphItem>(viewport_item); - EXPECT_EQ(custom_plot->graphCount(), 3); - - viewport_item->setVisible(std::vector<GraphItem*>{first_plot}); - EXPECT_EQ(FindVisible::findVisible(custom_plot.get()).size(), 1); - - viewport_item->setVisible(std::vector<GraphItem*>{second_plot, third_plot}); - EXPECT_EQ(FindVisible::findVisible(custom_plot.get()).size(), 2); - - viewport_item->setAllVisible(); - EXPECT_EQ(FindVisible::findVisible(custom_plot.get()).size(), 3); -} - -//! Two GraphViewportItem's and switch between them. - -TEST_F(GraphViewportPlotControllerTest, switchBetweenTwoViewports) -{ - auto custom_plot = std::make_unique<QCustomPlot>(); - GraphViewportPlotController controller(custom_plot.get()); - - // setting up controller with viewport item - SessionModel model; - auto viewport_item0 = model.insertItem<GraphViewportItem>(); - auto viewport_item1 = model.insertItem<GraphViewportItem>(); - - auto data_item = model.insertItem<Data1DItem>(); - const std::vector<double> expected_values = {1.0, 2.0, 3.0}; - const std::vector<double> expected_centers = {0.5, 1.5, 2.5}; - data_item->setAxis<FixedBinAxisItem>(3, 0.0, 3.0); - data_item->setValues(expected_values); - - auto graph_item = model.insertItem<GraphItem>(viewport_item0); - graph_item->setDataItem(data_item); - controller.setItem(viewport_item0); - - // single graph on custom plot. - EXPECT_EQ(custom_plot->graphCount(), 1); - - // switch to second (empty) viewport, QCustomPlot should have no graphs - controller.setItem(viewport_item1); - EXPECT_EQ(custom_plot->graphCount(), 0); -} - -//! Adding graph, then undo, then redo again. - -TEST_F(GraphViewportPlotControllerTest, addGraphUndoRedo) -{ - auto custom_plot = std::make_unique<QCustomPlot>(); - GraphViewportPlotController controller(custom_plot.get()); - - // setting up controller with viewport item - SessionModel model; - - auto viewport_item = model.insertItem<GraphViewportItem>(); - controller.setItem(viewport_item); - - // No graphs yet. - EXPECT_EQ(custom_plot->graphCount(), 0); - - // Populating with data items - auto data1 = model.insertItem<Data1DItem>(); - const std::vector<double> expected_values = {1.0, 2.0, 3.0}; - const std::vector<double> expected_centers = {0.5, 1.5, 2.5}; - data1->setAxis<FixedBinAxisItem>(3, 0.0, 3.0); - data1->setValues(expected_values); - - // beginning of our undo/redo story - model.setUndoRedoEnabled(true); - EXPECT_EQ(model.undoStack()->index(), 0); - EXPECT_EQ(model.undoStack()->count(), 0); - - // adding graph item to viewport - auto graph_item = model.insertItem<GraphItem>(viewport_item, {"", 0}); - EXPECT_EQ(model.undoStack()->index(), 1); - EXPECT_EQ(model.undoStack()->count(), 1); - - // assigning data to graph - graph_item->setDataItem(data1); - EXPECT_EQ(model.undoStack()->index(), 2); - EXPECT_EQ(model.undoStack()->count(), 2); - - // validating graph in custom plot - EXPECT_EQ(custom_plot->graphCount(), 1); - EXPECT_EQ(TestUtils::binCenters(custom_plot->graph()), expected_centers); - EXPECT_EQ(TestUtils::binValues(custom_plot->graph()), expected_values); - - // undoing data assignment - model.undoStack()->undo(); - EXPECT_EQ(model.undoStack()->index(), 1); - EXPECT_EQ(model.undoStack()->count(), 2); - - // graph is still there, but empty - EXPECT_EQ(custom_plot->graphCount(), 1); - EXPECT_EQ(TestUtils::binCenters(custom_plot->graph()), std::vector<double>()); - EXPECT_EQ(TestUtils::binValues(custom_plot->graph()), std::vector<double>()); - EXPECT_EQ(graph_item->dataItem(), nullptr); - - // redoing data assignment - model.undoStack()->redo(); - EXPECT_EQ(model.undoStack()->index(), 2); - EXPECT_EQ(model.undoStack()->count(), 2); - - // graph is complete again - EXPECT_EQ(graph_item->dataItem(), data1); - EXPECT_EQ(custom_plot->graphCount(), 1); - EXPECT_EQ(TestUtils::binCenters(custom_plot->graph()), expected_centers); - EXPECT_EQ(TestUtils::binValues(custom_plot->graph()), expected_values); -} - -//! Adding graph together with data in macro, then undo, then redo again. - -TEST_F(GraphViewportPlotControllerTest, addGraphUndoRedoMacro) -{ - auto custom_plot = std::make_unique<QCustomPlot>(); - GraphViewportPlotController controller(custom_plot.get()); - - // setting up controller with viewport item - SessionModel model; - - auto viewport_item = model.insertItem<GraphViewportItem>(); - controller.setItem(viewport_item); - - // No graphs yet. - EXPECT_EQ(custom_plot->graphCount(), 0); - - // beginning of our undo/redo story - model.setUndoRedoEnabled(true); - EXPECT_EQ(model.undoStack()->index(), 0); - EXPECT_EQ(model.undoStack()->count(), 0); - - // adding data and graph as macro - model.undoStack()->beginMacro("addGraph"); - // Populating with data items - auto data1 = model.insertItem<Data1DItem>(); - const std::vector<double> expected_values = {1.0, 2.0, 3.0}; - const std::vector<double> expected_centers = {0.5, 1.5, 2.5}; - data1->setAxis<FixedBinAxisItem>(3, 0.0, 3.0); - data1->setValues(expected_values); - auto data_identifier = data1->identifier(); - // adding graph item to viewport - auto graph_item = model.insertItem<GraphItem>(viewport_item, {"", 0}); - // assigning data to graph - graph_item->setDataItem(data1); - model.undoStack()->endMacro(); - - EXPECT_EQ(viewport_item->graphItems()[0]->dataItem(), model.topItem<Data1DItem>()); - - EXPECT_EQ(model.undoStack()->index(), 1); - EXPECT_EQ(model.undoStack()->count(), 1); - - // validating graph in custom plot - EXPECT_EQ(custom_plot->graphCount(), 1); - EXPECT_EQ(TestUtils::binCenters(custom_plot->graph()), expected_centers); - EXPECT_EQ(TestUtils::binValues(custom_plot->graph()), expected_values); - - // undoing macro - model.undoStack()->undo(); - EXPECT_EQ(model.undoStack()->index(), 0); - EXPECT_EQ(model.undoStack()->count(), 1); - - // no graph and no items - EXPECT_EQ(viewport_item->graphItems().size(), 0); - EXPECT_EQ(model.topItem<Data1DItem>(), nullptr); - EXPECT_EQ(custom_plot->graphCount(), 0); - - // redoing macro - model.undoStack()->redo(); - EXPECT_EQ(custom_plot->graphCount(), 1); - EXPECT_EQ(viewport_item->graphItems().size(), 1); - - EXPECT_EQ(model.topItem<Data1DItem>()->identifier(), data_identifier); - EXPECT_EQ(viewport_item->graphItems()[0]->dataItem(), model.topItem<Data1DItem>()); - - EXPECT_EQ(TestUtils::binCenters(custom_plot->graph()), expected_centers); - EXPECT_EQ(TestUtils::binValues(custom_plot->graph()), expected_values); -} diff --git a/mvvm/tests/testview/pencontroller.test.cpp b/mvvm/tests/testview/pencontroller.test.cpp deleted file mode 100644 index b3203981880bcb92df23d1b4f9cb571bd98fabed..0000000000000000000000000000000000000000 --- a/mvvm/tests/testview/pencontroller.test.cpp +++ /dev/null @@ -1,109 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testview/pencontroller.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "customplot_test_utils.h" -#include "google_test.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/plotting/pencontroller.h" -#include "mvvm/standarditems/plottableitems.h" -#include "qcustomplot.h" - -#include <stdexcept> - -using namespace ModelView; - -//! Testing PenController. - -class PenControllerTest : public ::testing::Test { -public: - ~PenControllerTest(); -}; - -PenControllerTest::~PenControllerTest() = default; - -//! Initial state. - -TEST_F(PenControllerTest, initialState) -{ - // Constructor accept valid QCPGraph - EXPECT_THROW(PenController(nullptr), std::runtime_error); - - auto custom_plot = std::make_unique<QCustomPlot>(); - auto graph = custom_plot->addGraph(); - - PenController controller(graph); - EXPECT_EQ(controller.currentItem(), nullptr); -} - -TEST_F(PenControllerTest, graphItemInInitialState) -{ - auto custom_plot = std::make_unique<QCustomPlot>(); - auto graph = custom_plot->addGraph(); - - PenController controller(graph); - - SessionModel model; - auto pen_item = model.insertItem<PenItem>(); - controller.setItem(pen_item); - - EXPECT_EQ(controller.currentItem(), pen_item); - - // parameters of graph in QCustomPlot - EXPECT_EQ(graph->pen().color(), QColor(Qt::black)); - EXPECT_EQ(graph->pen().style(), Qt::SolidLine); - EXPECT_EQ(graph->pen().width(), 1); -} - -TEST_F(PenControllerTest, setPenSelected) -{ - auto custom_plot = std::make_unique<QCustomPlot>(); - auto graph = custom_plot->addGraph(); - - PenController controller(graph); - - SessionModel model; - auto pen_item = model.insertItem<PenItem>(); - controller.setItem(pen_item); - - pen_item->setSelected(true); - - // parameters of graph in QCustomPlot - EXPECT_EQ(graph->pen().color(), QColor(Qt::black)); - EXPECT_EQ(graph->pen().style(), Qt::DashLine); - EXPECT_EQ(graph->pen().width(), 1); -} - -TEST_F(PenControllerTest, setColorAndWidth) -{ - auto custom_plot = std::make_unique<QCustomPlot>(); - auto graph = custom_plot->addGraph(); - - PenController controller(graph); - - SessionModel model; - auto pen_item = model.insertItem<PenItem>(); - controller.setItem(pen_item); - - pen_item->setProperty(PenItem::P_WIDTH, 2); - pen_item->setProperty(PenItem::P_COLOR, QColor(Qt::red)); - - // parameters of graph in QCustomPlot - EXPECT_EQ(graph->pen().color(), QColor(Qt::red)); - EXPECT_EQ(graph->pen().style(), Qt::SolidLine); - EXPECT_EQ(graph->pen().width(), 2); - - // set color via named color machinery - pen_item->setNamedColor("azure"); - EXPECT_EQ(graph->pen().color().name(), QString("#f0ffff")); -} diff --git a/mvvm/tests/testview/propertyflatview.test.cpp b/mvvm/tests/testview/propertyflatview.test.cpp deleted file mode 100644 index a134258cdcc270841ba58112bf50d046002bfc1a..0000000000000000000000000000000000000000 --- a/mvvm/tests/testview/propertyflatview.test.cpp +++ /dev/null @@ -1,86 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testview/propertyflatview.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/standarditems/vectoritem.h" -#include "mvvm/widgets/propertyflatview.h" -#include "toyitems.h" -#include "toymodel.h" -#include <QGridLayout> - -using namespace ModelView; - -//! Tests of PropertyFlatView class. - -class PropertyFlatViewTest : public ::testing::Test { -public: - ~PropertyFlatViewTest(); - - //! Returns vector representing enable status of widgets in layout. - - std::vector<int> enable_status(PropertyFlatView& flat_view) - { - std::vector<int> result; - auto layout = flat_view.findChild<QGridLayout*>(); - for (int row = 0; row < layout->rowCount(); ++row) - for (int col = 0; col < layout->columnCount(); ++col) - result.push_back( - static_cast<int>(layout->itemAtPosition(row, col)->widget()->isEnabled())); - return result; - } -}; - -PropertyFlatViewTest::~PropertyFlatViewTest() = default; - -TEST_F(PropertyFlatViewTest, layoutForVector) -{ - SessionModel model; - auto vector_item = model.insertItem<VectorItem>(); - - PropertyFlatView flat_view; - flat_view.setItem(vector_item); - - auto layout = flat_view.findChild<QGridLayout*>(); - ASSERT_TRUE(layout != nullptr); - - EXPECT_EQ(layout->rowCount(), 3); - EXPECT_EQ(layout->columnCount(), 2); - std::vector<int> expected_enabled = {1, 1, 1, 1, 1, 1}; -} - -TEST_F(PropertyFlatViewTest, appearanceForItem) -{ - SessionModel model; - auto vector_item = model.insertItem<VectorItem>(); - auto x_item = vector_item->getItem(VectorItem::P_X); - - x_item->setEnabled(false); - - PropertyFlatView flat_view; - flat_view.setItem(vector_item); - - auto layout = flat_view.findChild<QGridLayout*>(); - ASSERT_TRUE(layout != nullptr); - - EXPECT_EQ(layout->rowCount(), 3); - EXPECT_EQ(layout->columnCount(), 2); - std::vector<int> expected_enabled = {0, 0, 1, 1, 1, 1}; - EXPECT_EQ(enable_status(flat_view), expected_enabled); - - // enabling x item - x_item->setEnabled(true); - expected_enabled = {1, 1, 1, 1, 1, 1}; - EXPECT_EQ(enable_status(flat_view), expected_enabled); -} diff --git a/mvvm/tests/testview/viewportaxisplotcontroller.test.cpp b/mvvm/tests/testview/viewportaxisplotcontroller.test.cpp deleted file mode 100644 index 3b89d72980f089881c4ec608a994fb7c0ee90273..0000000000000000000000000000000000000000 --- a/mvvm/tests/testview/viewportaxisplotcontroller.test.cpp +++ /dev/null @@ -1,435 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testview/viewportaxisplotcontroller.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "customplot_test_utils.h" -#include "google_test.h" -#include "mockwidgets.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/plotting/viewportaxisplotcontroller.h" -#include "mvvm/standarditems/axisitems.h" -#include "mvvm/standarditems/plottableitems.h" -#include "qcustomplot.h" -#include <QSignalSpy> - -using namespace ModelView; -using ::testing::_; - -//! Testing AxisPlotControllers. - -class ViewportAxisPlotControllerTest : public ::testing::Test { -public: - ~ViewportAxisPlotControllerTest(); - - std::unique_ptr<QSignalSpy> createSpy(QCPAxis* axis) - { - return std::make_unique<QSignalSpy>( - axis, static_cast<void (QCPAxis::*)(const QCPRange&)>(&QCPAxis::rangeChanged)); - } - - std::unique_ptr<QSignalSpy> createSpy2(QCPAxis* axis) - { - return std::make_unique<QSignalSpy>( - axis, static_cast<void (QCPAxis::*)(const QCPRange&, const QCPRange&)>( - &QCPAxis::rangeChanged)); - } -}; - -ViewportAxisPlotControllerTest::~ViewportAxisPlotControllerTest() = default; - -//! Initial state. - -TEST_F(ViewportAxisPlotControllerTest, initialState) -{ - auto custom_plot = std::make_unique<QCustomPlot>(); - - auto axis = custom_plot->xAxis; - - // checking initial defaults - const double customplot_default_lower(0.0), customplot_default_upper(5.0); - EXPECT_EQ(axis->range().lower, customplot_default_lower); - EXPECT_EQ(axis->range().upper, customplot_default_upper); - - // controller shouldn''t change axis range - ViewportAxisPlotController controller(axis); - EXPECT_EQ(axis->range().lower, customplot_default_lower); - EXPECT_EQ(axis->range().upper, customplot_default_upper); - - // checking axis signaling - auto xChanged = createSpy(custom_plot->xAxis); - auto yChanged = createSpy(custom_plot->yAxis); - - // changing range of axis - custom_plot->xAxis->setRangeLower(1.0); - - // checking that QCPaxis properly emiting signals - EXPECT_EQ(xChanged->count(), 1); - EXPECT_EQ(yChanged->count(), 0); -} - -//! Controller subscribed to ViewportAxisItem. -//! Checking that QCPAxis get same parameters as in AxisItem. - -TEST_F(ViewportAxisPlotControllerTest, setViewportAxisItem) -{ - auto custom_plot = std::make_unique<QCustomPlot>(); - const double expected_min = 1.0; - const double expected_max = 2.0; - - // creating the model with single ViewportAxisItem - SessionModel model; - auto axisItem = model.insertItem<ViewportAxisItem>(); - axisItem->setProperty(ViewportAxisItem::P_MIN, expected_min); - axisItem->setProperty(ViewportAxisItem::P_MAX, expected_max); - - // setting up QCustomPlot and item controller. - ASSERT_TRUE(custom_plot->xAxis != nullptr); - ViewportAxisPlotController controller(custom_plot->xAxis); - - auto prev_y_range = custom_plot->yAxis->range(); - auto xChanged = createSpy(custom_plot->xAxis); - auto yChanged = createSpy(custom_plot->yAxis); - - // Subscribtion to ViewportAxisItem should change QCPAxis range for X. - controller.setItem(axisItem); - - EXPECT_EQ(custom_plot->xAxis->range().lower, expected_min); - EXPECT_EQ(custom_plot->xAxis->range().upper, expected_max); - EXPECT_EQ(xChanged->count(), 1); - EXPECT_EQ(yChanged->count(), 0); - - // Range for QCPAxis y-axis should stay the same. - EXPECT_EQ(custom_plot->yAxis->range(), prev_y_range); -} - -//! Controller subscribed to ViewportAxisItem. -//! Change QCPAxis and check that ViewportAxisItem got new values. - -TEST_F(ViewportAxisPlotControllerTest, changeQCPAxis) -{ - auto custom_plot = std::make_unique<QCustomPlot>(); - - // creating the model with single ViewportAxisItem - SessionModel model; - auto axisItem = model.insertItem<ViewportAxisItem>(); - axisItem->setProperty(ViewportAxisItem::P_MIN, 42.0); - axisItem->setProperty(ViewportAxisItem::P_MAX, 42.1); - - // setting up QCustomPlot and item controller. - const double expected_min = 1.0; - const double expected_max = 2.0; - auto xChanged = createSpy(custom_plot->xAxis); - auto yChanged = createSpy(custom_plot->yAxis); - - // Setting up controller. - ViewportAxisPlotController controller(custom_plot->xAxis); - controller.setItem(axisItem); - - EXPECT_EQ(xChanged->count(), 1); - EXPECT_EQ(yChanged->count(), 0); - - // Changing QCPAxis - custom_plot->xAxis->setRange(expected_min, expected_max); - EXPECT_EQ(xChanged->count(), 2); - EXPECT_EQ(yChanged->count(), 0); - - // Check changed properties in ViewportAxisItem - EXPECT_EQ(axisItem->property<double>(ViewportAxisItem::P_MIN), expected_min); - EXPECT_EQ(axisItem->property<double>(ViewportAxisItem::P_MAX), expected_max); -} - -//! Controller subscribed to ViewportAxisItem. -//! Change ViewportAxisItem and check that QCPAxis got new values. - -TEST_F(ViewportAxisPlotControllerTest, changeViewportAxisItem) -{ - auto custom_plot = std::make_unique<QCustomPlot>(); - - // creating the model with single ViewportAxisItem - SessionModel model; - auto axisItem = model.insertItem<ViewportAxisItem>(); - axisItem->setProperty(ViewportAxisItem::P_MIN, 42.0); - axisItem->setProperty(ViewportAxisItem::P_MAX, 42.1); - - // setting up QCustomPlot and item controller. - ViewportAxisPlotController controller(custom_plot->xAxis); - controller.setItem(axisItem); - auto xChanged = createSpy(custom_plot->xAxis); - auto yChanged = createSpy(custom_plot->yAxis); - - // changing values - const double expected_min = 1.0; - const double expected_max = 2.0; - axisItem->setProperty(ViewportAxisItem::P_MIN, expected_min); - axisItem->setProperty(ViewportAxisItem::P_MAX, expected_max); - - // Checking QCPAxis - EXPECT_EQ(xChanged->count(), 2); - EXPECT_EQ(yChanged->count(), 0); - EXPECT_EQ(custom_plot->xAxis->range().lower, expected_min); - EXPECT_EQ(custom_plot->xAxis->range().upper, expected_max); -} - -//! Controller subscribed to ViewportAxisItem. -//! Change ViewportAxisItem and check that QCPAxis got new values. -//! Check correctness of signals issued by QCPAxisItem. - -TEST_F(ViewportAxisPlotControllerTest, changeViewportAxisItemSignaling) -{ - auto custom_plot = std::make_unique<QCustomPlot>(); - - // creating the model with single ViewportAxisItem - SessionModel model; - auto axisItem = model.insertItem<ViewportAxisItem>(); - axisItem->setProperty(ViewportAxisItem::P_MIN, 1.0); - axisItem->setProperty(ViewportAxisItem::P_MAX, 2.0); - - // setting up QCustomPlot and item controller. - ViewportAxisPlotController controller(custom_plot->xAxis); - controller.setItem(axisItem); - - // initial condition - EXPECT_EQ(custom_plot->xAxis->range().lower, 1.0); - EXPECT_EQ(custom_plot->xAxis->range().upper, 2.0); - - auto rangeChanged = createSpy(custom_plot->xAxis); - auto rangeChanged2 = createSpy2(custom_plot->xAxis); - - // making a change - const double expected_max = 20.0; - axisItem->setProperty(ViewportAxisItem::P_MAX, expected_max); - - // Checking QCPAxis - EXPECT_EQ(rangeChanged->count(), 1); - EXPECT_EQ(rangeChanged2->count(), 1); - EXPECT_EQ(custom_plot->xAxis->range().lower, 1.0); - EXPECT_EQ(custom_plot->xAxis->range().upper, expected_max); - - QList<QVariant> arguments = rangeChanged->takeFirst(); - EXPECT_EQ(arguments.size(), 1); - auto reportedRange = arguments.at(0).value<QCPRange>(); - EXPECT_EQ(reportedRange.lower, 1.0); - EXPECT_EQ(reportedRange.upper, 20.0); - - arguments = rangeChanged2->takeFirst(); - EXPECT_EQ(arguments.size(), 2); - auto newRange = arguments.at(0).value<QCPRange>(); - auto oldRange = arguments.at(1).value<QCPRange>(); - EXPECT_EQ(newRange.lower, 1.0); - EXPECT_EQ(newRange.upper, 20.0); - EXPECT_EQ(oldRange.lower, 1.0); - EXPECT_EQ(oldRange.upper, 2.0); -} - -//! Controller subscribed to ViewportAxisItem. -//! Change ViewportAxisItem and check that QCPAxis got new values. -//! Check correctness that there is not extra looping and item doesn't start changing many times - -TEST_F(ViewportAxisPlotControllerTest, changeViewportAxisItemMapping) -{ - auto custom_plot = std::make_unique<QCustomPlot>(); - - // creating the model with single ViewportAxisItem - SessionModel model; - auto axisItem = model.insertItem<ViewportAxisItem>(); - axisItem->setProperty(ViewportAxisItem::P_MIN, 1.0); - axisItem->setProperty(ViewportAxisItem::P_MAX, 2.0); - - // setting up QCustomPlot and item controller. - ViewportAxisPlotController controller(custom_plot->xAxis); - controller.setItem(axisItem); - - MockWidgetForItem widget(axisItem); - EXPECT_CALL(widget, onDataChange(_, _)).Times(0); - EXPECT_CALL(widget, onPropertyChange(axisItem, ViewportAxisItem::P_MAX)).Times(1); - EXPECT_CALL(widget, onChildPropertyChange(_, _)).Times(0); - EXPECT_CALL(widget, onItemInserted(_, _)).Times(0); - EXPECT_CALL(widget, onAboutToRemoveItem(_, _)).Times(0); - - // making a change - const double expected_max = 20.0; - axisItem->setProperty(ViewportAxisItem::P_MAX, expected_max); - - EXPECT_EQ(custom_plot->xAxis->range().lower, 1.0); - EXPECT_EQ(custom_plot->xAxis->range().upper, expected_max); -} - -//! Set ViewportAxisItem logz, subscribe controller and check that QCPAxis has it. - -TEST_F(ViewportAxisPlotControllerTest, viewportLogz) -{ - auto custom_plot = std::make_unique<QCustomPlot>(); - - // creating the model with single ViewportAxisItem - SessionModel model; - auto axisItem = model.insertItem<ViewportAxisItem>(); - axisItem->setProperty(ViewportAxisItem::P_IS_LOG, true); - - // setting up QCustomPlot and item controller. - auto qcp_axis = custom_plot->xAxis; - ViewportAxisPlotController controller(qcp_axis); - controller.setItem(axisItem); - - // QCPAxis should switch to logarithmic - EXPECT_EQ(qcp_axis->scaleType(), QCPAxis::stLogarithmic); -} - -//! Controller subscribed to ViewportAxisItem. -//! Change ViewportAxisItem logz and check that QCPAxis got new values. - -TEST_F(ViewportAxisPlotControllerTest, changeViewportLogz) -{ - auto custom_plot = std::make_unique<QCustomPlot>(); - - // creating the model with single ViewportAxisItem - SessionModel model; - auto axisItem = model.insertItem<ViewportAxisItem>(); - - // setting up QCustomPlot and item controller. - auto qcp_axis = custom_plot->xAxis; - ViewportAxisPlotController controller(qcp_axis); - controller.setItem(axisItem); - - // initial linear scale of axis - EXPECT_EQ(qcp_axis->scaleType(), QCPAxis::stLinear); - - // changing scale - axisItem->setProperty(ViewportAxisItem::P_IS_LOG, true); - - // QCPAxis should switch to logarithmic - EXPECT_EQ(qcp_axis->scaleType(), QCPAxis::stLogarithmic); -} - -//! Controller subscribed to ViewportAxisItem. -//! Change ViewportAxisItem and check that QCPAxis got new values. -//! Same test as before, only QCPAxis y-axis checked. - -TEST_F(ViewportAxisPlotControllerTest, changeViewportAxisItemYCase) -{ - auto custom_plot = std::make_unique<QCustomPlot>(); - - // creating the model with single ViewportAxisItem - SessionModel model; - auto axisItem = model.insertItem<ViewportAxisItem>(); - axisItem->setProperty(ViewportAxisItem::P_MIN, 42.0); - axisItem->setProperty(ViewportAxisItem::P_MAX, 42.1); - - // setting up QCustomPlot and item controller. - ViewportAxisPlotController controller(custom_plot->yAxis); - controller.setItem(axisItem); - auto xChanged = createSpy(custom_plot->xAxis); - auto yChanged = createSpy(custom_plot->yAxis); - - // changing values - const double expected_min = 1.0; - const double expected_max = 2.0; - axisItem->setProperty(ViewportAxisItem::P_MIN, expected_min); - axisItem->setProperty(ViewportAxisItem::P_MAX, expected_max); - - // Checking QCPAxis - EXPECT_EQ(xChanged->count(), 0); - EXPECT_EQ(yChanged->count(), 2); - EXPECT_EQ(custom_plot->yAxis->range().lower, expected_min); - EXPECT_EQ(custom_plot->yAxis->range().upper, expected_max); -} - -//! Model with two AxisItem's. Controller first is subscribed to one item, then to another. - -TEST_F(ViewportAxisPlotControllerTest, oneControllerTwoAxisItems) -{ - auto custom_plot = std::make_unique<QCustomPlot>(); - - // creating the model with single ViewportAxisItem - SessionModel model; - auto axis_item0 = model.insertItem<ViewportAxisItem>(); - axis_item0->setProperty(ViewportAxisItem::P_MIN, 1.0); - axis_item0->setProperty(ViewportAxisItem::P_MAX, 2.0); - - auto axis_item1 = model.insertItem<ViewportAxisItem>(); - axis_item1->setProperty(ViewportAxisItem::P_MIN, 10.0); - axis_item1->setProperty(ViewportAxisItem::P_MAX, 20.0); - - // setting up QCustomPlot and item controller. - auto controller = std::make_unique<ViewportAxisPlotController>(custom_plot->xAxis); - controller->setItem(axis_item0); - auto xChanged = createSpy(custom_plot->xAxis); - auto yChanged = createSpy(custom_plot->yAxis); - - // initial axis status - EXPECT_EQ(axis_item0->property<double>(ViewportAxisItem::P_MIN), - custom_plot->xAxis->range().lower); - EXPECT_EQ(axis_item0->property<double>(ViewportAxisItem::P_MAX), - custom_plot->xAxis->range().upper); - - // switching to second axis - controller->setItem(axis_item1); - - EXPECT_EQ(xChanged->count(), 1); - EXPECT_EQ(yChanged->count(), 0); - - EXPECT_EQ(axis_item1->property<double>(ViewportAxisItem::P_MIN), - custom_plot->xAxis->range().lower); - EXPECT_EQ(axis_item1->property<double>(ViewportAxisItem::P_MAX), - custom_plot->xAxis->range().upper); - - // changing QCPAxis - const double expected_min = 100.0; - const double expected_max = 200.0; - custom_plot->xAxis->setRange(expected_min, expected_max); - - // previous axis should still have original values - EXPECT_EQ(axis_item0->property<double>(ViewportAxisItem::P_MIN), 1.0); - EXPECT_EQ(axis_item0->property<double>(ViewportAxisItem::P_MAX), 2.0); - - // second axis should get values from QCPAxis - EXPECT_EQ(axis_item1->property<double>(ViewportAxisItem::P_MIN), expected_min); - EXPECT_EQ(axis_item1->property<double>(ViewportAxisItem::P_MAX), expected_max); - - // removing axes from the model - model.removeItem(model.rootItem(), {"", 0}); - model.removeItem(model.rootItem(), {"", 0}); - EXPECT_EQ(model.rootItem()->childrenCount(), 0); - - // no UB should follow (valgrind will tell us) - custom_plot->xAxis->setRange(1.0, 2.0); - - // destroying controller, no UB - controller.reset(); - custom_plot->xAxis->setRange(2.0, 3.0); -} - -//! Controller subscribed to ViewportAxisItem. -//! Change ViewportAxisItem title and check that QCPAxis got new values. - -TEST_F(ViewportAxisPlotControllerTest, changeAxisTitle) -{ - auto custom_plot = std::make_unique<QCustomPlot>(); - - // creating the model with single ViewportAxisItem - SessionModel model; - auto axisItem = model.insertItem<ViewportAxisItem>(); - - // setting up QCustomPlot and item controller. - auto qcp_axis = custom_plot->xAxis; - ViewportAxisPlotController controller(qcp_axis); - controller.setItem(axisItem); - - // changing title - auto textItem = axisItem->item<TextItem>(ViewportAxisItem::P_TITLE); - textItem->setProperty(TextItem::P_TEXT, "abc"); - - // no need to change title size and font (checked in axistitlecontroller.test) - - // QCPAxis should switch to logarithmic - EXPECT_EQ(qcp_axis->label(), QString("abc")); -} diff --git a/mvvm/tests/testview/widgetutils.test.cpp b/mvvm/tests/testview/widgetutils.test.cpp deleted file mode 100644 index bb975f491fbbb888e93c3e92fea5a94e44950457..0000000000000000000000000000000000000000 --- a/mvvm/tests/testview/widgetutils.test.cpp +++ /dev/null @@ -1,102 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testview/widgetutils.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/widgets/widgetutils.h" -#include "test_utils.h" -#include <QDebug> -#include <QDir> - -using namespace ModelView; - -//! Testing functions from utils. - -class WidgetUtilsTest : public ::testing::Test { -public: - ~WidgetUtilsTest(); -}; - -WidgetUtilsTest::~WidgetUtilsTest() = default; - -//! Test of WithTildeHomePath function. - -TEST_F(WidgetUtilsTest, WithTildeHomePath) -{ - if (ModelView::Utils::IsWindowsHost()) { - auto test_dir = QString::fromStdString(TestUtils::TestOutputDir()); - EXPECT_EQ(Utils::WithTildeHomePath(test_dir), test_dir); - } else { - auto home_path = QDir::homePath(); - auto test_dir = QString::fromStdString(TestUtils::TestOutputDir()); - auto expected = test_dir.startsWith(home_path) - ? QString("~") + test_dir.mid(home_path.size()) - : test_dir; - - // "/home/user/build-debug/test_output" -> ~/build-debug/test_output" - EXPECT_EQ(Utils::WithTildeHomePath(test_dir).toStdString(), expected.toStdString()); - - EXPECT_EQ(Utils::WithTildeHomePath("/opt/sw/build").toStdString(), - std::string("/opt/sw/build")); - } -} - -TEST_F(WidgetUtilsTest, ProjectWindowTitle) -{ - // untitled and unmodified project - EXPECT_EQ(Utils::ProjectWindowTitle(QString(""), false), "Untitled"); - - // untitled and modified project - EXPECT_EQ(Utils::ProjectWindowTitle(QString(""), true), "*Untitled"); - - // unmodified project without projectDir - EXPECT_EQ(Utils::ProjectWindowTitle(QString("Untitled"), false), "Untitled"); - - // modified project without projectDir - EXPECT_EQ(Utils::ProjectWindowTitle(QString("Untitled"), true), "*Untitled"); - - // unmodified project with projectDir - EXPECT_EQ(Utils::ProjectWindowTitle(QString("/home/user/project1"), false), "project1"); - - // modified project with projectDir - EXPECT_EQ(Utils::ProjectWindowTitle(QString("/home/user/project1"), true), "*project1"); -} - -TEST_F(WidgetUtilsTest, ClickableText) -{ - EXPECT_EQ(Utils::ClickableText("abc", "site.com"), QString("<a href=\"site.com\">abc</a>")); -} - -TEST_F(WidgetUtilsTest, toStringList) -{ - using vec_t = std::vector<std::string>; - EXPECT_EQ(Utils::toStringList(vec_t()), QStringList()); - EXPECT_EQ(Utils::toStringList(vec_t({"abc", "cde"})), QStringList({"abc", "cde"})); -} - -TEST_F(WidgetUtilsTest, fromStringList) -{ - using vec_t = std::vector<std::string>; - EXPECT_EQ(Utils::fromStringList(QStringList()), vec_t()); - EXPECT_EQ(Utils::fromStringList(QStringList({"abc", "cde"})), vec_t({"abc", "cde"})); -} - -TEST_F(WidgetUtilsTest, toFromByteArray) -{ - QStringList expected = QStringList() << "aaa" - << "bbb" - << "ccc"; - - auto array = Utils::serialize(expected); - EXPECT_EQ(Utils::deserialize(array), expected); -} diff --git a/mvvm/tests/testviewmodel/CMakeLists.txt b/mvvm/tests/testviewmodel/CMakeLists.txt deleted file mode 100644 index c5ad35aa81cda89e9e13b16693b60dc34f4884b9..0000000000000000000000000000000000000000 --- a/mvvm/tests/testviewmodel/CMakeLists.txt +++ /dev/null @@ -1,20 +0,0 @@ -set(test testviewmodel) - -file(GLOB source_files "*.cpp") -file(GLOB include_files "*.h") - -find_package(Qt5Core REQUIRED) -find_package(Qt5Test REQUIRED) - -# necessary for Qt creator and clang code model -include_directories(${gtest_SOURCE_DIR}/include ${gtest_SOURCE_DIR}) - -set(CMAKE_AUTOMOC ON) -add_executable(${test} ${source_files} ${include_files}) -target_link_libraries(${test} gtest gmock Qt5::Core Qt5::Test mvvm_viewmodel testmachinery qcustomplot) - -if (MVVM_DISCOVER_TESTS) - gtest_discover_tests(${test}) -else() - add_custom_target(${test}_run ALL DEPENDS ${test} COMMAND ${test}) -endif() diff --git a/mvvm/tests/testviewmodel/TestAll.cpp b/mvvm/tests/testviewmodel/TestAll.cpp deleted file mode 100644 index 1705b94d0a03e61340b211608bdf60acd05e0248..0000000000000000000000000000000000000000 --- a/mvvm/tests/testviewmodel/TestAll.cpp +++ /dev/null @@ -1,27 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testviewmodel/TestAll.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "qcustomplot.h" -#include <QApplication> -#include <QStandardItem> - -int main(int argc, char** argv) -{ - ::testing::InitGoogleTest(&argc, argv); - - ModelView::Comparators::registerComparators(); - - return RUN_ALL_TESTS(); -} diff --git a/mvvm/tests/testviewmodel/TestToyLayerItem.cpp b/mvvm/tests/testviewmodel/TestToyLayerItem.cpp deleted file mode 100644 index b10c233b2d5f42b763ef95f0f81321b036942d35..0000000000000000000000000000000000000000 --- a/mvvm/tests/testviewmodel/TestToyLayerItem.cpp +++ /dev/null @@ -1,155 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testviewmodel/TestToyLayerItem.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/model/itemutils.h" -#include "mvvm/standarditems/vectoritem.h" -#include "mvvm/viewmodel/defaultviewmodel.h" -#include "mvvm/viewmodel/standardviewitems.h" -#include "mvvm/viewmodel/topitemsviewmodel.h" -#include "toyitems.h" -#include "toymodel.h" -#include <QSignalSpy> - -using namespace ModelView; - -//! Tests for toy Layer in the context of model and view model. - -class ToyLayerItemTest : public ::testing::Test { -public: - ~ToyLayerItemTest(); -}; - -ToyLayerItemTest::~ToyLayerItemTest() = default; - -//! Initial state. - -TEST_F(ToyLayerItemTest, initialState) -{ - ToyItems::LayerItem item; - EXPECT_TRUE(Utils::IsSinglePropertyTag(item, ToyItems::LayerItem::P_THICKNESS)); - EXPECT_TRUE(Utils::IsSinglePropertyTag(item, ToyItems::LayerItem::P_COLOR)); - EXPECT_FALSE(Utils::IsSinglePropertyTag(item, ToyItems::LayerItem::T_PARTICLES)); -} - -//! Toy layer as prodused by toy SampleModel. - -TEST_F(ToyLayerItemTest, inModel) -{ - ToyItems::SampleModel model; - auto layer = model.insertItem<ToyItems::LayerItem>(); - - EXPECT_FALSE(layer->data<QVariant>().isValid()); - EXPECT_EQ(layer->displayName(), ToyItems::GUI::Constants::LayerItemType); -} - -TEST_F(ToyLayerItemTest, inViewModel) -{ - ToyItems::SampleModel model; - auto layerItem = model.insertItem<ToyItems::LayerItem>(); - - // constructing viewModel from sample model - DefaultViewModel viewModel(&model); - - // root item should have one child, item looking at our layerItem - EXPECT_EQ(viewModel.rowCount(), 1); - EXPECT_EQ(viewModel.columnCount(), 2); - - // accessing to viewItem representing layerItem - QModelIndex i_layer = viewModel.index(0, 0); - auto viewItem = dynamic_cast<ViewLabelItem*>(viewModel.itemFromIndex(i_layer)); - EXPECT_TRUE(viewItem != nullptr); - EXPECT_EQ(viewItem->item(), layerItem); - - // it has two rows and two columns, corresponding to our "thickness" and "color" properties - EXPECT_EQ(viewModel.rowCount(i_layer), 2); - EXPECT_EQ(viewModel.columnCount(i_layer), 2); - - // accessing to views representing label and value of thickness property - QModelIndex thicknessLabelIndex = viewModel.index(0, 0, i_layer); - auto thicknessLabelView = - dynamic_cast<ViewLabelItem*>(viewModel.itemFromIndex(thicknessLabelIndex)); - EXPECT_TRUE(thicknessLabelView != nullptr); - - QModelIndex thicknessValueIndex = viewModel.index(0, 1, i_layer); - auto thicknessValueView = - dynamic_cast<ViewDataItem*>(viewModel.itemFromIndex(thicknessValueIndex)); - EXPECT_TRUE(thicknessValueView != nullptr); - - // internally, views for label and data should point to single SessionItem corresponding to - // thickness property - EXPECT_EQ(thicknessLabelView->item(), layerItem->getItem(ToyItems::LayerItem::P_THICKNESS)); - EXPECT_EQ(thicknessValueView->item(), layerItem->getItem(ToyItems::LayerItem::P_THICKNESS)); -} - -//! Constructing ViewModel from a Layer with one "thickness" property. -//! Change thickness property in SessionItem, control dataChanged signals from ViewModel. - -TEST_F(ToyLayerItemTest, layerItemDataChanged) -{ - ToyItems::SampleModel model; - auto layerItem = model.insertItem<ToyItems::LayerItem>(); - - // constructing viewModel from sample model - DefaultViewModel viewModel(&model); - - QModelIndex i_layer = viewModel.index(0, 0); - QModelIndex thicknessIndex = viewModel.index(0, 1, i_layer); - - QSignalSpy spyDataChanged(&viewModel, &DefaultViewModel::dataChanged); - - layerItem->setProperty(ToyItems::LayerItem::P_THICKNESS, 50.0); - EXPECT_EQ(spyDataChanged.count(), 1); - - // dataChanged should report thicknessIndex and two roles - QList<QVariant> arguments = spyDataChanged.takeFirst(); - EXPECT_EQ(arguments.size(), 3); // QModelIndex left, QModelIndex right, QVector<int> roles - EXPECT_EQ(arguments.at(0).value<QModelIndex>(), thicknessIndex); - EXPECT_EQ(arguments.at(1).value<QModelIndex>(), thicknessIndex); - QVector<int> expectedRoles = {Qt::DisplayRole, Qt::EditRole}; - EXPECT_EQ(arguments.at(2).value<QVector<int>>(), expectedRoles); -} - -//! Validates display name - -TEST_F(ToyLayerItemTest, displayNameInMultiLayer) -{ - ToyItems::SampleModel model; - auto multiLayer = model.insertItem<ToyItems::MultiLayerItem>(); - - auto layer0 = model.insertItem<ToyItems::LayerItem>(multiLayer); - EXPECT_EQ(layer0->displayName(), "Layer"); - - auto layer1 = model.insertItem<ToyItems::LayerItem>(multiLayer); - EXPECT_EQ(layer0->displayName(), "Layer0"); - EXPECT_EQ(layer1->displayName(), "Layer1"); -} - -//! LayerItem as rootItem. - -TEST_F(ToyLayerItemTest, setRootItemContext) -{ - ToyItems::SampleModel model; - auto layer = model.insertItem<ToyItems::LayerItem>(); - DefaultViewModel viewModel(&model); - viewModel.setRootSessionItem(layer); - - EXPECT_EQ(viewModel.rowCount(QModelIndex()), 2); - EXPECT_EQ(viewModel.columnCount(QModelIndex()), 2); - - // index of item representing thickness - QModelIndex thicknessIndex = viewModel.index(0, 0, QModelIndex()); - EXPECT_EQ(viewModel.sessionItemFromIndex(thicknessIndex), - layer->getItem(ToyItems::LayerItem::P_THICKNESS)); -} diff --git a/mvvm/tests/testviewmodel/TestToyMultiLayerItem.cpp b/mvvm/tests/testviewmodel/TestToyMultiLayerItem.cpp deleted file mode 100644 index 4c5165b91d955be366ab645db2e07895ed1f91e9..0000000000000000000000000000000000000000 --- a/mvvm/tests/testviewmodel/TestToyMultiLayerItem.cpp +++ /dev/null @@ -1,105 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testviewmodel/TestToyMultiLayerItem.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/model/itemutils.h" -#include "mvvm/viewmodel/defaultviewmodel.h" -#include "mvvm/viewmodel/standardviewitems.h" -#include "mvvm/viewmodel/viewmodelutils.h" -#include "toyitems.h" -#include "toymodel.h" -#include <QSignalSpy> - -using namespace ModelView; - -//! Tests of toy MultiLayer in the context of model and viewmodel. - -class ToyMultilayerItemTest : public ::testing::Test { -public: - ~ToyMultilayerItemTest(); -}; - -ToyMultilayerItemTest::~ToyMultilayerItemTest() = default; - -//! Initial state. - -TEST_F(ToyMultilayerItemTest, initialState) -{ - ToyItems::MultiLayerItem item; - EXPECT_FALSE(Utils::IsSinglePropertyTag(item, ToyItems::MultiLayerItem::T_LAYERS)); -} - -//! Toy multilayer in a SampleModel. - -TEST_F(ToyMultilayerItemTest, multiLayer) -{ - ToyItems::SampleModel model; - auto multiLayer = model.insertItem<ToyItems::MultiLayerItem>(); - - EXPECT_FALSE(multiLayer->data<QVariant>().isValid()); - EXPECT_EQ(multiLayer->displayName(), ToyItems::GUI::Constants::MultiLayerItemType); -} - -//! Constructing ViewModel from a MultiLayer. -//! Checking that view items point co correct SessionItem. - -TEST_F(ToyMultilayerItemTest, multiLayerView) -{ - ToyItems::SampleModel model; - auto multiLayerItem = model.insertItem<ToyItems::MultiLayerItem>(); - - DefaultViewModel viewModel(&model); - EXPECT_EQ(viewModel.rowCount(), 1); - EXPECT_EQ(viewModel.columnCount(), 2); - - // accessing first child under the root item - QModelIndex mlIndex = viewModel.index(0, 0); - - // it should be ViewLabelItem looking at our MultiLayer item - auto viewItem = dynamic_cast<ViewLabelItem*>(viewModel.itemFromIndex(mlIndex)); - EXPECT_TRUE(viewItem != nullptr); - EXPECT_EQ(viewItem->item(), multiLayerItem); - - // adding layer - model.insertItem<ToyItems::LayerItem>(multiLayerItem); - EXPECT_EQ(viewModel.rowCount(mlIndex), 1); - EXPECT_EQ(viewModel.columnCount(mlIndex), 2); -} - -//! Find ViewItem corresponding to given MultiLayer item. - -TEST_F(ToyMultilayerItemTest, findMultiLayerView) -{ - ToyItems::SampleModel model; - auto multiLayerItem = model.insertItem<ToyItems::MultiLayerItem>(); - - DefaultViewModel viewModel(&model); - - auto views = viewModel.findViews(multiLayerItem); - EXPECT_EQ(views.size(), 2); - EXPECT_EQ(views.at(0)->item(), multiLayerItem); -} - -//! How ViewLabelItem sees MultiLayer - -TEST_F(ToyMultilayerItemTest, viewItemsForMultiLayer) -{ - ToyItems::SampleModel model; - - auto multiLayer = model.insertItem<ToyItems::MultiLayerItem>(); - - ViewLabelItem labelItem(multiLayer); - EXPECT_EQ(labelItem.data(Qt::DisplayRole).toString().toStdString(), - ToyItems::GUI::Constants::MultiLayerItemType); -} diff --git a/mvvm/tests/testviewmodel/TestToyParticleItem.cpp b/mvvm/tests/testviewmodel/TestToyParticleItem.cpp deleted file mode 100644 index 90ae72b435f87544679c6d8a3c4bc8dfc4ce329a..0000000000000000000000000000000000000000 --- a/mvvm/tests/testviewmodel/TestToyParticleItem.cpp +++ /dev/null @@ -1,63 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testviewmodel/TestToyParticleItem.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/model/itemutils.h" -#include "mvvm/viewmodel/defaultviewmodel.h" -#include "mvvm/viewmodel/viewmodelutils.h" -#include "toyitems.h" -#include "toymodel.h" -#include <QSignalSpy> - -using namespace ModelView; - -//! Tests of toy MultiLayer in the context of model and viewmodel. - -class ToyParticleItemTest : public ::testing::Test { -public: - ~ToyParticleItemTest(); -}; - -ToyParticleItemTest::~ToyParticleItemTest() = default; - -//! Initial state. - -TEST_F(ToyParticleItemTest, initialState) -{ - ToyItems::ParticleItem item; - EXPECT_TRUE(Utils::IsSinglePropertyTag(item, ToyItems::ParticleItem::P_POSITION)); - EXPECT_TRUE(Utils::IsSinglePropertyTag(item, ToyItems::ParticleItem::P_SHAPES)); -} - -TEST_F(ToyParticleItemTest, TopLevelItems) -{ - ToyItems::SampleModel model; - auto particle = model.insertItem<ToyItems::ParticleItem>(); - - EXPECT_EQ(Utils::TopLevelItems(*model.rootItem()), std::vector<SessionItem*>({particle})); - EXPECT_EQ(Utils::TopLevelItems(*particle), std::vector<SessionItem*>{}); -} - -TEST_F(ToyParticleItemTest, SinglePropertyItems) -{ - ToyItems::SampleModel model; - auto particle = model.insertItem<ToyItems::ParticleItem>(); - - EXPECT_EQ(Utils::TopLevelItems(*model.rootItem()), std::vector<SessionItem*>({particle})); - - EXPECT_EQ(Utils::SinglePropertyItems(*model.rootItem()), std::vector<SessionItem*>{}); - std::vector<SessionItem*> expected = {particle->getItem(ToyItems::ParticleItem::P_POSITION), - particle->getItem(ToyItems::ParticleItem::P_SHAPES)}; - EXPECT_EQ(Utils::SinglePropertyItems(*particle), expected); -} diff --git a/mvvm/tests/testviewmodel/defaulteditorfactory.test.cpp b/mvvm/tests/testviewmodel/defaulteditorfactory.test.cpp deleted file mode 100644 index 511836a70dea1fac480b64de2ca92d27ca7be135..0000000000000000000000000000000000000000 --- a/mvvm/tests/testviewmodel/defaulteditorfactory.test.cpp +++ /dev/null @@ -1,200 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testviewmodel/defaulteditorfactory.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/editors/booleditor.h" -#include "mvvm/editors/coloreditor.h" -#include "mvvm/editors/combopropertyeditor.h" -#include "mvvm/editors/defaulteditorfactory.h" -#include "mvvm/editors/editor_constants.h" -#include "mvvm/editors/externalpropertyeditor.h" -#include "mvvm/editors/integereditor.h" -#include "mvvm/editors/scientificdoubleeditor.h" -#include "mvvm/editors/scientificspinbox.h" -#include "mvvm/editors/scientificspinboxeditor.h" -#include "mvvm/editors/selectablecomboboxeditor.h" -#include "mvvm/model/comboproperty.h" -#include "mvvm/model/externalproperty.h" -#include "mvvm/model/propertyitem.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/utils/reallimits.h" -#include "mvvm/viewmodel/defaultviewmodel.h" -#include "mvvm/viewmodel/viewmodeldelegate.h" -#include "widgetbasedtest.h" -#include <QSpinBox> -#include <QStandardItemModel> -#include <limits> - -using namespace ModelView; - -class DefaultEditorFactoryTest : public WidgetBasedTest { -public: - DefaultEditorFactoryTest() : m_factory(std::make_unique<DefaultEditorFactory>()) {} - ~DefaultEditorFactoryTest(); - - //! Helper function to build temporary model and create editor for cell. - std::unique_ptr<CustomEditor> createEditor(const QVariant& variant, - RealLimits limits = RealLimits::limitless(), - const std::string& editor_type = {}) - { - // populating model with data - SessionModel model; - auto propertyItem = model.insertItem<PropertyItem>(); - propertyItem->setData(variant); - if (limits.hasLowerLimit() || limits.hasUpperLimit()) - propertyItem->setLimits(limits); - if (!editor_type.empty()) - propertyItem->setEditorType(editor_type); - - // create view model and use index of data cell to create an editor - DefaultViewModel viewModel(&model); - return m_factory->createEditor(viewModel.index(0, 1)); - } - -protected: - std::unique_ptr<DefaultEditorFactory> m_factory; -}; - -DefaultEditorFactoryTest::~DefaultEditorFactoryTest() = default; - -//! Tests editor creation on bool property. - -TEST_F(DefaultEditorFactoryTest, boolProperty) -{ - auto editor = createEditor(QVariant::fromValue(true)); - EXPECT_TRUE(dynamic_cast<BoolEditor*>(editor.get())); -} - -//! Tests editor creation on integer property. - -TEST_F(DefaultEditorFactoryTest, integerProperty) -{ - auto editor = createEditor(QVariant::fromValue(42)); - EXPECT_TRUE(dynamic_cast<IntegerEditor*>(editor.get())); - - auto spin_box = editor->findChild<QSpinBox*>(); - - ASSERT_TRUE(spin_box != nullptr); - EXPECT_EQ(spin_box->minimum(), -65536); - EXPECT_EQ(spin_box->maximum(), 65536); -} - -//! Tests editor creation on integer property with limits. - -TEST_F(DefaultEditorFactoryTest, integerPropertyWithLimits) -{ - auto editor = createEditor(QVariant::fromValue(42), RealLimits::limited(-1, 1)); - EXPECT_TRUE(dynamic_cast<IntegerEditor*>(editor.get())); - - auto spin_box = editor->findChild<QSpinBox*>(); - ASSERT_TRUE(spin_box != nullptr); - EXPECT_EQ(spin_box->minimum(), -1); - EXPECT_EQ(spin_box->maximum(), 1); -} - -//! Tests editor creation on double property. - -TEST_F(DefaultEditorFactoryTest, doubleProperty) -{ - auto editor = createEditor(QVariant::fromValue(42.42)); - EXPECT_TRUE(dynamic_cast<ScientificSpinBoxEditor*>(editor.get())); - - auto spin_box = editor->findChild<ScientificSpinBox*>(); - ASSERT_TRUE(spin_box != nullptr); - EXPECT_FLOAT_EQ(spin_box->minimum(), -std::numeric_limits<double>::max()); - EXPECT_FLOAT_EQ(spin_box->maximum(), std::numeric_limits<double>::max()); -} - -//! Tests editor creation on double property with limits. - -TEST_F(DefaultEditorFactoryTest, doublePropertyWithLimits) -{ - auto editor = createEditor(QVariant::fromValue(42.42), RealLimits::limited(41, 43)); - EXPECT_TRUE(dynamic_cast<ScientificSpinBoxEditor*>(editor.get())); - - auto spin_box = editor->findChild<ScientificSpinBox*>(); - ASSERT_TRUE(spin_box != nullptr); - EXPECT_FLOAT_EQ(spin_box->minimum(), 41); - EXPECT_FLOAT_EQ(spin_box->maximum(), 43); -} - -//! Tests editor creation on color property. - -TEST_F(DefaultEditorFactoryTest, colorProperty) -{ - auto editor = createEditor(QVariant::fromValue(QColor(Qt::green))); - EXPECT_TRUE(dynamic_cast<ColorEditor*>(editor.get())); -} - -//! Tests editor creation on combo property. - -TEST_F(DefaultEditorFactoryTest, comboProperty) -{ - auto editor = createEditor(QVariant::fromValue(ComboProperty())); - EXPECT_TRUE(dynamic_cast<ComboPropertyEditor*>(editor.get())); -} - -//! Tests editor creation on combo property. - -TEST_F(DefaultEditorFactoryTest, externalProperty) -{ - auto editor = createEditor(QVariant::fromValue(ExternalProperty())); - EXPECT_TRUE(dynamic_cast<ExternalPropertyEditor*>(editor.get())); -} - -//! Tests editor creation on some unsupported property. - -TEST_F(DefaultEditorFactoryTest, unsupportedProperty) -{ - // no dedicated editor for std::string yet - auto editor = createEditor(QVariant::fromValue(std::string("text"))); - EXPECT_EQ(editor.get(), nullptr); - - // no editor for RealLimits - editor = createEditor(QVariant::fromValue(RealLimits::limited(1.0, 2.0))); - EXPECT_EQ(editor.get(), nullptr); - - // no editor for invalid variant - editor = createEditor(QVariant()); - EXPECT_EQ(editor.get(), nullptr); - - // special case of invalid index - EXPECT_EQ(m_factory->createEditor(QModelIndex()), nullptr); -} - -//! Create test editor using EDITOR role. - -TEST_F(DefaultEditorFactoryTest, editorType) -{ - auto editor = createEditor(QVariant::fromValue(ComboProperty()), RealLimits(), - GUI::Constants::SelectableComboPropertyEditorType); - EXPECT_TRUE(dynamic_cast<SelectableComboBoxEditor*>(editor.get())); -} - -//! Tests editor creation on combo property in QStandardItemModel with our variant. - -TEST_F(DefaultEditorFactoryTest, comboPropertyInStandardModel) -{ - QStandardItemModel model; - auto parent = model.invisibleRootItem(); - QList<QStandardItem*> children{new QStandardItem}; - parent->appendRow(children); - - auto item = model.item(0, 0); - item->setData(QVariant::fromValue(ComboProperty()), Qt::EditRole); - - auto editor = m_factory->createEditor(model.index(0, 0)); - EXPECT_TRUE(dynamic_cast<ComboPropertyEditor*>(editor.get())); -} diff --git a/mvvm/tests/testviewmodel/defaultviewmodel.test.cpp b/mvvm/tests/testviewmodel/defaultviewmodel.test.cpp deleted file mode 100644 index be4121358982a885a5cb88d89d72c458f812a48a..0000000000000000000000000000000000000000 --- a/mvvm/tests/testviewmodel/defaultviewmodel.test.cpp +++ /dev/null @@ -1,852 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testviewmodel/defaultviewmodel.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "folderbasedtest.h" -#include "google_test.h" -#include "mvvm/model/compounditem.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/model/taginfo.h" -#include "mvvm/serialization/jsondocument.h" -#include "mvvm/serialization/jsonitem_types.h" -#include "mvvm/serialization/jsonmodelconverter.h" -#include "mvvm/standarditems/axisitems.h" -#include "mvvm/standarditems/containeritem.h" -#include "mvvm/standarditems/data1ditem.h" -#include "mvvm/standarditems/graphitem.h" -#include "mvvm/standarditems/graphviewportitem.h" -#include "mvvm/standarditems/vectoritem.h" -#include "mvvm/viewmodel/defaultviewmodel.h" -#include "mvvm/viewmodel/standardviewitems.h" -#include "mvvm/viewmodel/viewmodelutils.h" -#include "test_utils.h" -#include <QDebug> -#include <QJsonObject> -#include <QSignalSpy> - -using namespace ModelView; - -class DefaultViewModelTest : public FolderBasedTest { -public: - DefaultViewModelTest() : FolderBasedTest("test_DefaultViewModel") {} - ~DefaultViewModelTest(); -}; - -DefaultViewModelTest::~DefaultViewModelTest() = default; - -TEST_F(DefaultViewModelTest, initialState) -{ - SessionModel model; - DefaultViewModel viewModel(&model); - EXPECT_EQ(viewModel.rowCount(), 0); - EXPECT_EQ(viewModel.columnCount(), 0); - EXPECT_EQ(viewModel.sessionItemFromIndex(QModelIndex()), model.rootItem()); -} - -//! Single property item in a model. - -TEST_F(DefaultViewModelTest, fromPropertyItem) -{ - SessionModel model; - auto propertyItem = model.insertItem<PropertyItem>(); - propertyItem->setData(42.0); - - DefaultViewModel viewModel(&model); - EXPECT_EQ(viewModel.rowCount(), 1); - EXPECT_EQ(viewModel.columnCount(), 2); - - // accessing first child under the root item - QModelIndex labelIndex = viewModel.index(0, 0); - QModelIndex dataIndex = viewModel.index(0, 1); - - // it should be ViewLabelItem looking at our PropertyItem item - auto labelItem = dynamic_cast<ViewLabelItem*>(viewModel.itemFromIndex(labelIndex)); - ASSERT_TRUE(labelItem != nullptr); - EXPECT_EQ(labelItem->item(), propertyItem); - - auto dataItem = dynamic_cast<ViewDataItem*>(viewModel.itemFromIndex(dataIndex)); - ASSERT_TRUE(dataItem != nullptr); - EXPECT_EQ(dataItem->item(), propertyItem); -} - -//! Single property item in a model, inserted after DefaultViewModel was setup. - -TEST_F(DefaultViewModelTest, initThenInsert) -{ - SessionModel model; - DefaultViewModel viewModel(&model); - - auto propertyItem = model.insertItem<PropertyItem>(); - propertyItem->setData(42.0); - - EXPECT_EQ(viewModel.rowCount(), 1); - EXPECT_EQ(viewModel.columnCount(), 2); - - // accessing first child under the root item - QModelIndex labelIndex = viewModel.index(0, 0); - QModelIndex dataIndex = viewModel.index(0, 1); - - // it should be ViewLabelItem looking at our PropertyItem item - auto labelItem = dynamic_cast<ViewLabelItem*>(viewModel.itemFromIndex(labelIndex)); - ASSERT_TRUE(labelItem != nullptr); - EXPECT_EQ(labelItem->item(), propertyItem); - - // Feature: since our PropertyItem got it's value after ViewModel was initialized, the model - // still holds ViewEmptyItem and not ViewDataItem. - auto dataItem = dynamic_cast<ViewDataItem*>(viewModel.itemFromIndex(dataIndex)); - ASSERT_TRUE(dataItem != nullptr); -} - -//! Single property item in a model. - -TEST_F(DefaultViewModelTest, sessionItemFromIndex) -{ - SessionModel model; - auto propertyItem = model.insertItem<PropertyItem>(); - propertyItem->setData(42.0); - - DefaultViewModel viewModel(&model); - EXPECT_EQ(viewModel.rowCount(), 1); - EXPECT_EQ(viewModel.columnCount(), 2); - - // accessing first child under the root item - QModelIndex labelIndex = viewModel.index(0, 0); - QModelIndex dataIndex = viewModel.index(0, 1); - - EXPECT_EQ(viewModel.sessionItemFromIndex(QModelIndex()), model.rootItem()); - EXPECT_EQ(viewModel.sessionItemFromIndex(labelIndex), propertyItem); - EXPECT_EQ(viewModel.sessionItemFromIndex(dataIndex), propertyItem); -} - -//! Index from single property item. - -TEST_F(DefaultViewModelTest, indexFromSessionItem) -{ - SessionModel model; - auto propertyItem = model.insertItem<PropertyItem>(); - propertyItem->setData(42.0); - - DefaultViewModel viewModel(&model); - EXPECT_EQ(viewModel.rowCount(), 1); - EXPECT_EQ(viewModel.columnCount(), 2); - - // accessing first child under the root item - QModelIndex labelIndex = viewModel.index(0, 0); - QModelIndex dataIndex = viewModel.index(0, 1); - - QModelIndexList expected{labelIndex, dataIndex}; - EXPECT_EQ(viewModel.indexOfSessionItem(propertyItem), expected); -} - -//! Find ViewItem's corresponding to given PropertyItem. - -TEST_F(DefaultViewModelTest, findPropertyItemView) -{ - SessionModel model; - auto propertyItem = model.insertItem<PropertyItem>(); - propertyItem->setData(42.0); - - DefaultViewModel viewModel(&model); - auto views = viewModel.findViews(propertyItem); -} - -//! Constructing ViewModel from single PropertyItem. -//! Change thickness property in SessionItem, control dataChanged signals from ViewModel. - -TEST_F(DefaultViewModelTest, propertyItemDataChanged) -{ - SessionModel model; - auto propertyItem = model.insertItem<PropertyItem>(); - propertyItem->setData(42.0); - - // constructing viewModel from sample model - DefaultViewModel viewModel(&model); - - QModelIndex dataIndex = viewModel.index(0, 1); - - QSignalSpy spyDataChanged(&viewModel, &DefaultViewModel::dataChanged); - - propertyItem->setData(50.0); - EXPECT_EQ(spyDataChanged.count(), 1); - - // dataChanged should report thicknessIndex and two roles - QList<QVariant> arguments = spyDataChanged.takeFirst(); - EXPECT_EQ(arguments.size(), 3); // QModelIndex left, QModelIndex right, QVector<int> roles - EXPECT_EQ(arguments.at(0).value<QModelIndex>(), dataIndex); - EXPECT_EQ(arguments.at(1).value<QModelIndex>(), dataIndex); - QVector<int> expectedRoles = {Qt::DisplayRole, Qt::EditRole}; - EXPECT_EQ(arguments.at(2).value<QVector<int>>(), expectedRoles); -} - -//! Inserting single top level item. - -TEST_F(DefaultViewModelTest, insertSingleTopItem) -{ - SessionModel model; - DefaultViewModel viewModel(&model); - - QSignalSpy spyInsert(&viewModel, &DefaultViewModel::rowsInserted); - - // inserting single item - model.insertItem<SessionItem>(); - - // root item should have one child - EXPECT_EQ(viewModel.rowCount(), 1); - EXPECT_EQ(viewModel.columnCount(), 2); - - // removing child - model.removeItem(model.rootItem(), {"", 0}); - EXPECT_EQ(spyInsert.count(), 1); - EXPECT_EQ(viewModel.rowCount(), 0); - EXPECT_EQ(viewModel.columnCount(), 0); - - QList<QVariant> arguments = spyInsert.takeFirst(); - EXPECT_EQ(arguments.size(), 3); // QModelIndex &parent, int first, int last - EXPECT_EQ(arguments.at(0).value<QModelIndex>(), QModelIndex()); - EXPECT_EQ(arguments.at(1).value<int>(), 0); - EXPECT_EQ(arguments.at(2).value<int>(), 0); -} - -//! Removing single top level item. - -TEST_F(DefaultViewModelTest, removeSingleTopItem) -{ - SessionModel model; - - // inserting single item - model.insertItem<SessionItem>(); - - // constructing viewModel from sample model - DefaultViewModel viewModel(&model); - - // root item should have one child - EXPECT_EQ(viewModel.rowCount(), 1); - EXPECT_EQ(viewModel.columnCount(), 2); - - QSignalSpy spyRemove(&viewModel, &DefaultViewModel::rowsRemoved); - - // removing child - model.removeItem(model.rootItem(), {"", 0}); - ASSERT_EQ(spyRemove.count(), 1); - EXPECT_EQ(viewModel.rowCount(), 0); - EXPECT_EQ(viewModel.columnCount(), 0); - - QList<QVariant> arguments = spyRemove.takeFirst(); - ASSERT_EQ(arguments.size(), 3); // QModelIndex &parent, int first, int last - EXPECT_EQ(arguments.at(0).value<QModelIndex>(), QModelIndex()); - EXPECT_EQ(arguments.at(1).value<int>(), 0); - EXPECT_EQ(arguments.at(2).value<int>(), 0); -} - -//! Remove one of two top level items. - -TEST_F(DefaultViewModelTest, removeOneOfTopItems) -{ - SessionModel model; - - // inserting single item - model.insertItem<SessionItem>(); - model.insertItem<SessionItem>(); - - // constructing viewModel from sample model - DefaultViewModel viewModel(&model); - - // root item should have one child - EXPECT_EQ(viewModel.rowCount(), 2); - EXPECT_EQ(viewModel.columnCount(), 2); - - QSignalSpy spyRemove(&viewModel, &DefaultViewModel::rowsRemoved); - QSignalSpy spyInsert(&viewModel, &DefaultViewModel::rowsInserted); - - // removing child - model.removeItem(model.rootItem(), {"", 0}); - - // removal was called once - EXPECT_EQ(spyRemove.count(), 1); - EXPECT_EQ(viewModel.rowCount(), 1); - EXPECT_EQ(viewModel.columnCount(), 2); - - // no call to insert - EXPECT_EQ(spyInsert.count(), 0); - - QList<QVariant> arguments = spyRemove.takeFirst(); - EXPECT_EQ(arguments.size(), 3); // QModelIndex &parent, int first, int last - EXPECT_EQ(arguments.at(0).value<QModelIndex>(), QModelIndex()); - EXPECT_EQ(arguments.at(1).value<int>(), 0); - EXPECT_EQ(arguments.at(2).value<int>(), 0); -} - -//! Single property item in ViewModel with various appearance flags. - -TEST_F(DefaultViewModelTest, propertyItemAppearance) -{ - SessionModel model; - - // default item - auto item1 = model.insertItem<PropertyItem>(); - item1->setData(42.0); - - // disabled item - auto item2 = model.insertItem<PropertyItem>(); - item2->setData(42.0); - item2->setEnabled(false); // our convention: gray color, read only - - // read only item - auto item3 = model.insertItem<PropertyItem>(); - item3->setData(42.0); - item3->setEditable(false); // our convention: normal color, read only - - // making view model - DefaultViewModel viewModel(&model); - - // In tests below is important that SessionItem::isEnabled==false means that item is - // shown in gray color. While QStandardItem::isEnabled means "no interaction". - // In our case QStandardItem::isEnabled should be always true. - - // ViewLabel and ViewDataItem of item1 - EXPECT_FALSE(viewModel.flags(viewModel.index(0, 0)) & Qt::ItemIsEditable); - EXPECT_TRUE(viewModel.flags(viewModel.index(0, 1)) & Qt::ItemIsEditable); - - // ViewLabel and ViewDataItem of item2 - EXPECT_FALSE(viewModel.flags(viewModel.index(1, 0)) & Qt::ItemIsEditable); - EXPECT_FALSE(viewModel.flags(viewModel.index(1, 1)) & Qt::ItemIsEditable); - - // ViewLabel and ViewDataItem of item2 - EXPECT_FALSE(viewModel.flags(viewModel.index(2, 0)) & Qt::ItemIsEditable); - EXPECT_FALSE(viewModel.flags(viewModel.index(2, 1)) & Qt::ItemIsEditable); -} - -//! Signals in ViewModel when property item changes its appearance. - -TEST_F(DefaultViewModelTest, propertyItemAppearanceChanged) -{ - SessionModel model; - - // default item - auto item = model.insertItem<PropertyItem>(); - item->setData(42.0); - - // setting up ViewModel and spying it's dataChanged signals - DefaultViewModel viewModel(&model); - auto labelView = viewModel.itemFromIndex(viewModel.index(0, 0)); - auto dataView = viewModel.itemFromIndex(viewModel.index(0, 1)); - QSignalSpy spyDataChanged(&viewModel, &DefaultViewModel::dataChanged); - - // Changing item appearance - item->setEnabled(false); - EXPECT_EQ(spyDataChanged.count(), 2); // change in LabelView and DataView - - // first pack of arguments is related to ViewLabelItem - QList<QVariant> arguments = spyDataChanged.takeFirst(); - EXPECT_EQ(arguments.size(), 3); // QModelIndex &parent, int first, int last - auto index1 = arguments.at(0).value<QModelIndex>(); - auto index2 = arguments.at(1).value<QModelIndex>(); - auto roles = arguments.at(2).value<QVector<int>>(); - EXPECT_EQ(index1, viewModel.indexFromItem(labelView)); - EXPECT_EQ(index2, viewModel.indexFromItem(labelView)); -#if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0) - QVector<int> expected_roles = {Qt::ForegroundRole}; -#else - QVector<int> expected_roles = {Qt::TextColorRole}; -#endif - EXPECT_EQ(roles, expected_roles); - - // second pack of arguments is related to ViewDataItem - arguments = spyDataChanged.takeFirst(); - EXPECT_EQ(arguments.size(), 3); // QModelIndex &parent, int first, int last - index1 = arguments.at(0).value<QModelIndex>(); - index2 = arguments.at(1).value<QModelIndex>(); - roles = arguments.at(2).value<QVector<int>>(); - EXPECT_EQ(index1, viewModel.indexFromItem(dataView)); - EXPECT_EQ(index2, viewModel.indexFromItem(dataView)); - -#if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0) - expected_roles = {Qt::ForegroundRole}; -#else - expected_roles = {Qt::TextColorRole}; -#endif - - EXPECT_EQ(roles, expected_roles); -} - -//! Signals in ViewModel when property item changes its tooltips. - -TEST_F(DefaultViewModelTest, tooltipChanged) -{ - SessionModel model; - - // default item - auto item = model.insertItem<PropertyItem>(); - item->setData(42.0); - item->setToolTip("abc"); - - // setting up ViewModel and spying it's dataChanged signals - DefaultViewModel viewModel(&model); - auto labelView = viewModel.itemFromIndex(viewModel.index(0, 0)); - auto dataView = viewModel.itemFromIndex(viewModel.index(0, 1)); - - EXPECT_EQ(viewModel.data(viewModel.index(0, 0), Qt::ToolTipRole).toString(), QString("abc")); - EXPECT_EQ(viewModel.data(viewModel.index(0, 1), Qt::ToolTipRole).toString(), QString("abc")); - - QSignalSpy spyDataChanged(&viewModel, &DefaultViewModel::dataChanged); - - // Changing tooltip - item->setToolTip("abc2"); - EXPECT_EQ(spyDataChanged.count(), 2); // change in LabelView and DataView - - // first pack of arguments is related to ViewLabelItem - QList<QVariant> arguments = spyDataChanged.takeFirst(); - EXPECT_EQ(arguments.size(), 3); // QModelIndex &parent, int first, int last - auto index1 = arguments.at(0).value<QModelIndex>(); - auto index2 = arguments.at(1).value<QModelIndex>(); - auto roles = arguments.at(2).value<QVector<int>>(); - EXPECT_EQ(index1, viewModel.indexFromItem(labelView)); - EXPECT_EQ(index2, viewModel.indexFromItem(labelView)); - QVector<int> expected_roles = {Qt::ToolTipRole}; - EXPECT_EQ(roles, expected_roles); - - // second pack of arguments is related to ViewDataItem - arguments = spyDataChanged.takeFirst(); - EXPECT_EQ(arguments.size(), 3); // QModelIndex &parent, int first, int last - index1 = arguments.at(0).value<QModelIndex>(); - index2 = arguments.at(1).value<QModelIndex>(); - roles = arguments.at(2).value<QVector<int>>(); - EXPECT_EQ(index1, viewModel.indexFromItem(dataView)); - EXPECT_EQ(index2, viewModel.indexFromItem(dataView)); - - expected_roles = {Qt::ToolTipRole}; - EXPECT_EQ(roles, expected_roles); -} - -//! Setting property item as ROOT item. - -TEST_F(DefaultViewModelTest, setPropertyItemAsRoot) -{ - SessionModel model; - DefaultViewModel viewModel(&model); - - QSignalSpy spyAboutReset(&viewModel, &DefaultViewModel::modelAboutToBeReset); - QSignalSpy spyReset(&viewModel, &DefaultViewModel::modelReset); - - auto item = model.insertItem<PropertyItem>(); - viewModel.setRootSessionItem(item); - - // new root item doesn't have children - EXPECT_EQ(viewModel.rowCount(), 0); - EXPECT_EQ(viewModel.columnCount(), 0); - - EXPECT_EQ(spyAboutReset.count(), 1); - EXPECT_EQ(spyReset.count(), 1); - - // attempt to use nullptr as root item - EXPECT_THROW(viewModel.setRootSessionItem(nullptr), std::runtime_error); - - // attempt to use alien model - SessionModel model2; - EXPECT_THROW(viewModel.setRootSessionItem(model2.rootItem()), std::runtime_error); -} - -//! Setting property item as ROOT item. -//! Same as above, only view model was initialized after. - -TEST_F(DefaultViewModelTest, setPropertyItemAsRootAfter) -{ - SessionModel model; - auto item = model.insertItem<PropertyItem>(); - - DefaultViewModel viewModel(&model); - EXPECT_EQ(viewModel.rowCount(), 1); - EXPECT_EQ(viewModel.columnCount(), 2); - - QSignalSpy spyAboutReset(&viewModel, &DefaultViewModel::modelAboutToBeReset); - QSignalSpy spyReset(&viewModel, &DefaultViewModel::modelReset); - viewModel.setRootSessionItem(item); - - // new root item doesn't have children - EXPECT_EQ(viewModel.rowCount(), 0); - EXPECT_EQ(viewModel.columnCount(), 0); - - EXPECT_EQ(spyAboutReset.count(), 1); - EXPECT_EQ(spyReset.count(), 1); - - // attempt to use nullptr as root item - EXPECT_THROW(viewModel.setRootSessionItem(nullptr), std::runtime_error); - - // attempt to use alien model - SessionModel model2; - EXPECT_THROW(viewModel.setRootSessionItem(model2.rootItem()), std::runtime_error); -} - -//! Setting top level item as ROOT item (case parent and children). - -TEST_F(DefaultViewModelTest, setCompoundAsRootItem) -{ - SessionModel model; - DefaultViewModel viewModel(&model); - - auto item = model.insertItem<CompoundItem>(); - item->addProperty("thickness", 42.0); - item->addProperty<VectorItem>("position"); - item->addProperty("radius", 43.0); - - viewModel.setRootSessionItem(item); - - EXPECT_EQ(viewModel.rowCount(), 3); - EXPECT_EQ(viewModel.columnCount(), 2); - - // checking vector item - auto index_of_vector_item = viewModel.index(1, 0); - EXPECT_EQ(viewModel.rowCount(index_of_vector_item), 3); - EXPECT_EQ(viewModel.columnCount(index_of_vector_item), 2); -} - -//! Setting vector item as ROOT item. - -TEST_F(DefaultViewModelTest, setVectorItemAsRoot) -{ - SessionModel model; - auto vectorItem = model.insertItem<VectorItem>(); - - DefaultViewModel viewModel(&model); - viewModel.setRootSessionItem(vectorItem); - - EXPECT_EQ(viewModel.rowCount(), 3); - EXPECT_EQ(viewModel.columnCount(), 2); -} - -//! On model destroyed. - -TEST_F(DefaultViewModelTest, onModelReset) -{ - auto model = std::make_unique<SessionModel>(); - model->insertItem<SessionItem>(); - model->insertItem<SessionItem>(); - model->insertItem<SessionItem>(); - - DefaultViewModel viewModel(model.get()); - - QSignalSpy spyAboutReset(&viewModel, &DefaultViewModel::modelAboutToBeReset); - QSignalSpy spyReset(&viewModel, &DefaultViewModel::modelReset); - - model->clear(); - EXPECT_EQ(viewModel.rowCount(), 0); - EXPECT_EQ(viewModel.columnCount(), 0); - - EXPECT_EQ(spyAboutReset.count(), 1); - EXPECT_EQ(spyReset.count(), 1); -} - -//! On model destroyed. - -TEST_F(DefaultViewModelTest, onModelDestroyed) -{ - auto model = std::make_unique<SessionModel>(); - model->insertItem<SessionItem>(); - - DefaultViewModel viewModel(model.get()); - EXPECT_EQ(viewModel.rowCount(), 1); - EXPECT_EQ(viewModel.columnCount(), 2); - - model.reset(); - EXPECT_EQ(viewModel.rowCount(), 0); - EXPECT_EQ(viewModel.columnCount(), 0); -} - -TEST_F(DefaultViewModelTest, fromVector) -{ - SessionModel model; - auto vectorItem = model.insertItem<VectorItem>(); - - // constructing viewModel from sample model - DefaultViewModel viewModel(&model); - - // root item should have one child, item looking at our vectorItem - EXPECT_EQ(viewModel.rowCount(), 1); - EXPECT_EQ(viewModel.columnCount(), 2); - - // accessing to viewItem representing layerItem - QModelIndex vectorIndex = viewModel.index(0, 0); - - // it has three rows and two columns, corresponding to our P_X, P_Y, P_Z - EXPECT_EQ(viewModel.rowCount(vectorIndex), 3); - EXPECT_EQ(viewModel.columnCount(vectorIndex), 2); - - // ViewLabelItem and ViewDataItem correspondint to P_X - auto pxLabel = - dynamic_cast<ViewLabelItem*>(viewModel.itemFromIndex(viewModel.index(0, 0, vectorIndex))); - auto pxData = - dynamic_cast<ViewDataItem*>(viewModel.itemFromIndex(viewModel.index(0, 1, vectorIndex))); - EXPECT_EQ(pxLabel->item(), vectorItem->getItem(VectorItem::P_X)); - EXPECT_EQ(pxData->item(), vectorItem->getItem(VectorItem::P_X)); - - // ViewLabelItem and ViewDataItem correspondint to P_Y - pxLabel = - dynamic_cast<ViewLabelItem*>(viewModel.itemFromIndex(viewModel.index(1, 0, vectorIndex))); - pxData = - dynamic_cast<ViewDataItem*>(viewModel.itemFromIndex(viewModel.index(1, 1, vectorIndex))); - EXPECT_EQ(pxLabel->item(), vectorItem->getItem(VectorItem::P_Y)); - EXPECT_EQ(pxData->item(), vectorItem->getItem(VectorItem::P_Y)); - - // ViewLabelItem and ViewDataItem correspondint to P_Z - pxLabel = - dynamic_cast<ViewLabelItem*>(viewModel.itemFromIndex(viewModel.index(2, 0, vectorIndex))); - pxData = - dynamic_cast<ViewDataItem*>(viewModel.itemFromIndex(viewModel.index(2, 1, vectorIndex))); - EXPECT_EQ(pxLabel->item(), vectorItem->getItem(VectorItem::P_Z)); - EXPECT_EQ(pxData->item(), vectorItem->getItem(VectorItem::P_Z)); -} - -TEST_F(DefaultViewModelTest, horizontalLabels) -{ - SessionModel model; - model.insertItem<VectorItem>(); - - // constructing viewModel from sample model - DefaultViewModel viewModel(&model); - - EXPECT_EQ(viewModel.headerData(0, Qt::Horizontal, Qt::DisplayRole).toString(), QString("Name")); - EXPECT_EQ(viewModel.headerData(1, Qt::Horizontal, Qt::DisplayRole).toString(), - QString("Value")); -} - -//! Testing ViewModel signals while loading data with the help of json loader. - -TEST_F(DefaultViewModelTest, jsonConverterLoadModel) -{ - JsonModelConverter converter(ConverterMode::project); - QJsonObject object; - - // preparing jsob object - { - SessionModel model("TestModel"); - model.insertItem<PropertyItem>(); - JsonModelConverter converter(ConverterMode::project); - // writing model to json - object = converter.to_json(model); - } - - // loading model - SessionModel model("TestModel"); - DefaultViewModel viewmodel(&model); - EXPECT_EQ(viewmodel.rowCount(), 0); - EXPECT_EQ(viewmodel.columnCount(), 0); - - QSignalSpy spyInsert(&viewmodel, &DefaultViewModel::rowsInserted); - QSignalSpy spyRemove(&viewmodel, &DefaultViewModel::rowsRemoved); - QSignalSpy spyAboutReset(&viewmodel, &DefaultViewModel::modelAboutToBeReset); - QSignalSpy spyReset(&viewmodel, &DefaultViewModel::modelReset); - - converter.from_json(object, model); - - EXPECT_EQ(spyInsert.count(), 1); // FIXME shouldn't it be '0'? - EXPECT_EQ(spyRemove.count(), 0); - EXPECT_EQ(spyAboutReset.count(), 1); - EXPECT_EQ(spyReset.count(), 1); - - EXPECT_EQ(viewmodel.rowCount(), 1); - EXPECT_EQ(viewmodel.columnCount(), 2); -} - -//! Testing ViewModel signals while loading data with the help of json document. -//! Model is empty. - -TEST_F(DefaultViewModelTest, jsonDocumentLoadEmptyModel) -{ - auto fileName = TestUtils::TestFileName(testDir(), "jsonDocumentLoadEmptyModel.json"); - - // preparing jsob object - { - SessionModel model("TestModel"); - JsonDocument document({&model}); - document.save(fileName); - } - - // loading model - SessionModel model("TestModel"); - DefaultViewModel viewmodel(&model); - EXPECT_EQ(viewmodel.rowCount(), 0); - EXPECT_EQ(viewmodel.columnCount(), 0); - - JsonDocument document({&model}); - - QSignalSpy spyInsert(&viewmodel, &DefaultViewModel::rowsInserted); - QSignalSpy spyRemove(&viewmodel, &DefaultViewModel::rowsRemoved); - QSignalSpy spyAboutReset(&viewmodel, &DefaultViewModel::modelAboutToBeReset); - QSignalSpy spyReset(&viewmodel, &DefaultViewModel::modelReset); - - document.load(fileName); - - EXPECT_EQ(spyInsert.count(), 0); - EXPECT_EQ(spyRemove.count(), 0); - EXPECT_EQ(spyAboutReset.count(), 1); - EXPECT_EQ(spyReset.count(), 1); - - EXPECT_EQ(viewmodel.rowCount(), 0); - EXPECT_EQ(viewmodel.columnCount(), 0); -} - -//! Testing ViewModel signals while loading data with the help of json document. -//! Model is empty. - -TEST_F(DefaultViewModelTest, jsonDocumentLoadModel) -{ - auto fileName = TestUtils::TestFileName(testDir(), "jsonDocumentLoadModel.json"); - - // preparing jsob object - { - SessionModel model("TestModel"); - JsonDocument document({&model}); - model.insertItem<PropertyItem>(); - document.save(fileName); - } - - // loading model - SessionModel model("TestModel"); - DefaultViewModel viewmodel(&model); - EXPECT_EQ(viewmodel.rowCount(), 0); - EXPECT_EQ(viewmodel.columnCount(), 0); - - JsonDocument document({&model}); - - QSignalSpy spyInsert(&viewmodel, &DefaultViewModel::rowsInserted); - QSignalSpy spyRemove(&viewmodel, &DefaultViewModel::rowsRemoved); - QSignalSpy spyAboutReset(&viewmodel, &DefaultViewModel::modelAboutToBeReset); - QSignalSpy spyReset(&viewmodel, &DefaultViewModel::modelReset); - - document.load(fileName); - - EXPECT_EQ(spyInsert.count(), 1); - EXPECT_EQ(spyRemove.count(), 0); - EXPECT_EQ(spyAboutReset.count(), 1); - EXPECT_EQ(spyReset.count(), 1); - - EXPECT_EQ(viewmodel.rowCount(), 1); - EXPECT_EQ(viewmodel.columnCount(), 2); -} - -//! Testing view model after restoring from json document. - -TEST_F(DefaultViewModelTest, vectorItemInJsonDocument) -{ - auto fileName = TestUtils::TestFileName(testDir(), "vectorItemInJsonDocument.json"); - - SessionModel model; - model.insertItem<VectorItem>(); - - // constructing viewModel from sample model - DefaultViewModel viewmodel(&model); - - // root item should have one child, item looking at our vectorItem - EXPECT_EQ(viewmodel.rowCount(), 1); - EXPECT_EQ(viewmodel.columnCount(), 2); - - JsonDocument document({&model}); - document.save(fileName); - - // cleaning original model - model.clear(); - - QSignalSpy spyInsert(&viewmodel, &DefaultViewModel::rowsInserted); - QSignalSpy spyRemove(&viewmodel, &DefaultViewModel::rowsRemoved); - QSignalSpy spyAboutReset(&viewmodel, &DefaultViewModel::modelAboutToBeReset); - QSignalSpy spyReset(&viewmodel, &DefaultViewModel::modelReset); - - document.load(fileName); - - EXPECT_EQ(spyInsert.count(), 4); - EXPECT_EQ(spyRemove.count(), 0); - EXPECT_EQ(spyAboutReset.count(), 1); - EXPECT_EQ(spyReset.count(), 1); - - EXPECT_EQ(viewmodel.rowCount(), 1); - EXPECT_EQ(viewmodel.columnCount(), 2); -} - -//! Testing view model after restoring from json document. -//! VectorItem is made root item. Test demonstrates that controller is capable -//! to restore old rootSessionItem on onModelReset signal - -TEST_F(DefaultViewModelTest, vectorItemAsRootInJsonDocument) -{ - auto fileName = TestUtils::TestFileName(testDir(), "vectorItemAsRootInJsonDocument.json"); - - SessionModel model; - auto vectorItem = model.insertItem<VectorItem>(); - - // constructing viewModel from sample model - DefaultViewModel viewmodel(&model); - viewmodel.setRootSessionItem(vectorItem); - - // root item should have one child, item looking at our vectorItem - EXPECT_EQ(viewmodel.rowCount(), 3); - EXPECT_EQ(viewmodel.columnCount(), 2); - EXPECT_EQ(viewmodel.rootSessionItem(), vectorItem); - - JsonDocument document({&model}); - document.save(fileName); - - // model.clear(); // if we uncomment this, information about rootSessionItem will be lost - - QSignalSpy spyInsert(&viewmodel, &DefaultViewModel::rowsInserted); - QSignalSpy spyRemove(&viewmodel, &DefaultViewModel::rowsRemoved); - QSignalSpy spyAboutReset(&viewmodel, &DefaultViewModel::modelAboutToBeReset); - QSignalSpy spyReset(&viewmodel, &DefaultViewModel::modelReset); - - document.load(fileName); - - EXPECT_EQ(spyInsert.count(), 3); - EXPECT_EQ(spyRemove.count(), 0); - EXPECT_EQ(spyAboutReset.count(), 1); - EXPECT_EQ(spyReset.count(), 1); - - EXPECT_EQ(viewmodel.rootSessionItem(), model.rootItem()->children().at(0)); // vectorItem - - EXPECT_EQ(viewmodel.rowCount(), 3); - EXPECT_EQ(viewmodel.columnCount(), 2); -} - -//! Real life bug. One container with Data1DItem's, one ViewportItem with single graph. -//! DefaultViewModel is looking on ViewPortItem. Graph is deleted first. - -TEST_F(DefaultViewModelTest, deleteGraphVromViewport) -{ - SessionModel model; - - // creating data container and single Data1DItem in it - auto data_container = model.insertItem<ContainerItem>(); - auto data_item = model.insertItem<Data1DItem>(data_container); - data_item->setAxis<FixedBinAxisItem>(3, 0.0, 3.0); - data_item->setValues(std::vector<double>({1.0, 2.0, 3.0})); - - // creating Viewport with single graph - auto viewport_item = model.insertItem<GraphViewportItem>(); - auto graph_item = model.insertItem<GraphItem>(viewport_item); - graph_item->setDataItem(data_item); - - DefaultViewModel viewmodel(&model); - viewmodel.setRootSessionItem(viewport_item); - - // validating that we see graph at propeer index - EXPECT_EQ(viewmodel.rowCount(), 3); // X, Y and Graph - QModelIndex graph_index = viewmodel.index(2, 0); - auto graphLabel = dynamic_cast<ViewLabelItem*>(viewmodel.itemFromIndex(graph_index)); - ASSERT_TRUE(graphLabel != nullptr); - EXPECT_EQ(graphLabel->item(), graph_item); - - // removing graph item - model.removeItem(graph_item->parent(), graph_item->tagRow()); - EXPECT_EQ(viewmodel.rowCount(), 2); // X, Y - - graph_item = model.insertItem<GraphItem>(viewport_item); - EXPECT_EQ(viewmodel.rowCount(), 3); // X, Y -} diff --git a/mvvm/tests/testviewmodel/labeldatarowstrategy.test.cpp b/mvvm/tests/testviewmodel/labeldatarowstrategy.test.cpp deleted file mode 100644 index 5331740488a0a6dc9f6d4c34b93b76cbccdd30e6..0000000000000000000000000000000000000000 --- a/mvvm/tests/testviewmodel/labeldatarowstrategy.test.cpp +++ /dev/null @@ -1,82 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testviewmodel/labeldatarowstrategy.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/viewmodel/labeldatarowstrategy.h" -#include "mvvm/viewmodel/standardviewitems.h" -#include "test_utils.h" - -namespace { -const int expected_column_count = 2; -const QStringList expected_labels = QStringList() << "Name" - << "Value"; -} // namespace - -using namespace ModelView; - -class LabelDataRowStrategyTest : public ::testing::Test { -public: - ~LabelDataRowStrategyTest(); -}; - -LabelDataRowStrategyTest::~LabelDataRowStrategyTest() = default; - -TEST_F(LabelDataRowStrategyTest, initialState) -{ - LabelDataRowStrategy constructor; - EXPECT_EQ(constructor.constructRow(nullptr).size(), 0); - EXPECT_EQ(constructor.horizontalHeaderLabels(), expected_labels); -} - -//! Checks row construction for standard top level item, like Level, MultiLayer etc. - -TEST_F(LabelDataRowStrategyTest, topLevelItem) -{ - SessionItem item("model_type"); - - LabelDataRowStrategy constructor; - auto items = constructor.constructRow(&item); - EXPECT_EQ(items.size(), expected_column_count); // label and empty items - EXPECT_EQ(constructor.horizontalHeaderLabels(), expected_labels); - - // checking that it is label and data - auto labelItem = dynamic_cast<ViewLabelItem*>(items.at(0).get()); - auto dataItem = dynamic_cast<ViewDataItem*>(items.at(1).get()); - ASSERT_TRUE(labelItem != nullptr); - EXPECT_EQ(labelItem->item(), &item); - ASSERT_TRUE(dataItem != nullptr); - EXPECT_EQ(dataItem->item(), &item); -} - -//! Checks row construction for property item. - -TEST_F(LabelDataRowStrategyTest, propertyItem) -{ - SessionItem item("model_type"); - item.setData(42.0); - - LabelDataRowStrategy constructor; - auto items = constructor.constructRow(&item); - EXPECT_EQ(items.size(), expected_column_count); - EXPECT_EQ(constructor.horizontalHeaderLabels(), expected_labels); - - // checking that it is label and data - auto labelItem = dynamic_cast<ViewLabelItem*>(items.at(0).get()); - auto dataItem = dynamic_cast<ViewDataItem*>(items.at(1).get()); - ASSERT_TRUE(labelItem != nullptr); - EXPECT_EQ(labelItem->item(), &item); - ASSERT_TRUE(dataItem != nullptr); - EXPECT_EQ(dataItem->item(), &item); -} diff --git a/mvvm/tests/testviewmodel/propertiesrowstrategy.test.cpp b/mvvm/tests/testviewmodel/propertiesrowstrategy.test.cpp deleted file mode 100644 index 7f6faa3402ff6e0157ff05df8d520343c2ccc89a..0000000000000000000000000000000000000000 --- a/mvvm/tests/testviewmodel/propertiesrowstrategy.test.cpp +++ /dev/null @@ -1,162 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testviewmodel/propertiesrowstrategy.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/standarditems/vectoritem.h" -#include "mvvm/viewmodel/propertiesrowstrategy.h" -#include "mvvm/viewmodel/standardviewitems.h" -#include "test_utils.h" - -using namespace ModelView; - -class PropertiesRowStrategyTest : public ::testing::Test { -public: - ~PropertiesRowStrategyTest(); -}; - -PropertiesRowStrategyTest::~PropertiesRowStrategyTest() = default; - -TEST_F(PropertiesRowStrategyTest, initialState) -{ - PropertiesRowStrategy strategy; - EXPECT_EQ(strategy.constructRow(nullptr).size(), 0); - EXPECT_EQ(strategy.horizontalHeaderLabels(), QStringList()); -} - -//! Checks row construction for standard top level item. It shouldn't generate any rows. - -TEST_F(PropertiesRowStrategyTest, topLevelItem) -{ - SessionItem item("model_type"); - - PropertiesRowStrategy strategy; - auto items = strategy.constructRow(&item); - EXPECT_EQ(items.size(), 0); - EXPECT_EQ(strategy.horizontalHeaderLabels(), QStringList()); -} - -//! Checks row construction for property item. It shouldn't generate any rows. - -TEST_F(PropertiesRowStrategyTest, propertyItem) -{ - SessionItem item("model_type"); - item.setData(42.0); - - PropertiesRowStrategy strategy; - auto items = strategy.constructRow(&item); - EXPECT_EQ(items.size(), 0); - EXPECT_EQ(strategy.horizontalHeaderLabels(), QStringList()); -} - -//! Checks row construction for vector item. -//! There should be 3 view items looking to x, y, z properties. - -TEST_F(PropertiesRowStrategyTest, vectorItemCustomLabels) -{ - VectorItem item; - - EXPECT_EQ(item.property<double>(VectorItem::P_X), 0.0); - EXPECT_EQ(item.property<double>(VectorItem::P_Y), 0.0); - EXPECT_EQ(item.property<double>(VectorItem::P_Z), 0.0); - - PropertiesRowStrategy strategy({"a", "b", "c"}); - auto items = strategy.constructRow(&item); - - EXPECT_EQ(items.size(), 3); - EXPECT_EQ(strategy.horizontalHeaderLabels(), QStringList() << "a" - << "b" - << "c"); - - // views should look at 3 property items - auto view_x = items.at(0).get(); - EXPECT_EQ(view_x->item(), item.getItem(VectorItem::P_X)); - - auto view_y = items.at(1).get(); - EXPECT_EQ(view_y->item(), item.getItem(VectorItem::P_Y)); - - auto view_z = items.at(2).get(); - EXPECT_EQ(view_z->item(), item.getItem(VectorItem::P_Z)); -} - -//! Checks row label construction for vector item. - -TEST_F(PropertiesRowStrategyTest, vectorItemAutoLabels) -{ - VectorItem item; - - EXPECT_EQ(item.property<double>(VectorItem::P_X), 0.0); - EXPECT_EQ(item.property<double>(VectorItem::P_Y), 0.0); - EXPECT_EQ(item.property<double>(VectorItem::P_Z), 0.0); - - QStringList expected = QStringList() << "X" - << "Y" - << "Z"; - - PropertiesRowStrategy strategy; - auto items = strategy.constructRow(&item); - EXPECT_EQ(strategy.horizontalHeaderLabels(), expected); -} - -//! Row construction for rootItem with single item inserted. Shouldn't generate any row. - -TEST_F(PropertiesRowStrategyTest, baseItemInModelContext) -{ - SessionModel model; - - PropertiesRowStrategy strategy; - auto items = strategy.constructRow(model.rootItem()); - EXPECT_EQ(items.size(), 0); - - model.insertItem<SessionItem>(); - items = strategy.constructRow(model.rootItem()); - EXPECT_EQ(items.size(), 0); -} - -//! Row construction for rootItem with single item inserted. Shouldn't generate any row. - -TEST_F(PropertiesRowStrategyTest, propertyItemTree) -{ - SessionModel model; - auto parent = model.insertItem<SessionItem>(); - - parent->registerTag(TagInfo::universalTag("universal_tag")); - parent->registerTag(TagInfo::propertyTag("property_tag", GUI::Constants::PropertyType)); - - model.insertItem<SessionItem>(parent, "universal_tag"); - model.insertItem<PropertyItem>(parent, "property_tag"); - - PropertiesRowStrategy strategy; - auto items = strategy.constructRow(model.rootItem()); - - // root item doesn't have properties - EXPECT_EQ(items.size(), 0); - - // parent has one registered property. - items = strategy.constructRow(parent); - EXPECT_EQ(items.size(), 1); -} - -//! Row construction for rootItem when vectorItem is present. Shouldn't generate any row. - -TEST_F(PropertiesRowStrategyTest, vectorItemInModelContext) -{ - SessionModel model; - model.insertItem<VectorItem>(); - - PropertiesRowStrategy strategy; - auto items = strategy.constructRow(model.rootItem()); - EXPECT_EQ(items.size(), 0); -} diff --git a/mvvm/tests/testviewmodel/propertyflatviewmodel.test.cpp b/mvvm/tests/testviewmodel/propertyflatviewmodel.test.cpp deleted file mode 100644 index 06fcefdb7ad4772c8cc4c864cf9f25847ad343f8..0000000000000000000000000000000000000000 --- a/mvvm/tests/testviewmodel/propertyflatviewmodel.test.cpp +++ /dev/null @@ -1,122 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testviewmodel/propertyflatviewmodel.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/model/propertyitem.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/model/taginfo.h" -#include "mvvm/standarditems/vectoritem.h" -#include "mvvm/viewmodel/propertyflatviewmodel.h" -#include "toyitems.h" -#include "toymodel.h" - -using namespace ModelView; - -//! Tests for PropertyFlatViewModel class. - -class PropertyFlatViewModelTest : public ::testing::Test { -public: - ~PropertyFlatViewModelTest(); -}; - -PropertyFlatViewModelTest::~PropertyFlatViewModelTest() = default; - -TEST_F(PropertyFlatViewModelTest, initialState) -{ - SessionModel model; - PropertyFlatViewModel viewModel(&model); - EXPECT_EQ(viewModel.rowCount(), 0); - EXPECT_EQ(viewModel.columnCount(), 0); - EXPECT_EQ(viewModel.sessionItemFromIndex(QModelIndex()), model.rootItem()); -} - -TEST_F(PropertyFlatViewModelTest, baseItem) -{ - SessionModel model; - model.insertItem<SessionItem>(); - - PropertyFlatViewModel viewModel(&model); - - // Root item has default tag and all items considered as top items. - // PropertyViewModel shouldn't see any items. - EXPECT_EQ(viewModel.rowCount(), 0); - EXPECT_EQ(viewModel.columnCount(), 0); -} - -TEST_F(PropertyFlatViewModelTest, propertyItem) -{ - SessionModel model; - auto parent = model.insertItem<SessionItem>(); - - parent->registerTag(TagInfo::universalTag("universal_tag")); - parent->registerTag(TagInfo::propertyTag("property_tag", GUI::Constants::PropertyType)); - - model.insertItem<SessionItem>(parent, "universal_tag"); - model.insertItem<PropertyItem>(parent, "property_tag"); - model.insertItem<SessionItem>(parent, "universal_tag"); - - PropertyFlatViewModel viewModel(&model); - viewModel.setRootSessionItem(parent); - - // View model should see only property item belonging to parent. - EXPECT_EQ(viewModel.rowCount(), 1); - EXPECT_EQ(viewModel.columnCount(), 2); -} - -//! VectorItem in a model. - -TEST_F(PropertyFlatViewModelTest, vectorItem) -{ - SessionModel model; - auto parent = model.insertItem<VectorItem>(); - - PropertyFlatViewModel viewModel(&model); - - EXPECT_EQ(viewModel.rowCount(), 0); // root item doesn't have properties - EXPECT_EQ(viewModel.columnCount(), 0); - - // switching to vectorItem and checking that it has 3 properties - viewModel.setRootSessionItem(parent); - EXPECT_EQ(viewModel.rowCount(), 3); - EXPECT_EQ(viewModel.columnCount(), 2); -} - -//! ParticleItem in a model - -TEST_F(PropertyFlatViewModelTest, particleItem) -{ - ToyItems::SampleModel model; - auto particle = model.insertItem<ToyItems::ParticleItem>(); - auto group = dynamic_cast<GroupItem*>(particle->getItem(ToyItems::ParticleItem::P_SHAPES)); - group->setCurrentType(ToyItems::GUI::Constants::SphereItemType); - - PropertyFlatViewModel viewModel(&model); - viewModel.setRootSessionItem(particle); - - // We should see 3 rows: VectorItem, GroupItem itself, and Radius of sphere - EXPECT_EQ(viewModel.rowCount(), 3); - EXPECT_EQ(viewModel.columnCount(), 2); - - // switching group - group->setCurrentType(ToyItems::GUI::Constants::CylinderItemType); - // We should see 3 rows: VectorItem, GroupItem itself, Cylinderr length and radius - EXPECT_EQ(viewModel.rowCount(), 4); - EXPECT_EQ(viewModel.columnCount(), 2); - - // switching back - group->setCurrentType(ToyItems::GUI::Constants::SphereItemType); - EXPECT_EQ(viewModel.rowCount(), 3); - EXPECT_EQ(viewModel.columnCount(), 2); -} diff --git a/mvvm/tests/testviewmodel/propertytableviewmodel.test.cpp b/mvvm/tests/testviewmodel/propertytableviewmodel.test.cpp deleted file mode 100644 index 1f41631216835d6a1ee794ed791b7040ebf66cb7..0000000000000000000000000000000000000000 --- a/mvvm/tests/testviewmodel/propertytableviewmodel.test.cpp +++ /dev/null @@ -1,135 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testviewmodel/propertytableviewmodel.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/model/propertyitem.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/model/taginfo.h" -#include "mvvm/standarditems/vectoritem.h" -#include "mvvm/viewmodel/propertytableviewmodel.h" -#include "toyitems.h" - -using namespace ModelView; - -class PropertyTableViewModelTest : public ::testing::Test { -public: - ~PropertyTableViewModelTest(); -}; - -PropertyTableViewModelTest::~PropertyTableViewModelTest() = default; - -TEST_F(PropertyTableViewModelTest, initialState) -{ - SessionModel model; - PropertyTableViewModel viewModel(&model); - EXPECT_EQ(viewModel.rowCount(), 0); - EXPECT_EQ(viewModel.columnCount(), 0); - EXPECT_EQ(viewModel.sessionItemFromIndex(QModelIndex()), model.rootItem()); -} - -TEST_F(PropertyTableViewModelTest, baseItem) -{ - SessionModel model; - model.insertItem<SessionItem>(); - - PropertyTableViewModel viewModel(&model); - - EXPECT_EQ(viewModel.rowCount(), 0); - EXPECT_EQ(viewModel.columnCount(), 0); -} - -TEST_F(PropertyTableViewModelTest, propertyItem) -{ - SessionModel model; - auto parent = model.insertItem<SessionItem>(); - - parent->registerTag(TagInfo::universalTag("universal_tag")); - parent->registerTag(TagInfo::propertyTag("property_tag", GUI::Constants::PropertyType)); - - model.insertItem<SessionItem>(parent, "universal_tag"); - model.insertItem<PropertyItem>(parent, "property_tag"); - model.insertItem<SessionItem>(parent, "universal_tag"); - - PropertyTableViewModel viewModel(&model); - - // one cell corresponding to single item at property_tag of our parent - EXPECT_EQ(viewModel.rowCount(), 1); - EXPECT_EQ(viewModel.columnCount(), 1); - - viewModel.setRootSessionItem(parent); - EXPECT_EQ(viewModel.rowCount(), 0); - EXPECT_EQ(viewModel.columnCount(), 0); -} - -//! VectorItem in a model. - -TEST_F(PropertyTableViewModelTest, vectorItem) -{ - SessionModel model; - auto parent = model.insertItem<VectorItem>(); - - PropertyTableViewModel viewModel(&model); - - EXPECT_EQ(viewModel.rowCount(), 1); - EXPECT_EQ(viewModel.columnCount(), 3); - - // switching to vectorItem and checking that it has 3 properties - viewModel.setRootSessionItem(parent); - EXPECT_EQ(viewModel.rowCount(), 0); - EXPECT_EQ(viewModel.columnCount(), 0); -} - -//! MultiLayer with layers, view model still looks to the RootItem. -//! No MultiLayer should be visible in table. - -TEST_F(PropertyTableViewModelTest, multiLayerAndRootItem) -{ - SessionModel model; - auto multilayer = model.insertItem<ToyItems::MultiLayerItem>(); - model.insertItem<ToyItems::LayerItem>(multilayer); - model.insertItem<ToyItems::LayerItem>(multilayer); - - PropertyTableViewModel viewModel(&model); - - // ViewModel should be empty, since we are looking to RootItem. - EXPECT_EQ(viewModel.rowCount(), 0); - EXPECT_EQ(viewModel.columnCount(), 0); -} - -//! MultiLayer with layers, multilayer is given as root index. - -TEST_F(PropertyTableViewModelTest, multiLayer) -{ - SessionModel model; - auto multilayer = model.insertItem<ToyItems::MultiLayerItem>(); - model.insertItem<ToyItems::LayerItem>(multilayer); - model.insertItem<ToyItems::LayerItem>(multilayer); - - PropertyTableViewModel viewModel(&model); - viewModel.setRootSessionItem(multilayer); - - EXPECT_EQ(viewModel.rowCount(), 2); // two layers - EXPECT_EQ(viewModel.columnCount(), 2); // layer thickness and color - - // add another layer - model.insertItem<ToyItems::LayerItem>(multilayer); - EXPECT_EQ(viewModel.rowCount(), 3); // two layers - EXPECT_EQ(viewModel.columnCount(), 2); // layer thickness and color - - // switching view model back to model's root, table should be empty - viewModel.setRootSessionItem(model.rootItem()); - EXPECT_EQ(viewModel.rowCount(), 0); // two layers - EXPECT_EQ(viewModel.columnCount(), 0); // layer thickness and color -} diff --git a/mvvm/tests/testviewmodel/propertyviewmodel.test.cpp b/mvvm/tests/testviewmodel/propertyviewmodel.test.cpp deleted file mode 100644 index 101051411c1cc1a4cb4932672004b8c452afdafb..0000000000000000000000000000000000000000 --- a/mvvm/tests/testviewmodel/propertyviewmodel.test.cpp +++ /dev/null @@ -1,116 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testviewmodel/propertyviewmodel.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/model/propertyitem.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/model/taginfo.h" -#include "mvvm/standarditems/vectoritem.h" -#include "mvvm/viewmodel/propertyviewmodel.h" -#include "toyitems.h" -#include "toymodel.h" - -using namespace ModelView; - -//! Tests for PropertyViewModel class. - -class PropertyViewModelTest : public ::testing::Test { -public: - ~PropertyViewModelTest(); -}; - -PropertyViewModelTest::~PropertyViewModelTest() = default; - -TEST_F(PropertyViewModelTest, initialState) -{ - SessionModel model; - PropertyViewModel viewModel(&model); - EXPECT_EQ(viewModel.rowCount(), 0); - EXPECT_EQ(viewModel.columnCount(), 0); - EXPECT_EQ(viewModel.sessionItemFromIndex(QModelIndex()), model.rootItem()); -} - -TEST_F(PropertyViewModelTest, baseItem) -{ - SessionModel model; - model.insertItem<SessionItem>(); - - PropertyViewModel viewModel(&model); - - // Root item has default tag and all items considered as top items. - // PropertyViewModel shouldn't see any items. - EXPECT_EQ(viewModel.rowCount(), 0); - EXPECT_EQ(viewModel.columnCount(), 0); -} - -TEST_F(PropertyViewModelTest, propertyItem) -{ - SessionModel model; - auto parent = model.insertItem<SessionItem>(); - - parent->registerTag(TagInfo::universalTag("universal_tag")); - parent->registerTag(TagInfo::propertyTag("property_tag", GUI::Constants::PropertyType)); - - model.insertItem<SessionItem>(parent, "universal_tag"); - model.insertItem<PropertyItem>(parent, "property_tag"); - model.insertItem<SessionItem>(parent, "universal_tag"); - - PropertyViewModel viewModel(&model); - viewModel.setRootSessionItem(parent); - - // View model should see only property item belonging to parent. - EXPECT_EQ(viewModel.rowCount(), 1); - EXPECT_EQ(viewModel.columnCount(), 2); -} - -//! VectorItem in a model. - -TEST_F(PropertyViewModelTest, vectorItem) -{ - SessionModel model; - auto parent = model.insertItem<VectorItem>(); - - PropertyViewModel viewModel(&model); - - EXPECT_EQ(viewModel.rowCount(), 0); // root item doesn't have properties - EXPECT_EQ(viewModel.columnCount(), 0); - - // switching to vectorItem and checking that it has 3 properties - viewModel.setRootSessionItem(parent); - EXPECT_EQ(viewModel.rowCount(), 3); - EXPECT_EQ(viewModel.columnCount(), 2); -} - -//! LayerItem in a MultiLayer. - -TEST_F(PropertyViewModelTest, layerInMultiLayerAsRootItem) -{ - SessionModel model; - auto multilayer = model.insertItem<ToyItems::MultiLayerItem>(); - auto layer = model.insertItem<ToyItems::LayerItem>(multilayer); - - PropertyViewModel viewmodel(&model); - viewmodel.setRootSessionItem(layer); - - // check layer thickness and color - EXPECT_EQ(viewmodel.rowCount(), 2); - EXPECT_EQ(viewmodel.columnCount(), 2); - - // remove multilayer - model.removeItem(model.rootItem(), {"", 0}); - - EXPECT_EQ(viewmodel.rowCount(), 0); - EXPECT_EQ(viewmodel.columnCount(), 0); -} diff --git a/mvvm/tests/testviewmodel/scientificspinbox.test.cpp b/mvvm/tests/testviewmodel/scientificspinbox.test.cpp deleted file mode 100644 index 80140ca03aa1eb86df337891b0f29c866a81ae19..0000000000000000000000000000000000000000 --- a/mvvm/tests/testviewmodel/scientificspinbox.test.cpp +++ /dev/null @@ -1,128 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testviewmodel/scientificspinbox.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/editors/scientificspinbox.h" -#include <limits> - -using namespace ModelView; - -class ScientificSpinBoxTest : public ::testing::Test { -public: - ~ScientificSpinBoxTest() override; -}; - -ScientificSpinBoxTest::~ScientificSpinBoxTest() = default; - -TEST_F(ScientificSpinBoxTest, testValueFromText) -{ - QLocale locale(QLocale::C); - locale.setNumberOptions(QLocale::RejectGroupSeparator); - - QDoubleValidator validator; - validator.setLocale(locale); - validator.setNotation(QDoubleValidator::ScientificNotation); - - auto to_value = [&validator](QString text) { - return ScientificSpinBox::toDouble(text, validator, std::numeric_limits<double>::lowest(), - std::numeric_limits<double>::max(), 0.1); - }; - - // translation fails - EXPECT_EQ(0.1, to_value(QString("abcd"))); - EXPECT_EQ(0.1, to_value(QString("1,2"))); - EXPECT_EQ(0.1, to_value(QString("100,000,000.2"))); - EXPECT_EQ(0.1, to_value(QString("100.000.000.2"))); - EXPECT_EQ(0.1, to_value(QString("1e+2345"))); - EXPECT_EQ(0.1, to_value(QString("-1e+2345"))); - EXPECT_EQ(0.1, to_value(QString("1e-2345"))); - EXPECT_EQ(0.1, to_value(QString("-1e-2345"))); - EXPECT_EQ(0.1, to_value(QString("--0.1"))); - EXPECT_EQ(0.1, to_value(QString("-.e-12"))); - EXPECT_EQ(0.1, to_value(QString())); - - auto to_value_2 = [&validator](QString text) { - return ScientificSpinBox::toDouble(text, validator, -0.1, 1e+7, 0.1); - }; - - // translation fails due to out-of-bounds condition - EXPECT_EQ(0.1, to_value_2(QString("-0.2"))); - EXPECT_EQ(0.1, to_value_2(QString("-0.1e+1"))); - EXPECT_EQ(0.1, to_value_2(QString("1e+8"))); - - // legitimate values - EXPECT_EQ(-0.0999, to_value_2(QString("-0.0999"))); - EXPECT_EQ(-1e-13, to_value_2(QString("-.1e-12"))); - EXPECT_EQ(0.0, to_value_2(QString("0"))); - EXPECT_EQ(0.123, to_value_2(QString("0.123"))); - EXPECT_EQ(1e+6, to_value_2(QString("1e+6"))); - EXPECT_EQ(1.1e+6, to_value_2(QString("1.1e+6"))); - EXPECT_EQ(0.012, to_value_2(QString("0.012"))); -} - -TEST_F(ScientificSpinBoxTest, toString) -{ - int decimals = 3; - auto to_string = [&decimals](double val) { return ScientificSpinBox::toString(val, decimals); }; - - EXPECT_EQ(std::string("-123.45"), to_string(-123.45).toStdString()); - EXPECT_EQ(std::string("-100"), to_string(-99.9999).toStdString()); - EXPECT_EQ(std::string("-99.999"), to_string(-99.9994).toStdString()); - EXPECT_EQ(std::string("-10.123"), to_string(-10.12345).toStdString()); - EXPECT_EQ(std::string("-1"), to_string(-1.).toStdString()); - EXPECT_EQ(std::string("-0.1"), to_string(-0.1).toStdString()); - EXPECT_EQ(std::string("-0.1"), to_string(-0.1).toStdString()); - EXPECT_EQ(std::string("-9.99e-2"), to_string(-9.99e-2).toStdString()); - EXPECT_EQ(std::string("-1.266e-12"), to_string(-1.26555e-12).toStdString()); - EXPECT_EQ(std::string("0"), to_string(-0.0).toStdString()); - EXPECT_EQ(std::string("0"), to_string(0.0).toStdString()); - EXPECT_EQ(std::string("1e-12"), to_string(1.e-12).toStdString()); - EXPECT_EQ(std::string("1.23e-12"), to_string(1.23e-12).toStdString()); - EXPECT_EQ(std::string("1e-2"), to_string(1.e-2).toStdString()); - EXPECT_EQ(std::string("1.5e-2"), to_string(1.5e-2).toStdString()); - EXPECT_EQ(std::string("1.523e-2"), to_string(1.5234e-2).toStdString()); - EXPECT_EQ(std::string("9.99e-2"), to_string(9.99e-2).toStdString()); - EXPECT_EQ(std::string("1e-1"), to_string(9.9999e-2).toStdString()); - EXPECT_EQ(std::string("0.1"), to_string(0.1).toStdString()); - EXPECT_EQ(std::string("1"), to_string(1.).toStdString()); - EXPECT_EQ(std::string("1.1"), to_string(1.1).toStdString()); - EXPECT_EQ(std::string("1.123"), to_string(1.12345).toStdString()); - EXPECT_EQ(std::string("10.123"), to_string(10.12345).toStdString()); - EXPECT_EQ(std::string("99.9"), to_string(99.9).toStdString()); - EXPECT_EQ(std::string("99.999"), to_string(99.9994).toStdString()); - EXPECT_EQ(std::string("100"), to_string(99.9999).toStdString()); - EXPECT_EQ(std::string("123.45"), to_string(123.45).toStdString()); - EXPECT_EQ(std::string("1e+4"), to_string(1.e+4).toStdString()); - EXPECT_EQ(std::string("1.265e+12"), to_string(1.265e+12).toStdString()); - EXPECT_EQ(std::string("1.266e+12"), to_string(1.26555e+12).toStdString()); - - decimals = 5; - EXPECT_EQ(std::string("1.23e-12"), to_string(1.23e-12).toStdString()); - EXPECT_EQ(std::string("1.52346e-2"), to_string(1.523456e-2).toStdString()); - EXPECT_EQ(std::string("1e-1"), to_string(9.999999e-2).toStdString()); - EXPECT_EQ(std::string("1.12346"), to_string(1.123455).toStdString()); - EXPECT_EQ(std::string("10.12346"), to_string(10.123456).toStdString()); - EXPECT_EQ(std::string("99.9"), to_string(99.9).toStdString()); - EXPECT_EQ(std::string("100"), to_string(99.999999).toStdString()); - EXPECT_EQ(std::string("123.45"), to_string(123.45).toStdString()); - EXPECT_EQ(std::string("1.26556e+12"), to_string(1.265556e+12).toStdString()); -} - -TEST_F(ScientificSpinBoxTest, round) -{ - auto round_3 = [](double val) { return ScientificSpinBox::round(val, 3); }; - EXPECT_DOUBLE_EQ(1.232e-12, round_3(1.2323e-12)); - EXPECT_DOUBLE_EQ(0.123, round_3(0.1232)); - EXPECT_DOUBLE_EQ(1.002e+2, round_3(100.2)); -} diff --git a/mvvm/tests/testviewmodel/standardchildrenstrategies.test.cpp b/mvvm/tests/testviewmodel/standardchildrenstrategies.test.cpp deleted file mode 100644 index 5463c8d230a8cafe8aac1ab2daf993842509debe..0000000000000000000000000000000000000000 --- a/mvvm/tests/testviewmodel/standardchildrenstrategies.test.cpp +++ /dev/null @@ -1,263 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testviewmodel/standardchildrenstrategies.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/model/compounditem.h" -#include "mvvm/model/propertyitem.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/model/taginfo.h" -#include "mvvm/standarditems/vectoritem.h" -#include "mvvm/viewmodel/standardchildrenstrategies.h" -#include "toyitems.h" -#include "toymodel.h" - -using namespace ModelView; - -class StandardChildrenStrategiesTest : public ::testing::Test { -public: - ~StandardChildrenStrategiesTest(); - - //! Helper class with two properties and one top level item on board. - class TestItem : public CompoundItem { - public: - TestItem() : CompoundItem("test") - { - addProperty("length", 8.0); - registerTag(TagInfo::universalTag("children"), /*set_as_default*/ true); - insertItem(new SessionItem, TagRow::append()); - addProperty("height", 12.0); - } - ~TestItem(); - }; - - struct ChildrenData { - std::string model_type; - std::string tag; - bool operator==(const ChildrenData& other) const - { - return model_type == other.model_type && tag == other.tag; - } - }; - - std::vector<ChildrenData> children_data(std::vector<SessionItem*> children) - { - std::vector<ChildrenData> result; - for (auto child : children) - result.push_back({child->modelType(), child->tagRow().tag}); - return result; - } -}; - -StandardChildrenStrategiesTest::~StandardChildrenStrategiesTest() = default; -StandardChildrenStrategiesTest::TestItem::~TestItem() = default; - -//! Testing AllChildrenStrategy. - -TEST_F(StandardChildrenStrategiesTest, AllChildrenStrategy) -{ - AllChildrenStrategy strategy; - - // nullptr - auto children = strategy.children(nullptr); - EXPECT_EQ(children.size(), 0); - - // empty item - SessionItem item1("model_type"); - children = strategy.children(&item1); - EXPECT_EQ(children.size(), 0); - - // VectorItem - VectorItem item2; - children = strategy.children(&item2); - EXPECT_EQ(children.size(), 3); - - // CompoundItem - CompoundItem item3; - item3.addProperty("height", 42.0); - children = strategy.children(&item3); - EXPECT_EQ(children.size(), 1); - - // TestItem - TestItem item4; - children = strategy.children(&item4); - EXPECT_EQ(children.size(), 3); - - // GroupItem - ToyItems::ShapeGroupItem item5; - item5.setCurrentType(ToyItems::GUI::Constants::CylinderItemType); - children = strategy.children(&item5); - EXPECT_EQ(children.size(), 3); // number of registered children -} - -//! Testing TopItemsStrategy. - -TEST_F(StandardChildrenStrategiesTest, TopItemsStrategy) -{ - TopItemsStrategy strategy; - - // nullptr - auto children = strategy.children(nullptr); - EXPECT_EQ(children.size(), 0); - - // empty item - SessionItem item1("model_type"); - children = strategy.children(&item1); - EXPECT_EQ(children.size(), 0); - - // VectorItem - VectorItem item2; - children = strategy.children(&item2); - EXPECT_EQ(children.size(), 0); - - // CompoundItem - CompoundItem item3; - item3.addProperty("height", 42.0); - children = strategy.children(&item3); - EXPECT_EQ(children.size(), 0); - - // TestItem - TestItem item4; - children = strategy.children(&item4); - EXPECT_EQ(children.size(), 1); - - // GroupItem - ToyItems::ShapeGroupItem item5; - item5.setCurrentType(ToyItems::GUI::Constants::CylinderItemType); - children = strategy.children(&item5); - EXPECT_EQ(children.size(), 3); // number of registered children -} - -//! Testing PropertyItemsStrategy. - -TEST_F(StandardChildrenStrategiesTest, PropertyItemsStrategy) -{ - PropertyItemsStrategy strategy; - - // nullptr - { - auto children = strategy.children(nullptr); - EXPECT_EQ(children.size(), 0); - } - - // empty item - { - SessionItem item("model_type"); - auto children = strategy.children(&item); - EXPECT_EQ(children.size(), 0); - } - - // VectorItem - { - VectorItem item; - auto children = strategy.children(&item); - EXPECT_EQ(children.size(), 3); - } - - // CompoundItem - { - CompoundItem item; - item.addProperty("height", 42.0); - auto children = strategy.children(&item); - EXPECT_EQ(children.size(), 1); - } - - // TestItem - { - TestItem item; - auto children = strategy.children(&item); - EXPECT_EQ(children.size(), 2); - } - - // GroupItem - { - ToyItems::ShapeGroupItem item; - item.setCurrentType(ToyItems::GUI::Constants::CylinderItemType); - auto children = strategy.children(&item); - EXPECT_EQ(children.size(), 2); - - std::vector<ChildrenData> expected_children_data{ - {GUI::Constants::PropertyType, ToyItems::CylinderItem::P_RADIUS}, - {GUI::Constants::PropertyType, ToyItems::CylinderItem::P_HEIGHT}}; - EXPECT_EQ(children_data(children), expected_children_data); - } -} - -//! Testing PropertyItemsFlatStrategy. - -TEST_F(StandardChildrenStrategiesTest, PropertyItemsFlatStrategy) -{ - PropertyItemsFlatStrategy strategy; - - // nullptr - { - auto children = strategy.children(nullptr); - EXPECT_EQ(children.size(), 0); - } - - // empty item - { - SessionItem item("model_type"); - auto children = strategy.children(&item); - EXPECT_EQ(children.size(), 0); - } - - // VectorItem - { - VectorItem item; - auto children = strategy.children(&item); - EXPECT_EQ(children.size(), 3); - } - - // CompoundItem - { - CompoundItem item; - item.addProperty("height", 42.0); - auto children = strategy.children(&item); - EXPECT_EQ(children.size(), 1); - } - - // TestItem - { - TestItem item; - auto children = strategy.children(&item); - EXPECT_EQ(children.size(), 2); - } - - // GroupItem - { - ToyItems::ShapeGroupItem item; - item.setCurrentType(ToyItems::GUI::Constants::CylinderItemType); - auto children = strategy.children(&item); - EXPECT_EQ(children.size(), 2); - - std::vector<ChildrenData> expected_children_data{ - {GUI::Constants::PropertyType, ToyItems::CylinderItem::P_RADIUS}, - {GUI::Constants::PropertyType, ToyItems::CylinderItem::P_HEIGHT}}; - EXPECT_EQ(children_data(children), expected_children_data); - } - - // ParticleItem - { - ToyItems::ParticleItem item; - auto children = strategy.children(&item); - EXPECT_EQ(children.size(), 3); - - std::vector<ChildrenData> expected_children_data{ - {GUI::Constants::VectorItemType, ToyItems::ParticleItem::P_POSITION}, - {ToyItems::GUI::Constants::ShapeGroupItemType, ToyItems::ParticleItem::P_SHAPES}, - {GUI::Constants::PropertyType, ToyItems::SphereItem::P_RADIUS}}; - - EXPECT_EQ(children_data(children), expected_children_data); - } -} diff --git a/mvvm/tests/testviewmodel/standardviewitems.test.cpp b/mvvm/tests/testviewmodel/standardviewitems.test.cpp deleted file mode 100644 index 0cdce6d947d00e281d9574dff46246125128dc57..0000000000000000000000000000000000000000 --- a/mvvm/tests/testviewmodel/standardviewitems.test.cpp +++ /dev/null @@ -1,269 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testviewmodel/standardviewitems.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/viewmodel/standardviewitems.h" -#include <QColor> -#include <memory> -#include <stdexcept> - -using namespace ModelView; - -class StandardViewItemsTest : public ::testing::Test { -public: - ~StandardViewItemsTest(); -}; - -StandardViewItemsTest::~StandardViewItemsTest() = default; - -// ---------------------------------------------------------------------------- -// Tests for ViewLabelItem -// ---------------------------------------------------------------------------- - -TEST_F(StandardViewItemsTest, ViewLabelItem_initialState) -{ - SessionItem item; - ViewLabelItem viewItem(&item); - EXPECT_EQ(viewItem.item(), &item); - EXPECT_EQ(viewItem.item_role(), ItemDataRole::DISPLAY); -} - -//! ViewLabelItem::data method -//! Checks that the data method is correctly forwarded to underlying SessionItem. - -TEST_F(StandardViewItemsTest, ViewLabelItem_data) -{ - // create SessionItem with data on board - SessionItem item; - const std::string expected("Layer"); - EXPECT_TRUE(item.setData(expected, ItemDataRole::DISPLAY)); - - // initialize viewItem with sessionItem and check the data - ViewLabelItem viewItem(&item); - EXPECT_EQ(Utils::toCustomVariant(viewItem.data(Qt::EditRole)), QVariant::fromValue(expected)); - EXPECT_EQ(Utils::toCustomVariant(viewItem.data(Qt::DisplayRole)), - QVariant::fromValue(expected)); -} - -//! ViewLabelItem::setData -//! Checks that the setData method is correctly forwarded to underlying SessionItem. - -TEST_F(StandardViewItemsTest, ViewLabelItem_setData) -{ - // create SessionItem with data on board - SessionItem item; - const std::string expected("Layer"); - EXPECT_TRUE(item.setData(expected, ItemDataRole::DISPLAY)); - - // initialize viewItem with sessionItem and set the data - ViewLabelItem viewItem(&item); - QVariant new_data("MultiLayer"); - EXPECT_TRUE(viewItem.setData(new_data, Qt::EditRole)); - EXPECT_EQ(viewItem.data(Qt::DisplayRole), new_data); // new data - EXPECT_EQ(viewItem.data(Qt::EditRole), new_data); // new data - - // SessionItem itself should have new data - EXPECT_EQ(item.data<QVariant>(ItemDataRole::DISPLAY), - Utils::toCustomVariant(new_data)); // new data - - // it is not allowed to set another type of data to ViewLabelItem - QVariant not_allowed_value(42); - EXPECT_THROW(viewItem.setData(not_allowed_value, Qt::EditRole), std::runtime_error); -} - -//! Testing ViewLabelItem::flags. - -TEST_F(StandardViewItemsTest, ViewLabelItem_flags) -{ - SessionItem item; - const std::string expected("Layer"); - EXPECT_TRUE(item.setData(expected, ItemDataRole::DISPLAY)); - - ViewLabelItem viewItem(&item); - EXPECT_FALSE(viewItem.flags() & Qt::ItemIsEditable); -} - -//! Testing tooltip tole. - -TEST_F(StandardViewItemsTest, ViewLabelItem_toolTipRole) -{ - SessionItem item; - - ViewLabelItem viewItem(&item); - EXPECT_FALSE(viewItem.data(Qt::ToolTipRole).isValid()); - - item.setToolTip("abc"); - EXPECT_EQ(viewItem.data(Qt::ToolTipRole).toString(), QString("abc")); -} - -// ---------------------------------------------------------------------------- -// Tests for ViewDataItem -// ---------------------------------------------------------------------------- - -TEST_F(StandardViewItemsTest, ViewDataItem_initialState) -{ - SessionItem item; - ViewDataItem viewItem(&item); - EXPECT_EQ(viewItem.item(), &item); - EXPECT_EQ(viewItem.item_role(), ItemDataRole::DATA); -} - -//! ViewDataItem::data method for double values. -//! Checks that the data method is correctly forwarded to underlying SessionItem. - -TEST_F(StandardViewItemsTest, ViewDataItem_dataForDouble) -{ - // create SessionItem with data on board - SessionItem item; - QVariant expected(42.0); - EXPECT_TRUE(item.setData(expected)); - - // initialize viewItem with sessionItem and check the data - ViewDataItem viewItem(&item); - EXPECT_EQ(viewItem.data(Qt::EditRole), expected); - EXPECT_EQ(viewItem.data(Qt::DisplayRole), expected); -} - -//! ViewDataItem::setData for double values. -//! Checks that the setData method is correctly forwarded to underlying SessionItem. - -TEST_F(StandardViewItemsTest, ViewDataItem_setDataForDouble) -{ - // create SessionItem with data on board - SessionItem item; - QVariant expected(42.0); - EXPECT_TRUE(item.setData(expected)); - - // initialize viewItem with sessionItem and set the data - ViewDataItem viewItem(&item); - QVariant new_data(43.0); - EXPECT_TRUE(viewItem.setData(new_data, Qt::EditRole)); - EXPECT_EQ(viewItem.data(Qt::DisplayRole), new_data); // new data - EXPECT_EQ(viewItem.data(Qt::EditRole), new_data); // new data - - // SessionItem itself should have new data - EXPECT_EQ(item.data<QVariant>(), new_data); // new data - - // it is not allowed to set another type of data to ViewDataItem - QVariant not_allowed_value("Layer"); - EXPECT_THROW(viewItem.setData(not_allowed_value, Qt::EditRole), std::runtime_error); -} - -//! ViewDataItem::setData for double values. -//! Checks that setting of same data returns false. - -TEST_F(StandardViewItemsTest, ViewDataItem_setSameData) -{ - // create SessionItem with data on board - SessionItem item; - QVariant expected(42.0); - EXPECT_TRUE(item.setData(expected)); - - // initialize viewItem with sessionItem and set the data - ViewDataItem viewItem(&item); - QVariant new_data(42.0); - EXPECT_FALSE(viewItem.setData(new_data, Qt::EditRole)); - EXPECT_EQ(viewItem.data(Qt::EditRole), new_data); // new data -} - -//! ViewDataItem::data method for QColor. -//! Checks that the data method is correctly forwarded to underlying SessionItem. - -TEST_F(StandardViewItemsTest, ViewDataItem_dataForColor) -{ - // create SessionItem with data on board - SessionItem item; - QVariant expected = QVariant::fromValue(QColor(Qt::green)); - EXPECT_TRUE(item.setData(expected)); - - ViewDataItem viewItem(&item); - EXPECT_EQ(viewItem.data(Qt::EditRole), expected); - EXPECT_EQ(viewItem.data(Qt::DisplayRole), expected); - EXPECT_EQ(viewItem.data(Qt::DecorationRole), expected); -} - -//! ViewDataItem::setData for QColor. -//! Checks that the setData method is correctly forwarded to underlying SessionItem. - -TEST_F(StandardViewItemsTest, ViewDataItem_setDataForColor) -{ - // create SessionItem with data on board - SessionItem item; - QVariant expected = QVariant::fromValue(QColor(Qt::green)); - EXPECT_TRUE(item.setData(expected)); - - // initialize viewItem with sessionItem and set the data - ViewDataItem viewItem(&item); - QVariant new_data = QVariant::fromValue(QColor(Qt::red)); - EXPECT_TRUE(viewItem.setData(new_data, Qt::EditRole)); - EXPECT_EQ(viewItem.data(Qt::DisplayRole), new_data); // new data - EXPECT_EQ(viewItem.data(Qt::EditRole), new_data); // new data - EXPECT_EQ(viewItem.data(Qt::DecorationRole), new_data); // new data - - // SessionItem itself should have new data - EXPECT_EQ(item.data<QVariant>(), new_data); // new data - - // it is not allowed to set another type of data to ViewDataItem - QVariant not_allowed_value("Layer"); - EXPECT_THROW(viewItem.setData(not_allowed_value, Qt::EditRole), std::runtime_error); -} - -//! Testing ViewLabelItem::flags. - -TEST_F(StandardViewItemsTest, ViewDataItem_flags) -{ - SessionItem item; - QVariant expected = QVariant::fromValue(std::string("Layer")); - EXPECT_TRUE(item.setData(expected, ItemDataRole::DATA)); - - ViewDataItem viewItem(&item); - EXPECT_TRUE(viewItem.flags() & Qt::ItemIsEditable); -} - -//! Testing tooltip tole. - -TEST_F(StandardViewItemsTest, ViewDataItem_toolTipRole) -{ - SessionItem item; - - ViewDataItem viewItem(&item); - EXPECT_FALSE(viewItem.data(Qt::ToolTipRole).isValid()); - - item.setToolTip("abc"); - EXPECT_EQ(viewItem.data(Qt::ToolTipRole).toString(), QString("abc")); -} - -//! Behavior of ViewDataItem with SessionItem which initially contains invalid data. -//! It should be possible to set data after. - -TEST_F(StandardViewItemsTest, ViewDataItem_invalidTheValidData) -{ - SessionItem item; - ViewDataItem viewItem(&item); - - // initially data is invalid, and non-editable - EXPECT_FALSE(viewItem.flags() & Qt::ItemIsEditable); - EXPECT_FALSE(viewItem.data(Qt::EditRole).isValid()); - - // current behavior that setting data is still possible - EXPECT_TRUE(viewItem.setData(QVariant::fromValue(42.0), Qt::EditRole)); - - // setting data to original item - item.setData(43.0); - - // data became editable via ViewDataItem - EXPECT_TRUE(viewItem.flags() & Qt::ItemIsEditable); - EXPECT_EQ(viewItem.data(Qt::EditRole), QVariant::fromValue(43.0)); -} diff --git a/mvvm/tests/testviewmodel/topitemsviewmodel.test.cpp b/mvvm/tests/testviewmodel/topitemsviewmodel.test.cpp deleted file mode 100644 index fe93c1323404acca0179c8b16b1f09ff972989d5..0000000000000000000000000000000000000000 --- a/mvvm/tests/testviewmodel/topitemsviewmodel.test.cpp +++ /dev/null @@ -1,144 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testviewmodel/topitemsviewmodel.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/model/propertyitem.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/model/taginfo.h" -#include "mvvm/standarditems/vectoritem.h" -#include "mvvm/viewmodel/topitemsviewmodel.h" -#include "toyitems.h" -#include "toymodel.h" -#include <QSignalSpy> - -using namespace ModelView; - -//! Tests for TopItemsViewModel class. - -class TopItemsViewModelTest : public ::testing::Test { -public: - ~TopItemsViewModelTest(); -}; - -TopItemsViewModelTest::~TopItemsViewModelTest() = default; - -TEST_F(TopItemsViewModelTest, initialState) -{ - SessionModel model; - TopItemsViewModel viewModel(&model); - EXPECT_EQ(viewModel.rowCount(), 0); - EXPECT_EQ(viewModel.columnCount(), 0); - EXPECT_EQ(viewModel.sessionItemFromIndex(QModelIndex()), model.rootItem()); -} - -//! Insert LayerItem in empty model. - -TEST_F(TopItemsViewModelTest, insertLayerThenRemove) -{ - ToyItems::SampleModel model; - TopItemsViewModel viewmodel(&model); - - QSignalSpy spyInsert(&viewmodel, &ViewModelBase::rowsInserted); - QSignalSpy spyRemove(&viewmodel, &ViewModelBase::rowsRemoved); - - model.insertItem<ToyItems::LayerItem>(); - - EXPECT_EQ(viewmodel.rowCount(QModelIndex()), 1); - EXPECT_EQ(viewmodel.columnCount(QModelIndex()), 2); - - EXPECT_EQ(spyRemove.count(), 0); - EXPECT_EQ(spyInsert.count(), 1); - - model.removeItem(model.rootItem(), {"", 0}); - EXPECT_EQ(spyRemove.count(), 1); - EXPECT_EQ(spyInsert.count(), 1); - - EXPECT_EQ(viewmodel.rowCount(QModelIndex()), 0); - EXPECT_EQ(viewmodel.columnCount(QModelIndex()), 0); -} - -//! Insert LayerItem in MultiLayer. - -TEST_F(TopItemsViewModelTest, insertLayerInMultiLayerThenRemove) -{ - ToyItems::SampleModel model; - TopItemsViewModel viewmodel(&model); - - QSignalSpy spyInsert(&viewmodel, &ViewModelBase::rowsInserted); - QSignalSpy spyRemove(&viewmodel, &ViewModelBase::rowsRemoved); - - // inserting multilayer - auto multilayer = model.insertItem<ToyItems::MultiLayerItem>(); - - EXPECT_EQ(viewmodel.rowCount(QModelIndex()), 1); - EXPECT_EQ(viewmodel.columnCount(QModelIndex()), 2); - EXPECT_EQ(spyRemove.count(), 0); - EXPECT_EQ(spyInsert.count(), 1); - - // insert layer - auto layer = model.insertItem<ToyItems::LayerItem>(multilayer); - EXPECT_EQ(viewmodel.rowCount(QModelIndex()), 1); - EXPECT_EQ(viewmodel.columnCount(QModelIndex()), 2); - EXPECT_EQ(spyRemove.count(), 0); - EXPECT_EQ(spyInsert.count(), 2); - - // checking their indices - auto multiiLayer = viewmodel.index(0, 0, QModelIndex()); - auto i_layer = viewmodel.index(0, 0, multiiLayer); - EXPECT_EQ(viewmodel.sessionItemFromIndex(multiiLayer), multilayer); - EXPECT_EQ(viewmodel.sessionItemFromIndex(i_layer), layer); - - // checking row and columns - EXPECT_EQ(viewmodel.rowCount(multiiLayer), 1); - EXPECT_EQ(viewmodel.columnCount(multiiLayer), 2); - EXPECT_EQ(viewmodel.rowCount(i_layer), 0); - EXPECT_EQ(viewmodel.columnCount(i_layer), 0); - - // removing layer - model.removeItem(multilayer, {"", 0}); - EXPECT_EQ(spyRemove.count(), 1); - EXPECT_EQ(spyInsert.count(), 2); - EXPECT_EQ(viewmodel.rowCount(multiiLayer), 0); - EXPECT_EQ(viewmodel.columnCount(multiiLayer), 0); -} - -//! Insert LayerItem in MultiLayer while multilayer is root item. Then deleting multilayer. - -TEST_F(TopItemsViewModelTest, multuLayerAsRooItem) -{ - ToyItems::SampleModel model; - TopItemsViewModel viewmodel(&model); - - // setting up single multilayer playing the role - auto multilayer = model.insertItem<ToyItems::MultiLayerItem>(); - viewmodel.setRootSessionItem(multilayer); - QSignalSpy spyInsert(&viewmodel, &ViewModelBase::rowsInserted); - QSignalSpy spyRemove(&viewmodel, &ViewModelBase::rowsRemoved); - - // initial conditions - EXPECT_EQ(viewmodel.rowCount(QModelIndex()), 0); - EXPECT_EQ(viewmodel.columnCount(QModelIndex()), 0); - EXPECT_EQ(viewmodel.sessionItemFromIndex(QModelIndex()), multilayer); // our new root - - // adding layer - model.insertItem<ToyItems::LayerItem>(multilayer); - EXPECT_EQ(viewmodel.rowCount(QModelIndex()), 1); - EXPECT_EQ(viewmodel.columnCount(QModelIndex()), 2); - EXPECT_EQ(spyRemove.count(), 0); - EXPECT_EQ(spyInsert.count(), 1); - - // removing multilayer - model.removeItem(model.rootItem(), {"", 0}); -} diff --git a/mvvm/tests/testviewmodel/viewitem.test.cpp b/mvvm/tests/testviewmodel/viewitem.test.cpp deleted file mode 100644 index 532b911fc1a4333a92c770159b752d930da95088..0000000000000000000000000000000000000000 --- a/mvvm/tests/testviewmodel/viewitem.test.cpp +++ /dev/null @@ -1,232 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testviewmodel/viewitem.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/viewmodel/viewitem.h" -#include "test_utils.h" -#include <stdexcept> - -using namespace ModelView; - -//! Tests for ViewItem class. - -class ViewItemTest : public ::testing::Test { -public: - ~ViewItemTest(); - class TestItem : public ViewItem { - public: - TestItem() : ViewItem(nullptr, 0) {} - ~TestItem() override; - }; - - using children_t = std::vector<std::unique_ptr<ViewItem>>; - using expected_t = std::vector<ViewItem*>; - - //! Helper function to get two vectors, each ncolumns length, in the form of a pair. - //! First vector contains unique_ptr objects, second vector bare pointers to same objects. - //! First vector is intended to be moved inside a model, second vector is to validate - //! the content of a model after the move. - - std::pair<children_t, expected_t> test_data(int ncolumns) - { - auto vector_of_unique = TestUtils::create_row<ViewItem, TestItem>(ncolumns); - auto vector_of_pointers = TestUtils::create_pointers(vector_of_unique); - return std::make_pair(std::move(vector_of_unique), std::move(vector_of_pointers)); - } -}; - -ViewItemTest::~ViewItemTest() = default; -ViewItemTest::TestItem::~TestItem() = default; - -//! Initial state of RefViewItem. - -TEST_F(ViewItemTest, initialState) -{ - TestItem view_item; - - EXPECT_EQ(view_item.rowCount(), 0); - EXPECT_EQ(view_item.columnCount(), 0); - EXPECT_EQ(view_item.row(), -1); - EXPECT_EQ(view_item.column(), -1); - EXPECT_EQ(view_item.parent(), nullptr); - EXPECT_THROW(view_item.child(0, 0), std::runtime_error); - EXPECT_EQ(view_item.item(), nullptr); - EXPECT_EQ(view_item.item_role(), 0); -} - -//! Append single item as row. - -TEST_F(ViewItemTest, appendRow) -{ - auto [children, expected] = test_data(/*ncolumns*/ 1); - - // appending row with single item - TestItem view_item; - view_item.appendRow(std::move(children)); - - // checking parent - EXPECT_EQ(view_item.rowCount(), 1); - EXPECT_EQ(view_item.columnCount(), 1); - EXPECT_EQ(view_item.child(0, 0), expected[0]); - EXPECT_THROW(view_item.child(0, 1), std::runtime_error); - - // checking appended child - EXPECT_EQ(expected[0]->parent(), &view_item); - EXPECT_EQ(expected[0]->row(), 0); - EXPECT_EQ(expected[0]->column(), 0); -} - -//! Remove row. - -TEST_F(ViewItemTest, removeRow) -{ - auto [children, expected] = test_data(/*ncolumns*/ 1); - - // appending row with single item - TestItem view_item; - view_item.appendRow(std::move(children)); - view_item.removeRow(0); - - // checking parent - EXPECT_EQ(view_item.rowCount(), 0); - EXPECT_EQ(view_item.columnCount(), 0); -} - -//! Append two rows with two items each. - -TEST_F(ViewItemTest, appendTwoRows) -{ - // preparing two rows of children, two columns each - auto [children_row0, expected_row0] = test_data(/*ncolumns*/ 2); - auto [children_row1, expected_row1] = test_data(/*ncolumns*/ 2); - - // appending rows - TestItem view_item; - view_item.appendRow(std::move(children_row0)); - view_item.appendRow(std::move(children_row1)); - - EXPECT_EQ(view_item.rowCount(), 2); - EXPECT_EQ(view_item.columnCount(), 2); - EXPECT_EQ(view_item.child(0, 0), expected_row0[0]); - EXPECT_EQ(view_item.child(0, 1), expected_row0[1]); - EXPECT_EQ(view_item.child(1, 0), expected_row1[0]); - EXPECT_EQ(view_item.child(1, 1), expected_row1[1]); - EXPECT_THROW(view_item.child(2, 2), std::runtime_error); - - // checking parents - EXPECT_EQ(expected_row0[0]->parent(), &view_item); - EXPECT_EQ(expected_row0[1]->parent(), &view_item); - EXPECT_EQ(expected_row1[0]->parent(), &view_item); - EXPECT_EQ(expected_row1[1]->parent(), &view_item); - - // checking row and column of children - EXPECT_EQ(expected_row0[0]->row(), 0); - EXPECT_EQ(expected_row0[1]->row(), 0); - EXPECT_EQ(expected_row1[0]->row(), 1); - EXPECT_EQ(expected_row1[1]->row(), 1); - EXPECT_EQ(expected_row0[0]->column(), 0); - EXPECT_EQ(expected_row0[1]->column(), 1); - EXPECT_EQ(expected_row1[0]->column(), 0); - EXPECT_EQ(expected_row1[1]->column(), 1); - - // attempt to add row with different amount of children should fail - auto [children_row2, expected_row2] = test_data(/*ncolumns*/ 1); - EXPECT_THROW(view_item.appendRow(std::move(children_row2)), std::runtime_error); - EXPECT_EQ(view_item.rowCount(), 2); - EXPECT_EQ(view_item.columnCount(), 2); -} - -//! Append two rows with two items each. - -TEST_F(ViewItemTest, insertRowsThenRemove) -{ - // preparing two rows of children, two columns each - auto [children_row0, expected_row0] = test_data(/*ncolumns*/ 2); - auto [children_row1, expected_row1] = test_data(/*ncolumns*/ 2); - auto [children_row2, expected_row2] = test_data(/*ncolumns*/ 2); - - // appending rows - TestItem view_item; - view_item.appendRow(std::move(children_row0)); - view_item.appendRow(std::move(children_row1)); - view_item.insertRow(1, std::move(children_row2)); // inserting in-between - - EXPECT_EQ(view_item.rowCount(), 3); - EXPECT_EQ(view_item.columnCount(), 2); - EXPECT_EQ(view_item.child(0, 0), expected_row0[0]); - EXPECT_EQ(view_item.child(0, 1), expected_row0[1]); - EXPECT_EQ(view_item.child(1, 0), expected_row2[0]); - EXPECT_EQ(view_item.child(1, 1), expected_row2[1]); - EXPECT_EQ(view_item.child(2, 0), expected_row1[0]); - EXPECT_EQ(view_item.child(2, 1), expected_row1[1]); - - // checking parents - EXPECT_EQ(expected_row0[0]->parent(), &view_item); - EXPECT_EQ(expected_row0[1]->parent(), &view_item); - EXPECT_EQ(expected_row1[0]->parent(), &view_item); - EXPECT_EQ(expected_row1[1]->parent(), &view_item); - EXPECT_EQ(expected_row2[0]->parent(), &view_item); - EXPECT_EQ(expected_row2[1]->parent(), &view_item); - - // checking row and column of children - EXPECT_EQ(expected_row0[0]->row(), 0); - EXPECT_EQ(expected_row0[1]->row(), 0); - EXPECT_EQ(expected_row1[0]->row(), 2); - EXPECT_EQ(expected_row1[1]->row(), 2); - EXPECT_EQ(expected_row2[0]->row(), 1); - EXPECT_EQ(expected_row2[1]->row(), 1); - EXPECT_EQ(expected_row0[0]->column(), 0); - EXPECT_EQ(expected_row0[1]->column(), 1); - EXPECT_EQ(expected_row1[0]->column(), 0); - EXPECT_EQ(expected_row1[1]->column(), 1); - EXPECT_EQ(expected_row2[0]->column(), 0); - EXPECT_EQ(expected_row2[1]->column(), 1); - - // removing middle row - view_item.removeRow(1); - EXPECT_EQ(view_item.child(0, 0), expected_row0[0]); - EXPECT_EQ(view_item.child(0, 1), expected_row0[1]); - EXPECT_EQ(view_item.child(1, 0), expected_row1[0]); - EXPECT_EQ(view_item.child(1, 1), expected_row1[1]); -} - -//! Clean item's children. - -TEST_F(ViewItemTest, clear) -{ - auto [children, expected] = test_data(/*ncolumns*/ 1); - - TestItem view_item; - view_item.appendRow(std::move(children)); - view_item.clear(); - - EXPECT_EQ(view_item.rowCount(), 0); - EXPECT_EQ(view_item.columnCount(), 0); -} - -TEST_F(ViewItemTest, children) -{ - auto [children_row0, expected_row0] = test_data(/*ncolumns*/ 2); - auto [children_row1, expected_row1] = test_data(/*ncolumns*/ 2); - - TestItem view_item; - view_item.appendRow(std::move(children_row0)); - view_item.appendRow(std::move(children_row1)); - - std::vector<ViewItem*> expected; - std::copy(expected_row0.begin(), expected_row0.end(), std::back_inserter(expected)); - std::copy(expected_row1.begin(), expected_row1.end(), std::back_inserter(expected)); - - EXPECT_EQ(view_item.children(), expected); -} diff --git a/mvvm/tests/testviewmodel/viewmodelbase.test.cpp b/mvvm/tests/testviewmodel/viewmodelbase.test.cpp deleted file mode 100644 index 8c5253b7484f29a77069d668b07c64c4229dcd84..0000000000000000000000000000000000000000 --- a/mvvm/tests/testviewmodel/viewmodelbase.test.cpp +++ /dev/null @@ -1,377 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testviewmodel/viewmodelbase.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/viewmodel/standardviewitems.h" -#include "mvvm/viewmodel/viewmodelbase.h" -#include "test_utils.h" -#include <QSignalSpy> -#include <QStandardItemModel> - -using namespace ModelView; - -//! Tests for ViewModelBase class. - -class ViewModelBaseTest : public ::testing::Test { -public: - ~ViewModelBaseTest(); - - class TestItem : public ViewItem { - public: - TestItem() : ViewItem(nullptr, 0) {} - ~TestItem() override; - }; - - using children_t = std::vector<std::unique_ptr<ViewItem>>; - using expected_t = std::vector<ViewItem*>; - - //! Helper function to get two vectors, each ncolumns length, in the form of a pair. - //! First vector contains unique_ptr objects, second vector bare pointers to same objects. - //! First vector is intended to be moved inside a model, second vector is to validate - //! the content of a model after the move. - - std::pair<children_t, expected_t> test_data(int ncolumns) - { - auto vector_of_unique = TestUtils::create_row<ViewItem, TestItem>(ncolumns); - auto vector_of_pointers = TestUtils::create_pointers(vector_of_unique); - return std::make_pair(std::move(vector_of_unique), std::move(vector_of_pointers)); - } -}; - -ViewModelBaseTest::~ViewModelBaseTest() = default; -ViewModelBaseTest::TestItem::~TestItem() = default; - -//! Checking behaviour of QStandardItemModel for reference. - -TEST_F(ViewModelBaseTest, standardItemModel) -{ - QStandardItemModel model; - auto parent = model.invisibleRootItem(); - - EXPECT_EQ(model.rowCount(), 0); - EXPECT_EQ(model.columnCount(), 0); - - QList<QStandardItem*> children{new QStandardItem, new QStandardItem}; - parent->appendRow(children); - auto index = model.index(0, 1, QModelIndex()); - EXPECT_EQ(model.itemFromIndex(index), children.at(1)); - - // construction of index for non-existing column leads to invalid index - auto non_existing_index = model.index(0, 2, QModelIndex()); - EXPECT_FALSE(non_existing_index.isValid()); - EXPECT_EQ(non_existing_index, QModelIndex()); - - // attempt to retrieve item using this non-existing index leads to nullptr. - EXPECT_EQ(model.itemFromIndex(non_existing_index), nullptr); - - // default constructed index gives same nullptr - EXPECT_EQ(model.itemFromIndex(QModelIndex()), nullptr); - - // to summarize, default-constructed index, invalid index and index leading to non-existing - // item are the same -} - -//! Initial state of empty ViewModelBase. - -TEST_F(ViewModelBaseTest, initialState) -{ - ViewModelBase viewmodel; - EXPECT_EQ(viewmodel.rowCount(), 0); - EXPECT_EQ(viewmodel.columnCount(), 0); - EXPECT_TRUE(viewmodel.rootItem() != nullptr); - EXPECT_EQ(viewmodel.itemFromIndex(QModelIndex()), nullptr); - auto non_existing_index = viewmodel.index(0, 0, QModelIndex()); - EXPECT_FALSE(non_existing_index.isValid()); - EXPECT_EQ(viewmodel.itemFromIndex(non_existing_index), nullptr); - EXPECT_EQ(viewmodel.parent(QModelIndex()), QModelIndex()); - EXPECT_EQ(viewmodel.indexFromItem(viewmodel.rootItem()), QModelIndex()); -} - -TEST_F(ViewModelBaseTest, appendRow) -{ - ViewModelBase viewmodel; - - // item to append - auto [children, expected] = test_data(/*ncolumns*/ 1); - - // appending one row - viewmodel.appendRow(viewmodel.rootItem(), std::move(children)); - EXPECT_EQ(viewmodel.rowCount(), 1); - EXPECT_EQ(viewmodel.columnCount(), 1); - - // constructing index for child - auto child_index = viewmodel.index(0, 0, QModelIndex()); - EXPECT_EQ(child_index.row(), 0); - EXPECT_EQ(child_index.column(), 0); - EXPECT_EQ(child_index.model(), &viewmodel); - - // indexFromItem - EXPECT_EQ(viewmodel.indexFromItem(expected[0]), child_index); - - // getting child from index - EXPECT_EQ(viewmodel.itemFromIndex(child_index), expected[0]); - - // no grand-children - EXPECT_EQ(viewmodel.rowCount(child_index), 0); - EXPECT_EQ(viewmodel.columnCount(child_index), 0); - - // parent index - EXPECT_EQ(viewmodel.parent(child_index), QModelIndex()); -} - -//! Insert one row befor another. - -TEST_F(ViewModelBaseTest, insertRow) -{ - ViewModelBase viewmodel; - - // item to append - auto [children_row0, expected_row0] = test_data(/*ncolumns*/ 1); - auto [children_front, expected_front] = test_data(/*ncolumns*/ 1); - - // appending one row - viewmodel.appendRow(viewmodel.rootItem(), std::move(children_row0)); - viewmodel.insertRow(viewmodel.rootItem(), 0, std::move(children_front)); - EXPECT_EQ(viewmodel.rowCount(), 2); - EXPECT_EQ(viewmodel.columnCount(), 1); - - // constructing index for child - auto child_index0 = viewmodel.index(0, 0, QModelIndex()); - auto child_index1 = viewmodel.index(1, 0, QModelIndex()); - - // indexFromItem - EXPECT_EQ(viewmodel.indexFromItem(expected_row0[0]), child_index1); - EXPECT_EQ(viewmodel.indexFromItem(expected_front[0]), child_index0); - - // getting child from index - EXPECT_EQ(viewmodel.itemFromIndex(child_index0), expected_front[0]); - EXPECT_EQ(viewmodel.itemFromIndex(child_index1), expected_row0[0]); -} - -TEST_F(ViewModelBaseTest, removeRow) -{ - ViewModelBase viewmodel; - - // item to append - auto [children, expected] = test_data(/*ncolumns*/ 1); - - // appending one row - viewmodel.appendRow(viewmodel.rootItem(), std::move(children)); - EXPECT_EQ(viewmodel.rowCount(), 1); - EXPECT_EQ(viewmodel.columnCount(), 1); - - // removing row - viewmodel.removeRow(viewmodel.rootItem(), 0); - EXPECT_EQ(viewmodel.rowCount(), 0); - EXPECT_EQ(viewmodel.columnCount(), 0); -} - -TEST_F(ViewModelBaseTest, appendRowToRow) -{ - ViewModelBase viewmodel; - - // preparing two rows of children, two columns each - auto [children_row0, expected_row0] = test_data(/*ncolumns*/ 2); - auto [children_row1, expected_row1] = test_data(/*ncolumns*/ 2); - - // appending rows to root - viewmodel.appendRow(viewmodel.rootItem(), std::move(children_row0)); - // appending rows to row - auto child0_index = viewmodel.index(0, 0, QModelIndex()); - auto child1_index = viewmodel.index(0, 1, QModelIndex()); - viewmodel.appendRow(expected_row0[0], std::move(children_row1)); - - // checking results - EXPECT_EQ(viewmodel.rowCount(QModelIndex()), 1); - EXPECT_EQ(viewmodel.columnCount(QModelIndex()), 2); - EXPECT_EQ(viewmodel.rowCount(child0_index), 1); - EXPECT_EQ(viewmodel.columnCount(child0_index), 2); - - // checking parent index of children in second row - auto grandchild0_index = viewmodel.index(0, 0, child0_index); - auto grandchild1_index = viewmodel.index(0, 1, child0_index); - EXPECT_EQ(viewmodel.parent(grandchild0_index), child0_index); - EXPECT_EQ(viewmodel.parent(grandchild1_index), child0_index); - - // index of item - EXPECT_EQ(viewmodel.indexFromItem(expected_row0[0]), child0_index); - EXPECT_EQ(viewmodel.indexFromItem(expected_row0[1]), child1_index); - EXPECT_EQ(viewmodel.indexFromItem(expected_row1[0]), grandchild0_index); - EXPECT_EQ(viewmodel.indexFromItem(expected_row1[1]), grandchild1_index); -} - -TEST_F(ViewModelBaseTest, onRowsAppended) -{ - ViewModelBase viewmodel; - - // two items to append as a single row with two columns - auto [children, expected] = test_data(/*ncolumns*/ 2); - - QSignalSpy spyInsert(&viewmodel, &ViewModelBase::rowsInserted); - QSignalSpy spyRemove(&viewmodel, &ViewModelBase::rowsRemoved); - - // appending one row - viewmodel.appendRow(viewmodel.rootItem(), std::move(children)); - EXPECT_EQ(viewmodel.rowCount(), 1); - EXPECT_EQ(viewmodel.columnCount(), 2); - - // checking that signaling is about the parent - EXPECT_EQ(spyRemove.count(), 0); - EXPECT_EQ(spyInsert.count(), 1); - QList<QVariant> arguments = spyInsert.takeFirst(); - EXPECT_EQ(arguments.size(), 3); // QModelIndex &parent, int first, int last - EXPECT_EQ(arguments.at(0).value<QModelIndex>(), QModelIndex()); - EXPECT_EQ(arguments.at(1).value<int>(), 0); - EXPECT_EQ(arguments.at(2).value<int>(), 0); - - // getting child from index - auto index0 = viewmodel.index(0, 0, QModelIndex()); - auto index1 = viewmodel.index(0, 1, QModelIndex()); - EXPECT_EQ(viewmodel.itemFromIndex(index0), expected[0]); - EXPECT_EQ(viewmodel.itemFromIndex(index1), expected[1]); -} - -TEST_F(ViewModelBaseTest, rowsRemoved) -{ - ViewModelBase viewmodel; - - // three rows of items - auto [children_row0, expected_row0] = test_data(/*ncolumns*/ 2); - auto [children_row1, expected_row1] = test_data(/*ncolumns*/ 2); - auto [children_row2, expected_row2] = test_data(/*ncolumns*/ 2); - - QSignalSpy spyInsert(&viewmodel, &ViewModelBase::rowsInserted); - QSignalSpy spyRemove(&viewmodel, &ViewModelBase::rowsRemoved); - - // appending one row - viewmodel.appendRow(viewmodel.rootItem(), std::move(children_row0)); - viewmodel.appendRow(viewmodel.rootItem(), std::move(children_row1)); - viewmodel.appendRow(viewmodel.rootItem(), std::move(children_row2)); - - // removing middle row - viewmodel.removeRow(viewmodel.rootItem(), 1); - - // checking that signaling is about the parent - EXPECT_EQ(spyRemove.count(), 1); - EXPECT_EQ(spyInsert.count(), 3); - QList<QVariant> arguments = spyRemove.takeFirst(); - EXPECT_EQ(arguments.size(), 3); // QModelIndex &parent, int first, int last - EXPECT_EQ(arguments.at(0).value<QModelIndex>(), QModelIndex()); - EXPECT_EQ(arguments.at(1).value<int>(), 1); - EXPECT_EQ(arguments.at(2).value<int>(), 1); -} - -TEST_F(ViewModelBaseTest, data) -{ - SessionItem item; - QVariant expected(42.0); - item.setData(expected); - - children_t children; - children.emplace_back(std::make_unique<ViewDataItem>(&item)); - - ViewModelBase viewmodel; - viewmodel.appendRow(viewmodel.rootItem(), std::move(children)); - - QModelIndex children_index = viewmodel.index(0, 0, QModelIndex()); - - EXPECT_EQ(viewmodel.data(children_index, Qt::EditRole), expected); -} - -TEST_F(ViewModelBaseTest, setData) -{ - // creating single item - SessionItem item; - QVariant expected(42.0); - item.setData(expected); - - // creating view model displaying given SessionItem - children_t children; - children.emplace_back(std::make_unique<ViewDataItem>(&item)); - ViewModelBase viewmodel; - viewmodel.appendRow(viewmodel.rootItem(), std::move(children)); - - QSignalSpy spyData(&viewmodel, &ViewModelBase::dataChanged); - - // changing the data - QModelIndex children_index = viewmodel.index(0, 0, QModelIndex()); - QVariant new_value(43.0); - EXPECT_TRUE(viewmodel.setData(children_index, new_value, Qt::EditRole)); - - // checking signaling - EXPECT_EQ(spyData.count(), 1); - QList<QVariant> arguments = spyData.takeFirst(); - EXPECT_EQ(arguments.size(), 3); // QModelIndex &parent, int first, int last - EXPECT_EQ(arguments.at(0).value<QModelIndex>(), children_index); - EXPECT_EQ(arguments.at(1).value<QModelIndex>(), children_index); - QVector<int> expected_roles{Qt::EditRole}; - EXPECT_EQ(arguments.at(2).value<QVector<int>>(), expected_roles); -} - -TEST_F(ViewModelBaseTest, flags) -{ - SessionItem item; - QVariant expected(42.0); - item.setData(expected); - item.setDisplayName("Name"); - - children_t children; - children.emplace_back(std::make_unique<ViewLabelItem>(&item)); - children.emplace_back(std::make_unique<ViewDataItem>(&item)); - - ViewModelBase viewmodel; - viewmodel.appendRow(viewmodel.rootItem(), std::move(children)); - - QModelIndex label_index = viewmodel.index(0, 0, QModelIndex()); - QModelIndex data_index = viewmodel.index(0, 1, QModelIndex()); - - EXPECT_TRUE(viewmodel.flags(label_index) & Qt::ItemIsSelectable); - EXPECT_TRUE(viewmodel.flags(label_index) & Qt::ItemIsEnabled); - EXPECT_FALSE(viewmodel.flags(label_index) & Qt::ItemIsEditable); - - EXPECT_TRUE(viewmodel.flags(data_index) & Qt::ItemIsSelectable); - EXPECT_TRUE(viewmodel.flags(data_index) & Qt::ItemIsEnabled); - EXPECT_TRUE(viewmodel.flags(data_index) & Qt::ItemIsEditable); -} - -TEST_F(ViewModelBaseTest, clearRowsFromRoot) -{ - ViewModelBase viewmodel; - - // three rows of items - auto [children_row0, expected_row0] = test_data(/*ncolumns*/ 2); - auto [children_row1, expected_row1] = test_data(/*ncolumns*/ 2); - - QSignalSpy spyInsert(&viewmodel, &ViewModelBase::rowsInserted); - QSignalSpy spyRemove(&viewmodel, &ViewModelBase::rowsRemoved); - - // appending one row - viewmodel.appendRow(viewmodel.rootItem(), std::move(children_row0)); - viewmodel.appendRow(viewmodel.rootItem(), std::move(children_row1)); - - viewmodel.clearRows(viewmodel.rootItem()); - - EXPECT_EQ(viewmodel.rowCount(), 0); - EXPECT_EQ(viewmodel.columnCount(), 0); - - // checking that signaling is about the parent - EXPECT_EQ(spyRemove.count(), 1); - EXPECT_EQ(spyInsert.count(), 2); - QList<QVariant> arguments = spyRemove.takeFirst(); - EXPECT_EQ(arguments.size(), 3); // QModelIndex &parent, int first, int last - EXPECT_EQ(arguments.at(0).value<QModelIndex>(), QModelIndex()); - EXPECT_EQ(arguments.at(1).value<int>(), 0); - EXPECT_EQ(arguments.at(2).value<int>(), 1); -} diff --git a/mvvm/tests/testviewmodel/viewmodelcontroller.test.cpp b/mvvm/tests/testviewmodel/viewmodelcontroller.test.cpp deleted file mode 100644 index 7cbb98bfe61af93344be22661f59cac19b90fe5f..0000000000000000000000000000000000000000 --- a/mvvm/tests/testviewmodel/viewmodelcontroller.test.cpp +++ /dev/null @@ -1,479 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testviewmodel/viewmodelcontroller.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/model/propertyitem.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/standarditems/vectoritem.h" -#include "mvvm/viewmodel/labeldatarowstrategy.h" -#include "mvvm/viewmodel/standardchildrenstrategies.h" -#include "mvvm/viewmodel/standardviewitems.h" -#include "mvvm/viewmodel/viewmodelbase.h" -#include "mvvm/viewmodel/viewmodelcontroller.h" -#include "test_utils.h" -#include <QSignalSpy> - -using namespace ModelView; - -//! Tests of ViewModelController class. - -class ViewModelControllerTest : public ::testing::Test { -public: - ~ViewModelControllerTest(); - - auto create_controller(SessionModel* session_model, ViewModelBase* view_model) - { - auto result = std::make_unique<ViewModelController>(session_model, view_model); - result->setRowStrategy(std::make_unique<LabelDataRowStrategy>()); - result->setChildrenStrategy(std::make_unique<AllChildrenStrategy>()); - result->setRootSessionItem(session_model->rootItem()); - return result; - } -}; - -ViewModelControllerTest::~ViewModelControllerTest() = default; - -//! Initial state of the controller. It is in working state only after setRootItem. - -TEST_F(ViewModelControllerTest, initialState) -{ - SessionModel session_model; - ViewModelBase view_model; - auto controller = std::make_unique<ViewModelController>(&session_model, &view_model); - EXPECT_EQ(controller->sessionModel(), &session_model); - EXPECT_EQ(controller->rootSessionItem(), nullptr); -} - -//! Initial state of the controller. Empty SessionModel, empty ViewModel. - -TEST_F(ViewModelControllerTest, create_controller) -{ - SessionModel session_model; - ViewModelBase view_model; - auto controller = create_controller(&session_model, &view_model); - - EXPECT_EQ(controller->sessionModel(), &session_model); - EXPECT_EQ(controller->rootSessionItem(), session_model.rootItem()); - EXPECT_EQ(view_model.columnCount(), 0); - EXPECT_EQ(view_model.rowCount(), 0); -} - -//! Single property item in a model. - -TEST_F(ViewModelControllerTest, fromPropertyItem) -{ - SessionModel session_model; - auto propertyItem = session_model.insertItem<PropertyItem>(); - propertyItem->setData(42.0); - - ViewModelBase view_model; - auto controller = create_controller(&session_model, &view_model); - - EXPECT_EQ(view_model.rowCount(), 1); - EXPECT_EQ(view_model.columnCount(), 2); - - // accessing first child under the root item - QModelIndex labelIndex = view_model.index(0, 0); - QModelIndex dataIndex = view_model.index(0, 1); - - // it should be ViewLabelItem and ViewDataItem looking at our PropertyItem item - EXPECT_EQ(view_model.itemFromIndex(labelIndex)->item_role(), ItemDataRole::DISPLAY); - EXPECT_EQ(view_model.itemFromIndex(labelIndex)->item(), propertyItem); - EXPECT_EQ(view_model.itemFromIndex(dataIndex)->item_role(), ItemDataRole::DATA); - EXPECT_EQ(view_model.itemFromIndex(dataIndex)->item(), propertyItem); -} - -//! VectorItem in a model. - -TEST_F(ViewModelControllerTest, fromVectorItem) -{ - SessionModel session_model; - auto vectorItem = session_model.insertItem<VectorItem>(); - - ViewModelBase view_model; - auto controller = create_controller(&session_model, &view_model); - - EXPECT_EQ(view_model.rowCount(), 1); - EXPECT_EQ(view_model.columnCount(), 2); - - // accessing first child under the root item - QModelIndex vectorLabelIndex = view_model.index(0, 0); - QModelIndex vectorDataIndex = view_model.index(0, 1); - - // it should be ViewLabelItem and ViewDataItem looking at our VectorItem item - EXPECT_EQ(view_model.itemFromIndex(vectorLabelIndex)->item_role(), ItemDataRole::DISPLAY); - EXPECT_EQ(view_model.itemFromIndex(vectorLabelIndex)->item(), vectorItem); - EXPECT_EQ(view_model.itemFromIndex(vectorDataIndex)->item_role(), ItemDataRole::DATA); - EXPECT_EQ(view_model.itemFromIndex(vectorDataIndex)->item(), vectorItem); - - // checking X, Y, Z - std::vector<SessionItem*> children = vectorItem->children(); - for (int row = 0; row < 3; ++row) { // x, y, z - QModelIndex x_labelIndex = view_model.index(row, 0, vectorLabelIndex); - QModelIndex x_dataIndex = view_model.index(row, 1, vectorLabelIndex); - EXPECT_EQ(view_model.itemFromIndex(x_labelIndex)->item_role(), ItemDataRole::DISPLAY); - EXPECT_EQ(view_model.itemFromIndex(x_labelIndex)->item(), - children[static_cast<size_t>(row)]); - EXPECT_EQ(view_model.itemFromIndex(x_dataIndex)->item_role(), ItemDataRole::DATA); - EXPECT_EQ(view_model.itemFromIndex(x_dataIndex)->item(), - children[static_cast<size_t>(row)]); - } -} - -//! Single property item in a model, inserted after controller was setup. - -TEST_F(ViewModelControllerTest, initThenInsertProperty) -{ - SessionModel session_model; - - ViewModelBase view_model; - QSignalSpy spyInsert(&view_model, &ViewModelBase::rowsInserted); - QSignalSpy spyRemove(&view_model, &ViewModelBase::rowsRemoved); - - auto controller = create_controller(&session_model, &view_model); - auto propertyItem = session_model.insertItem<PropertyItem>(); - propertyItem->setData(42.0); - - // checking signaling - EXPECT_EQ(spyInsert.count(), 1); - EXPECT_EQ(spyRemove.count(), 0); - QList<QVariant> arguments = spyInsert.takeFirst(); - EXPECT_EQ(arguments.size(), 3); // QModelIndex &parent, int first, int last - EXPECT_EQ(arguments.at(0).value<QModelIndex>(), QModelIndex()); - EXPECT_EQ(arguments.at(1).value<int>(), 0); - EXPECT_EQ(arguments.at(2).value<int>(), 0); - - // checking model layout - EXPECT_EQ(view_model.rowCount(), 1); - EXPECT_EQ(view_model.columnCount(), 2); - - // accessing first child under the root item - QModelIndex labelIndex = view_model.index(0, 0); - QModelIndex dataIndex = view_model.index(0, 1); - - // it should be ViewLabelItem and ViewDataItem looking at our PropertyItem item - EXPECT_EQ(view_model.itemFromIndex(labelIndex)->item_role(), ItemDataRole::DISPLAY); - EXPECT_EQ(view_model.itemFromIndex(labelIndex)->item(), propertyItem); - - // Our PropertyItem got it's value after ViewModel was initialized, however, - // underlying ViewDataItem should see updated values - EXPECT_EQ(view_model.itemFromIndex(dataIndex)->item_role(), ItemDataRole::DATA); - EXPECT_EQ(view_model.itemFromIndex(dataIndex)->item(), propertyItem); -} - -//! Insert three property items in a model, inserted after controller was setup. - -TEST_F(ViewModelControllerTest, initThenInsertProperties) -{ - SessionModel session_model; - - ViewModelBase view_model; - QSignalSpy spyInsert(&view_model, &ViewModelBase::rowsInserted); - QSignalSpy spyRemove(&view_model, &ViewModelBase::rowsRemoved); - - auto controller = create_controller(&session_model, &view_model); - auto item0 = session_model.insertItem<PropertyItem>(); - auto item1 = session_model.insertItem<PropertyItem>(); - auto item2 = session_model.insertItem<PropertyItem>(); - - // checking signaling - EXPECT_EQ(spyInsert.count(), 3); - - // checking model layout - EXPECT_EQ(view_model.rowCount(), 3); - EXPECT_EQ(view_model.columnCount(), 2); - - EXPECT_EQ(view_model.itemFromIndex(view_model.index(0, 0))->item(), item0); - EXPECT_EQ(view_model.itemFromIndex(view_model.index(1, 0))->item(), item1); - EXPECT_EQ(view_model.itemFromIndex(view_model.index(2, 0))->item(), item2); -} - -//! Inserting property items in reversed order. - -TEST_F(ViewModelControllerTest, insertInBetween) -{ - SessionModel session_model; - - ViewModelBase view_model; - QSignalSpy spyInsert(&view_model, &ViewModelBase::rowsInserted); - QSignalSpy spyRemove(&view_model, &ViewModelBase::rowsRemoved); - - auto controller = create_controller(&session_model, &view_model); - auto item0 = session_model.insertItem<PropertyItem>(); - // inserting in front - auto item1 = session_model.insertItem<PropertyItem>(session_model.rootItem(), {"", 0}); - - // checking signaling - EXPECT_EQ(spyInsert.count(), 2); - - // checking model layout - EXPECT_EQ(view_model.rowCount(), 2); - EXPECT_EQ(view_model.columnCount(), 2); - - EXPECT_EQ(view_model.itemFromIndex(view_model.index(0, 0))->item(), item1); - EXPECT_EQ(view_model.itemFromIndex(view_model.index(1, 0))->item(), item0); -} - -//! Insert two property items in a model, inserted after controller was setup. - -TEST_F(ViewModelControllerTest, initThenInsertVector) -{ - SessionModel session_model; - - ViewModelBase view_model; - QSignalSpy spyInsert(&view_model, &ViewModelBase::rowsInserted); - QSignalSpy spyRemove(&view_model, &ViewModelBase::rowsRemoved); - - auto controller = create_controller(&session_model, &view_model); - session_model.insertItem<VectorItem>(); - session_model.insertItem<VectorItem>(); - - // checking signaling - EXPECT_EQ(spyInsert.count(), 8); // two vector items and 2*(x,y,z) - - // checking model layout - EXPECT_EQ(view_model.rowCount(), 2); - EXPECT_EQ(view_model.columnCount(), 2); -} - -//! Insert child to parent - -TEST_F(ViewModelControllerTest, insertChildToParent) -{ - SessionModel session_model; - - ViewModelBase view_model; - QSignalSpy spyInsert(&view_model, &ViewModelBase::rowsInserted); - QSignalSpy spyRemove(&view_model, &ViewModelBase::rowsRemoved); - - auto controller = create_controller(&session_model, &view_model); - - auto parent = session_model.insertItem<CompoundItem>(); - parent->registerTag(TagInfo::universalTag("children"), /*set_as_default*/ true); - session_model.insertItem<SessionItem>(parent); - session_model.insertItem<SessionItem>(parent); - - // checking signaling - EXPECT_EQ(spyInsert.count(), 3); - - // checking model layout: parent and two children - EXPECT_EQ(view_model.rowCount(), 1); - EXPECT_EQ(view_model.columnCount(), 2); - EXPECT_EQ(view_model.rowCount(view_model.index(0, 0)), 2); - EXPECT_EQ(view_model.columnCount(view_model.index(0, 0)), 2); -} - -//! Removing single top level item. - -TEST_F(ViewModelControllerTest, removeSingleTopItem) -{ - // constructing the model with single item - SessionModel session_model; - session_model.insertItem<SessionItem>(); - - // constructing viewmodel and its controller - ViewModelBase view_model; - auto controller = create_controller(&session_model, &view_model); - - // root item should have one child - EXPECT_EQ(view_model.rowCount(), 1); - EXPECT_EQ(view_model.columnCount(), 2); - - QSignalSpy spyInsert(&view_model, &ViewModelBase::rowsInserted); - QSignalSpy spyRemove(&view_model, &ViewModelBase::rowsRemoved); - - // removing child - session_model.removeItem(session_model.rootItem(), {"", 0}); - ASSERT_EQ(spyInsert.count(), 0); - ASSERT_EQ(spyRemove.count(), 1); - EXPECT_EQ(view_model.rowCount(), 0); - EXPECT_EQ(view_model.columnCount(), 0); - - QList<QVariant> arguments = spyRemove.takeFirst(); - ASSERT_EQ(arguments.size(), 3); // QModelIndex &parent, int first, int last - EXPECT_EQ(arguments.at(0).value<QModelIndex>(), QModelIndex()); - EXPECT_EQ(arguments.at(1).value<int>(), 0); - EXPECT_EQ(arguments.at(2).value<int>(), 0); -} - -//! Remove one of two top level items. - -TEST_F(ViewModelControllerTest, removeOneOfTopItems) -{ - // constructing model with two items - SessionModel session_model; - session_model.insertItem<SessionItem>(); - session_model.insertItem<SessionItem>(); - - // constructing viewmodel and its controller - ViewModelBase view_model; - auto controller = create_controller(&session_model, &view_model); - - // root item should have one child - EXPECT_EQ(view_model.rowCount(), 2); - EXPECT_EQ(view_model.columnCount(), 2); - - QSignalSpy spyRemove(&view_model, &ViewModelBase::rowsRemoved); - QSignalSpy spyInsert(&view_model, &ViewModelBase::rowsInserted); - - // removing child - session_model.removeItem(session_model.rootItem(), {"", 0}); - - // no insert was called - EXPECT_EQ(spyInsert.count(), 0); - - // removal was called once - EXPECT_EQ(spyRemove.count(), 1); - EXPECT_EQ(view_model.rowCount(), 1); - EXPECT_EQ(view_model.columnCount(), 2); - - QList<QVariant> arguments = spyRemove.takeFirst(); - EXPECT_EQ(arguments.size(), 3); // QModelIndex &parent, int first, int last - EXPECT_EQ(arguments.at(0).value<QModelIndex>(), QModelIndex()); - EXPECT_EQ(arguments.at(1).value<int>(), 0); - EXPECT_EQ(arguments.at(2).value<int>(), 0); -} - -//! Setting top level item as ROOT item - -TEST_F(ViewModelControllerTest, setRootItem) -{ - SessionModel session_model; - - // constructing viewmodel and its controller - ViewModelBase view_model; - auto controller = create_controller(&session_model, &view_model); - - auto item = session_model.insertItem<PropertyItem>(); - - controller->setRootSessionItem(item); - - // new root item doesn't have children - EXPECT_EQ(view_model.rowCount(), 0); - EXPECT_EQ(view_model.columnCount(), 0); -} - -//! Setting top level item as ROOT item (case parent and children). - -TEST_F(ViewModelControllerTest, setCompoundAsRootItem) -{ - SessionModel session_model; - - // constructing viewmodel and its controller - ViewModelBase view_model; - auto controller = create_controller(&session_model, &view_model); - - auto item = session_model.insertItem<CompoundItem>(); - item->addProperty("thickness", 42.0); - item->addProperty<VectorItem>("position"); - item->addProperty("radius", 43.0); - - controller->setRootSessionItem(item); - - EXPECT_EQ(view_model.rowCount(), 3); - EXPECT_EQ(view_model.columnCount(), 2); - - // checking vector item - auto index_of_vector_item = view_model.index(1, 0); - EXPECT_EQ(view_model.rowCount(index_of_vector_item), 3); - EXPECT_EQ(view_model.columnCount(index_of_vector_item), 2); -} - -//! On model reset. - -TEST_F(ViewModelControllerTest, onModelReset) -{ - SessionModel session_model; - session_model.insertItem<SessionItem>(); - session_model.insertItem<SessionItem>(); - session_model.insertItem<SessionItem>(); - - // constructing viewmodel and its controller - ViewModelBase view_model; - auto controller = create_controller(&session_model, &view_model); - EXPECT_EQ(controller->rootSessionItem(), session_model.rootItem()); - - QSignalSpy spyReset(&view_model, &ViewModelBase::modelReset); - - session_model.clear(); - - EXPECT_EQ(spyReset.count(), 1); - EXPECT_EQ(view_model.rowCount(), 0); - EXPECT_EQ(view_model.columnCount(), 0); - EXPECT_EQ(controller->rootSessionItem(), session_model.rootItem()); -} - -//! Real life scenario: initially empty SessionModel, apply ::clean, and then start to insert item. - -TEST_F(ViewModelControllerTest, onEmptyModelResetAndContinue) -{ - SessionModel session_model; - - // constructing viewmodel and its controller - ViewModelBase view_model; - auto controller = create_controller(&session_model, &view_model); - - QSignalSpy spyReset(&view_model, &ViewModelBase::modelReset); - session_model.clear(); - - EXPECT_EQ(spyReset.count(), 1); - - // inserting new item - QSignalSpy spyInsert(&view_model, &ViewModelBase::rowsInserted); - session_model.insertItem<SessionItem>(); - - EXPECT_EQ(spyInsert.count(), 1); -} - -//! On model destroyed. - -TEST_F(ViewModelControllerTest, onModelDestroyed) -{ - auto session_model = std::make_unique<SessionModel>(); - session_model->insertItem<SessionItem>(); - - // constructing viewmodel and its controller - ViewModelBase view_model; - auto controller = create_controller(session_model.get(), &view_model); - EXPECT_EQ(view_model.rowCount(), 1); - EXPECT_EQ(view_model.columnCount(), 2); - - session_model.reset(); - EXPECT_EQ(view_model.rowCount(), 0); - EXPECT_EQ(view_model.columnCount(), 0); - EXPECT_EQ(view_model.rootItem()->item(), nullptr); -} - -TEST_F(ViewModelControllerTest, findViews) -{ - SessionModel session_model; - ViewModelBase view_model; - auto controller = create_controller(&session_model, &view_model); - - // view of root item - auto views = controller->findViews(session_model.rootItem()); - ASSERT_EQ(views.size(), 1); - EXPECT_EQ(views.at(0), view_model.rootItem()); - - // views of VectorItem - auto item = session_model.insertItem<VectorItem>(); - views = controller->findViews(item); - ASSERT_EQ(views.size(), 2); - - // setting as root item - controller->setRootSessionItem(item); - views = controller->findViews(item); - ASSERT_EQ(views.size(), 1); - EXPECT_EQ(views.at(0), view_model.rootItem()); -} diff --git a/mvvm/tests/testviewmodel/viewmodelcontrollerbuilder.test.cpp b/mvvm/tests/testviewmodel/viewmodelcontrollerbuilder.test.cpp deleted file mode 100644 index a0f3706dbccff72c19727cbc8e9a7875a52e44c4..0000000000000000000000000000000000000000 --- a/mvvm/tests/testviewmodel/viewmodelcontrollerbuilder.test.cpp +++ /dev/null @@ -1,60 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testviewmodel/viewmodelcontrollerbuilder.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/factories/viewmodelcontrollerbuilder.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/viewmodel/labeldatarowstrategy.h" -#include "mvvm/viewmodel/standardchildrenstrategies.h" -#include "mvvm/viewmodel/viewmodelbase.h" -#include "mvvm/viewmodel/viewmodelcontroller.h" - -using namespace ModelView; - -//! Tests of ViewModelController class. - -class ViewModelControllerBuilderTest : public ::testing::Test { -public: - ~ViewModelControllerBuilderTest(); -}; - -ViewModelControllerBuilderTest::~ViewModelControllerBuilderTest() = default; - -//! Initial state of the builder. -//! It can't build anything without configuration. - -TEST_F(ViewModelControllerBuilderTest, initialState) -{ - EXPECT_THROW(std::unique_ptr<ViewModelController> controller = ViewModelControllerBuilder(), - std::runtime_error); -} - -TEST_F(ViewModelControllerBuilderTest, allItemsControllerBuild) -{ - SessionModel session_model; - ViewModelBase view_model; - - std::unique_ptr<ViewModelController> controller = - ViewModelControllerBuilder() - .model(&session_model) - .viewModel(&view_model) - .childrenStrategy(std::make_unique<AllChildrenStrategy>()) - .rowStrategy(std::make_unique<LabelDataRowStrategy>()); - controller->setRootSessionItem(session_model.rootItem()); - - EXPECT_EQ(controller->sessionModel(), &session_model); - EXPECT_EQ(controller->rootSessionItem(), session_model.rootItem()); - EXPECT_EQ(view_model.columnCount(), 0); - EXPECT_EQ(view_model.rowCount(), 0); -} diff --git a/mvvm/tests/testviewmodel/viewmodelcontrollerfactory.test.cpp b/mvvm/tests/testviewmodel/viewmodelcontrollerfactory.test.cpp deleted file mode 100644 index 3073ea748286434f2440a08edaa6177427c5e672..0000000000000000000000000000000000000000 --- a/mvvm/tests/testviewmodel/viewmodelcontrollerfactory.test.cpp +++ /dev/null @@ -1,48 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testviewmodel/viewmodelcontrollerfactory.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/factories/viewmodelcontrollerfactory.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/viewmodel/labeldatarowstrategy.h" -#include "mvvm/viewmodel/standardchildrenstrategies.h" -#include "mvvm/viewmodel/viewmodelbase.h" -#include "mvvm/viewmodel/viewmodelcontroller.h" - -using namespace ModelView; - -//! Tests of ViewModelControllerFactory method. - -class ViewModelControllerFactoryTest : public ::testing::Test { -public: - ~ViewModelControllerFactoryTest(); -}; - -ViewModelControllerFactoryTest::~ViewModelControllerFactoryTest() = default; - -TEST_F(ViewModelControllerFactoryTest, allItemsControllerBuild) -{ - SessionModel session_model; - ViewModelBase view_model; - - auto controller = Factory::CreateController<AllChildrenStrategy, LabelDataRowStrategy>( - &session_model, &view_model); - - controller->setRootSessionItem(session_model.rootItem()); - - EXPECT_EQ(controller->sessionModel(), &session_model); - EXPECT_EQ(controller->rootSessionItem(), session_model.rootItem()); - EXPECT_EQ(view_model.columnCount(), 0); - EXPECT_EQ(view_model.rowCount(), 0); -} diff --git a/mvvm/tests/testviewmodel/viewmodeldelegate.test.cpp b/mvvm/tests/testviewmodel/viewmodeldelegate.test.cpp deleted file mode 100644 index 3e2ac025a8bba2b0870f2d2fcd3ca4e2732f23d0..0000000000000000000000000000000000000000 --- a/mvvm/tests/testviewmodel/viewmodeldelegate.test.cpp +++ /dev/null @@ -1,94 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testviewmodel/viewmodeldelegate.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/editors/customeditor.h" -#include "mvvm/model/propertyitem.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/standarditems/vectoritem.h" -#include "mvvm/viewmodel/defaultviewmodel.h" -#include "mvvm/viewmodel/viewmodeldelegate.h" -#include "widgetbasedtest.h" -#include <QDataWidgetMapper> -#include <QStyleOptionViewItem> - -using namespace ModelView; - -//! Tests of ViewModelDelegate class. - -class ViewModelDelegateTest : public WidgetBasedTest { -public: - ~ViewModelDelegateTest(); - - struct TestData { - SessionModel model{}; - DefaultViewModel view_model; - ViewModelDelegate delegate; - QDataWidgetMapper mapper; - - TestData() : view_model(&model) - { - mapper.setModel(&view_model); - mapper.setItemDelegate(&delegate); - } - - std::unique_ptr<CustomEditor> create_editor(const QModelIndex& index) - { - return std::unique_ptr<CustomEditor>(dynamic_cast<CustomEditor*>( - delegate.createEditor(nullptr, QStyleOptionViewItem(), index))); - } - - void map_to_index(QWidget* widget, const QModelIndex& index) - { - mapper.setRootIndex(index.parent()); - mapper.setCurrentModelIndex(index.sibling(index.row(), 0)); - mapper.addMapping(widget, 1); - } - }; - - std::unique_ptr<TestData> test_data() { return std::make_unique<TestData>(); } -}; - -ViewModelDelegateTest::~ViewModelDelegateTest() = default; - -TEST_F(ViewModelDelegateTest, createEditor) -{ - TestData test_data; - test_data.model.insertItem<VectorItem>(); - - auto parent_index = test_data.view_model.index(0, 0); - auto x_value_index = test_data.view_model.index(0, 1, parent_index); - - EXPECT_TRUE(test_data.create_editor(x_value_index).get() != nullptr); -} - -//! Check that ViewModelDelegate can work with widget mapper. - -TEST_F(ViewModelDelegateTest, widgetMapper) -{ - TestData test_data; - auto vector_item = test_data.model.insertItem<VectorItem>(); - auto x_item = vector_item->getItem(VectorItem::P_X); - - // accessing to index list (index of label field and index of data field) - // of PropertyItem corresponding to x-coordinate. - auto x_value_index = test_data.view_model.indexOfSessionItem(x_item).at(1); - auto editor = test_data.create_editor(x_value_index); - - test_data.map_to_index(editor.get(), x_value_index); - - editor->setData(43.0); - editor->dataChanged(editor->data()); - EXPECT_EQ(x_item->data<double>(), 43.0); -} diff --git a/mvvm/tests/testviewmodel/viewmodelfactory.test.cpp b/mvvm/tests/testviewmodel/viewmodelfactory.test.cpp deleted file mode 100644 index 12712d654c625a37994c643bf8a2f79a4a4c4615..0000000000000000000000000000000000000000 --- a/mvvm/tests/testviewmodel/viewmodelfactory.test.cpp +++ /dev/null @@ -1,109 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testviewmodel/viewmodelfactory.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/factories/viewmodelfactory.h" -#include "mvvm/model/propertyitem.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/viewmodel/labeldatarowstrategy.h" -#include "mvvm/viewmodel/standardchildrenstrategies.h" -#include "mvvm/viewmodel/standardviewitems.h" -#include "test_utils.h" - -using namespace ModelView; - -namespace { -std::unique_ptr<ViewModelController> createController(SessionModel* model, ViewModelBase* viewModel) -{ - return Factory::CreateController<TopItemsStrategy, LabelDataRowStrategy>(model, viewModel); -} -} // namespace - -class ViewModelFactoryTest : public ::testing::Test { -public: - ~ViewModelFactoryTest(); - - class CustomModel : public ViewModel { - public: - CustomModel(SessionModel* model) : ViewModel(createController(model, this), nullptr) {} - }; -}; - -ViewModelFactoryTest::~ViewModelFactoryTest() = default; - -//! Creating DefaultViewModel using strategies. - -TEST_F(ViewModelFactoryTest, createDefaultViewModelInitial) -{ - SessionModel model; - - auto viewModel = Factory::CreateViewModel<AllChildrenStrategy, LabelDataRowStrategy>(&model); - EXPECT_EQ(viewModel->rowCount(), 0); - EXPECT_EQ(viewModel->columnCount(), 0); - EXPECT_EQ(viewModel->sessionItemFromIndex(QModelIndex()), model.rootItem()); -} - -//! Creating DefaultViewModel using strategies, validating behaviour on single item in SessionModel. - -TEST_F(ViewModelFactoryTest, createDefaultViewModelUseProperty) -{ - SessionModel model; - auto propertyItem = model.insertItem<PropertyItem>(); - propertyItem->setData(42.0); - - auto viewModel = Factory::CreateViewModel<AllChildrenStrategy, LabelDataRowStrategy>(&model); - - EXPECT_EQ(viewModel->rowCount(), 1); - EXPECT_EQ(viewModel->columnCount(), 2); - - // accessing first child under the root item - QModelIndex labelIndex = viewModel->index(0, 0); - QModelIndex dataIndex = viewModel->index(0, 1); - - // it should be ViewLabelItem looking at our PropertyItem item - auto labelItem = dynamic_cast<ViewLabelItem*>(viewModel->itemFromIndex(labelIndex)); - ASSERT_TRUE(labelItem != nullptr); - EXPECT_EQ(labelItem->item(), propertyItem); - - auto dataItem = dynamic_cast<ViewDataItem*>(viewModel->itemFromIndex(dataIndex)); - ASSERT_TRUE(dataItem != nullptr); - EXPECT_EQ(dataItem->item(), propertyItem); -} - -//! Creating DefaultViewModel using strategies, validating behaviour on single item in SessionModel. - -TEST_F(ViewModelFactoryTest, createCustomViewModel) -{ - SessionModel model; - auto propertyItem = model.insertItem<PropertyItem>(); - propertyItem->setData(42.0); - - CustomModel viewModel(&model); - - EXPECT_EQ(viewModel.rowCount(), 1); - EXPECT_EQ(viewModel.columnCount(), 2); - - // accessing first child under the root item - QModelIndex labelIndex = viewModel.index(0, 0); - QModelIndex dataIndex = viewModel.index(0, 1); - - // it should be ViewLabelItem looking at our PropertyItem item - auto labelItem = dynamic_cast<ViewLabelItem*>(viewModel.itemFromIndex(labelIndex)); - ASSERT_TRUE(labelItem != nullptr); - EXPECT_EQ(labelItem->item(), propertyItem); - - auto dataItem = dynamic_cast<ViewDataItem*>(viewModel.itemFromIndex(dataIndex)); - ASSERT_TRUE(dataItem != nullptr); - EXPECT_EQ(dataItem->item(), propertyItem); -} diff --git a/mvvm/tests/testviewmodel/viewmodelutils.test.cpp b/mvvm/tests/testviewmodel/viewmodelutils.test.cpp deleted file mode 100644 index 78bc9f0fb35fc62429226103f07781e9854611d2..0000000000000000000000000000000000000000 --- a/mvvm/tests/testviewmodel/viewmodelutils.test.cpp +++ /dev/null @@ -1,252 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/tests/testviewmodel/viewmodelutils.test.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "google_test.h" -#include "mvvm/model/mvvm_types.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/standarditems/vectoritem.h" -#include "mvvm/viewmodel/propertytableviewmodel.h" -#include "mvvm/viewmodel/standardviewitems.h" -#include "mvvm/viewmodel/viewmodelutils.h" -#include <QColor> -#include <QModelIndexList> -#include <QStandardItemModel> - -namespace { -QList<QStandardItem*> get_items(std::vector<int> data) -{ - QList<QStandardItem*> result; - - for (auto x : data) - result.append(new QStandardItem(QString::number(x))); - - return result; -} -} // namespace - -using namespace ModelView; - -class ViewModelUtilsTest : public ::testing::Test { -public: - ~ViewModelUtilsTest(); -}; - -ViewModelUtilsTest::~ViewModelUtilsTest() = default; - -TEST_F(ViewModelUtilsTest, iterate) -{ - QStandardItemModel model; - - model.setColumnCount(2); - QStandardItem* parentItem = model.invisibleRootItem(); - - auto row1 = get_items({1, 2}); - parentItem->appendRow(row1); - row1.at(0)->appendRow(get_items({3, 4})); - - auto row2 = get_items({10, 20}); - parentItem->appendRow(row2); - - std::vector<int> expected = {1, 2, 3, 4, 10, 20}; - std::vector<int> result; - - Utils::iterate_model(&model, QModelIndex(), [&](const QModelIndex& index) { - auto item = model.itemFromIndex(index); - result.push_back(item->data(Qt::EditRole).value<int>()); - }); - - EXPECT_EQ(result, expected); -} - -//! Translation of item role to Qt roles. - -TEST_F(ViewModelUtilsTest, ItemRoleToQtRole) -{ - // DATA role of SessionItem should be translated to two Qt roles (edit and display) - auto roles = Utils::ItemRoleToQtRole(ItemDataRole::DATA); - QVector<int> expected = {Qt::DisplayRole, Qt::EditRole}; - EXPECT_EQ(roles, expected); - - // APPEARANCE roles of SessionItem on Qt site means color - roles = Utils::ItemRoleToQtRole(ItemDataRole::APPEARANCE); -#if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0) - expected = {Qt::ForegroundRole}; -#else - expected = {Qt::TextColorRole}; -#endif - EXPECT_EQ(roles, expected); - - // tooltip role - roles = Utils::ItemRoleToQtRole(ItemDataRole::TOOLTIP); - expected = {Qt::ToolTipRole}; - EXPECT_EQ(roles, expected); -} - -//! Testing color role of item. - -TEST_F(ViewModelUtilsTest, itemTextColorRole) -{ - SessionItem item("Something"); - - // no color defined for item by default - auto variant = Utils::TextColorRole(item); - EXPECT_FALSE(variant.isValid()); - - item.setEnabled(false); - variant = Utils::TextColorRole(item); - EXPECT_EQ(variant.value<QColor>(), QColor(Qt::gray)); -} - -//! Testing check state role of item. - -TEST_F(ViewModelUtilsTest, itemCheckStateRole) -{ - SessionItem item("Something"); - - // no color defined for item by default - auto variant = Utils::CheckStateRole(item); - EXPECT_FALSE(variant.isValid()); - - item.setData(QVariant::fromValue(true)); - EXPECT_EQ(Utils::CheckStateRole(item).value<int>(), Qt::Checked); - - item.setData(QVariant::fromValue(false)); - EXPECT_EQ(Utils::CheckStateRole(item).value<int>(), Qt::Unchecked); -} - -//! Testing decoration role of the item. - -TEST_F(ViewModelUtilsTest, itemDecorationRole) -{ - SessionItem item("Something"); - - // no color defined for item by default - auto variant = Utils::DecorationRole(item); - EXPECT_FALSE(variant.isValid()); - - QColor expected(Qt::green); - item.setData(expected); - EXPECT_EQ(Utils::DecorationRole(item).value<QColor>(), expected); -} - -//! Testing tooltip role of the item. - -TEST_F(ViewModelUtilsTest, itemToolTipRole) -{ - SessionItem item("Something"); - - auto variant = Utils::ToolTipRole(item); - EXPECT_FALSE(variant.isValid()); - - item.setToolTip("abc"); - EXPECT_EQ(Utils::ToolTipRole(item).toString(), QString("abc")); -} - -//! Check ItemsFromIndex in PropertyTableViewModel context. -//! ViewItem with its three property x, y, z forms one row. All corresponding -//! indices of (x,y,z) should give us pointers to VectorItem's properties. - -TEST_F(ViewModelUtilsTest, itemsFromIndex) -{ - // creating VectorItem and viewModel to see it as a table - SessionModel model; - auto parent = model.insertItem<VectorItem>(); - PropertyTableViewModel viewModel(&model); - - // it's a table with one row and x,y,z columns - EXPECT_EQ(viewModel.rowCount(), 1); - EXPECT_EQ(viewModel.columnCount(), 3); - - // empty index list doesn't lead to SessionItem's - QModelIndexList index_list; - EXPECT_EQ(Utils::ItemsFromIndex(index_list).size(), 0); - - // index list populated with column of properties - index_list.push_back(viewModel.index(0, 0)); - index_list.push_back(viewModel.index(0, 1)); - index_list.push_back(viewModel.index(0, 2)); - - std::vector<SessionItem*> expected = {parent->getItem(VectorItem::P_X), - parent->getItem(VectorItem::P_Y), - parent->getItem(VectorItem::P_Z)}; - EXPECT_EQ(Utils::ItemsFromIndex(index_list), expected); - EXPECT_EQ(Utils::UniqueItemsFromIndex(index_list), expected); -} - -//! Check UniqueItemsFromIndex for artificially constructed viewmodel. - -TEST_F(ViewModelUtilsTest, UniqueItemsFromIndex) -{ - SessionItem item1; - item1.setData(42, ItemDataRole::DATA); - SessionItem item2; - item2.setData(42, ItemDataRole::DATA); - - ViewModelBase viewmodel; - std::vector<std::unique_ptr<ViewItem>> items; - items.emplace_back(std::make_unique<ViewLabelItem>(&item1)); - items.emplace_back(std::make_unique<ViewLabelItem>(&item2)); - items.emplace_back(std::make_unique<ViewDataItem>(&item1)); - items.emplace_back(std::make_unique<ViewDataItem>(&item2)); - viewmodel.insertRow(viewmodel.rootItem(), 0, std::move(items)); - - QModelIndexList index_list = {viewmodel.index(0, 0), viewmodel.index(0, 1), - viewmodel.index(0, 2), viewmodel.index(0, 3)}; - - EXPECT_EQ(Utils::ItemsFromIndex(index_list), - std::vector<SessionItem*>({&item1, &item2, &item1, &item2})); - EXPECT_EQ(Utils::UniqueItemsFromIndex(index_list), std::vector<SessionItem*>({&item1, &item2})); -} - -//! Check ParentItemsFromIndex in PropertyTableViewModel context. -//! ViewItem with its three property x, y, z forms one row. All corresponding -//! indices of (x,y,z) should give us pointer to VectorItem. - -TEST_F(ViewModelUtilsTest, parentItemsFromIndex) -{ - // creating VectorItem and viewModel to see it as a table - SessionModel model; - auto parent = model.insertItem<VectorItem>(); - PropertyTableViewModel viewModel(&model); - - // it's a table with one row and x,y,z columns - EXPECT_EQ(viewModel.rowCount(), 1); - EXPECT_EQ(viewModel.columnCount(), 3); - - // empty index list doesn't lead to SessionItem's - QModelIndexList index_list; - EXPECT_EQ(Utils::ParentItemsFromIndex(index_list).size(), 0); - - std::vector<SessionItem*> expected = {parent}; - - // one cell in a list should give us pointer to original VectorItem - index_list.push_back(viewModel.index(0, 1)); - EXPECT_EQ(Utils::ParentItemsFromIndex(index_list), expected); - - index_list.clear(); - index_list.push_back(viewModel.index(0, 1)); - EXPECT_EQ(Utils::ParentItemsFromIndex(index_list), expected); - - index_list.clear(); - index_list.push_back(viewModel.index(0, 2)); - EXPECT_EQ(Utils::ParentItemsFromIndex(index_list), expected); - - // tthree cells (x, y, z) in a list should give us pointer to original VectorItem - index_list.clear(); - index_list.push_back(viewModel.index(0, 0)); - index_list.push_back(viewModel.index(0, 1)); - index_list.push_back(viewModel.index(0, 2)); - EXPECT_EQ(Utils::ParentItemsFromIndex(index_list), expected); -} diff --git a/mvvm/view/CMakeLists.txt b/mvvm/view/CMakeLists.txt deleted file mode 100644 index 91553fd96b7b47c47ca0acbba7401b7abe51d267..0000000000000000000000000000000000000000 --- a/mvvm/view/CMakeLists.txt +++ /dev/null @@ -1,34 +0,0 @@ -# ----------------------------------------------------------------------------- -# Library: mvvm_view -# ----------------------------------------------------------------------------- - -set(library_name mvvm_view) - -add_library(${library_name} SHARED "") -add_subdirectory(mvvm) -add_library(MVVM::View ALIAS ${library_name}) # alias for build-tree usage - -# -- Generate header for export -- - -set(export_filename ${MVVM_AUTOGEN_DIR}/mvvm/view_export.h) -generate_export_header(${library_name} EXPORT_FILE_NAME ${export_filename}) - -# -- Dependencies -- - -target_link_libraries(${library_name} PUBLIC mvvm_viewmodel Qt5::Widgets PRIVATE qcustomplot) -target_include_directories(${library_name} - PUBLIC - $<INSTALL_INTERFACE:include> - $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}> $<BUILD_INTERFACE:${MVVM_AUTOGEN_DIR}> - ) - -# -- Definitions -- - -target_compile_features(${library_name} PUBLIC cxx_std_17) # clang code model in Qt creator - -# -- Installation -- - -install(TARGETS ${library_name} EXPORT mvvm-targets LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) -set_target_properties(${library_name} PROPERTIES EXPORT_NAME View SOVERSION ${MVVM_SOVERSION} VERSION ${MVVM_BUILDVERSION}) -install(DIRECTORY mvvm/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/mvvm FILES_MATCHING PATTERN "*.h") -install(FILES ${export_filename} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/mvvm) diff --git a/mvvm/view/mvvm/CMakeLists.txt b/mvvm/view/mvvm/CMakeLists.txt deleted file mode 100644 index a1c86ba45842314d9460e7fbff446887e5f0088f..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -add_subdirectory(widgets) -add_subdirectory(plotting) - diff --git a/mvvm/view/mvvm/plotting/CMakeLists.txt b/mvvm/view/mvvm/plotting/CMakeLists.txt deleted file mode 100644 index 414f3b778ceef352f00619c60af6b73d5313a5be..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/plotting/CMakeLists.txt +++ /dev/null @@ -1,45 +0,0 @@ -target_sources(${library_name} PRIVATE - axistitlecontroller.cpp - axistitlecontroller.h - colormapcanvas.cpp - colormapcanvas.h - colormapinfoformatter.cpp - colormapinfoformatter.h - colormapplotcontroller.cpp - colormapplotcontroller.h - colormapviewportplotcontroller.cpp - colormapviewportplotcontroller.h - colorscaleplotcontroller.cpp - colorscaleplotcontroller.h - customplotproxywidget.cpp - customplotproxywidget.h - customplotsceneadapter.cpp - customplotsceneadapter.h - customplotutils.cpp - customplotutils.h - data1dplotcontroller.cpp - data1dplotcontroller.h - data2dplotcontroller.cpp - data2dplotcontroller.h - graphcanvas.cpp - graphcanvas.h - graphinfoformatter.cpp - graphinfoformatter.h - graphplotcontroller.cpp - graphplotcontroller.h - graphviewportplotcontroller.cpp - graphviewportplotcontroller.h - mousemovereporter.cpp - mousemovereporter.h - mouseposinfo.h - pencontroller.cpp - pencontroller.h - sceneadapterinterface.h - statusstringformatterinterface.h - statusstringreporter.cpp - statusstringreporter.h - statusstringreporterfactory.cpp - statusstringreporterfactory.h - viewportaxisplotcontroller.cpp - viewportaxisplotcontroller.h -) diff --git a/mvvm/view/mvvm/plotting/axistitlecontroller.cpp b/mvvm/view/mvvm/plotting/axistitlecontroller.cpp deleted file mode 100644 index 79623e7f3dbb6b2073bf9b48ce0922c012323402..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/plotting/axistitlecontroller.cpp +++ /dev/null @@ -1,57 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/plotting/axistitlecontroller.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/plotting/axistitlecontroller.h" -#include "mvvm/standarditems/plottableitems.h" -#include "qcustomplot.h" -#include <stdexcept> - -using namespace ModelView; - -struct AxisTitleController::AxisTitleControllerImpl { - QCPAxis* m_axis{nullptr}; - - AxisTitleControllerImpl(QCPAxis* axis) : m_axis(axis) - { - if (!axis) - throw std::runtime_error("AxisTitleController: axis is not initialized."); - } - - void updateAxisFromItem(TextItem* item) - { - auto font = m_axis->labelFont(); - font.setPointSize(item->property<int>(TextItem::P_SIZE)); - font.setFamily(QString::fromStdString(item->property<std::string>(TextItem::P_FONT))); - m_axis->setLabel(QString::fromStdString(item->property<std::string>(TextItem::P_TEXT))); - m_axis->setLabelFont(font); - - m_axis->parentPlot()->replot(); - } -}; - -AxisTitleController::AxisTitleController(QCPAxis* axis) - : p_impl(std::make_unique<AxisTitleControllerImpl>(axis)) - -{ -} - -AxisTitleController::~AxisTitleController() = default; - -void AxisTitleController::subscribe() -{ - auto on_property_change = [this](auto, auto) { p_impl->updateAxisFromItem(currentItem()); }; - setOnPropertyChange(on_property_change); - - p_impl->updateAxisFromItem(currentItem()); -} diff --git a/mvvm/view/mvvm/plotting/axistitlecontroller.h b/mvvm/view/mvvm/plotting/axistitlecontroller.h deleted file mode 100644 index 45d33d11ee55a5e68223ca7b5c83de40c50055cd..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/plotting/axistitlecontroller.h +++ /dev/null @@ -1,45 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/plotting/axistitlecontroller.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_AXISTITLECONTROLLER_H -#define BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_AXISTITLECONTROLLER_H - -#include "mvvm/signals/itemlistener.h" -#include "mvvm/view_export.h" -#include <memory> - -class QCPAxis; - -namespace ModelView { - -class TextItem; - -//! Propagates title settings from TextItem to QCPAxis. - -class MVVM_VIEW_EXPORT AxisTitleController : public ItemListener<TextItem> { -public: - explicit AxisTitleController(QCPAxis* axis); - ~AxisTitleController() override; - -protected: - void subscribe() override; - -public: - struct AxisTitleControllerImpl; - std::unique_ptr<AxisTitleControllerImpl> p_impl; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_AXISTITLECONTROLLER_H diff --git a/mvvm/view/mvvm/plotting/colormapcanvas.cpp b/mvvm/view/mvvm/plotting/colormapcanvas.cpp deleted file mode 100644 index 0dcd7bbd4ccf521492e2d22cd54e53f1f2a247c2..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/plotting/colormapcanvas.cpp +++ /dev/null @@ -1,72 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/plotting/colormapcanvas.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/plotting/colormapcanvas.h" -#include "mvvm/plotting/colormapviewportplotcontroller.h" -#include "mvvm/plotting/customplotsceneadapter.h" -#include "mvvm/plotting/statusstringreporter.h" -#include "mvvm/plotting/statusstringreporterfactory.h" -#include "mvvm/standarditems/colormapviewportitem.h" -#include "mvvm/widgets/statuslabel.h" -#include "qcustomplot.h" - -using namespace ModelView; - -struct ColorMapCanvas::ColorMapCanvasImpl { - QCustomPlot* custom_plot{nullptr}; - std::unique_ptr<ColorMapViewportPlotController> viewport_controller; - std::unique_ptr<StatusStringReporter> reporter; - StatusLabel* status_label{nullptr}; - - ColorMapCanvasImpl() : custom_plot(new QCustomPlot), status_label(new StatusLabel) - { - viewport_controller = std::make_unique<ColorMapViewportPlotController>(custom_plot); - - auto on_mouse_move = [this](const std::string& str) { - status_label->setText(QString::fromStdString(str)); - }; - reporter = CreateColorMapReporter(custom_plot, on_mouse_move); - } - - QCustomPlot* customPlot() { return custom_plot; } -}; - -ColorMapCanvas::ColorMapCanvas(QWidget* parent) - : QWidget(parent), p_impl(std::make_unique<ColorMapCanvasImpl>()) -{ - auto layout = new QVBoxLayout(this); - layout->setMargin(0); - layout->setSpacing(0); - layout->addWidget(p_impl->custom_plot); - layout->addWidget(p_impl->status_label); - setLayout(layout); - - p_impl->customPlot()->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); - p_impl->customPlot()->axisRect()->setupFullAxesBox(true); -} - -ColorMapCanvas::~ColorMapCanvas() = default; - -void ColorMapCanvas::setItem(ColorMapViewportItem* viewport_item) -{ - p_impl->viewport_controller->setItem(viewport_item); -} - -//! Creates adapter to convert widget coordinates, to QCustomPlot internal coordinate system -//! (defined by its axes). - -std::unique_ptr<SceneAdapterInterface> ColorMapCanvas::createSceneAdapter() const -{ - return std::make_unique<CustomPlotSceneAdapter>(p_impl->customPlot()); -} diff --git a/mvvm/view/mvvm/plotting/colormapcanvas.h b/mvvm/view/mvvm/plotting/colormapcanvas.h deleted file mode 100644 index 00058b7562e74c962b429c511bcb31bdb58f3340..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/plotting/colormapcanvas.h +++ /dev/null @@ -1,48 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/plotting/colormapcanvas.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_COLORMAPCANVAS_H -#define BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_COLORMAPCANVAS_H - -#include "mvvm/view_export.h" -#include <QWidget> -#include <memory> - -namespace ModelView { - -class ColorMapViewportItem; -class SceneAdapterInterface; - -//! Widget to show 2D data as color map. -//! Contains embedded QCustomPlot widget, shows content of ColorMapViewportItem. - -class MVVM_VIEW_EXPORT ColorMapCanvas : public QWidget { - Q_OBJECT - -public: - explicit ColorMapCanvas(QWidget* parent = nullptr); - ~ColorMapCanvas() override; - - void setItem(ColorMapViewportItem* viewport_item); - - std::unique_ptr<SceneAdapterInterface> createSceneAdapter() const; - -private: - struct ColorMapCanvasImpl; - std::unique_ptr<ColorMapCanvasImpl> p_impl; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_COLORMAPCANVAS_H diff --git a/mvvm/view/mvvm/plotting/colormapinfoformatter.cpp b/mvvm/view/mvvm/plotting/colormapinfoformatter.cpp deleted file mode 100644 index 7e6bc5838aca4ac2386549eb07fd5586f3add153..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/plotting/colormapinfoformatter.cpp +++ /dev/null @@ -1,64 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/plotting/colormapinfoformatter.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/plotting/colormapinfoformatter.h" -#include "mvvm/utils/stringutils.h" -#include "qcustomplot.h" -#include <sstream> - -using namespace ModelView; - -namespace { -QCPColorMap* find_colormap(QCustomPlot* custom_plot) -{ - for (int i = 0; i < custom_plot->plottableCount(); ++i) { - if (auto plottable = dynamic_cast<QCPColorMap*>(custom_plot->plottable()); plottable) - return plottable; - } - - return nullptr; -} - -struct Context { - double xpos{0.0}; - double ypos{0.0}; - int nx{0}; - int ny{0}; - double value{0.0}; -}; - -std::string compose_string(const Context& context) -{ - std::ostringstream ostr; - ostr << "[x: " << Utils::DoubleToString(context.xpos, 3) << ", "; - ostr << "y: " << Utils::DoubleToString(context.ypos, 3) << "] "; - ostr << "[binx: " << context.nx << ", "; - ostr << "biny: " << context.ny << "] "; - ostr << "[value: " << Utils::ScientificDoubleToString(context.value) << "]"; - return ostr.str(); -} - -} // namespace - -std::string ColorMapInfoFormatter::status_string(QCustomPlot* custom_plot, double x, double y) const -{ - // shall we provide caching here? - auto color_map = find_colormap(custom_plot); - Context context{x, y}; - - color_map->data()->coordToCell(x, y, &context.nx, &context.ny); - context.value = color_map->data()->cell(context.nx, context.ny); - - return compose_string(context); -} diff --git a/mvvm/view/mvvm/plotting/colormapinfoformatter.h b/mvvm/view/mvvm/plotting/colormapinfoformatter.h deleted file mode 100644 index 8ca372d83731ffd351e7b754c288b3b7f9fab346..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/plotting/colormapinfoformatter.h +++ /dev/null @@ -1,38 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/plotting/colormapinfoformatter.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_COLORMAPINFOFORMATTER_H -#define BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_COLORMAPINFOFORMATTER_H - -#include "mvvm/plotting/statusstringformatterinterface.h" - -class QCustomPlot; - -namespace ModelView { - -//! Formats status string for current mouse position in QCPColorMap. -//! Includes coordinates of mouse pointer in viewport axes coordinates, add bins info for -//! QCPColorMap beneath. - -class MVVM_VIEW_EXPORT ColorMapInfoFormatter : public StatusStringFormatterInterface { -public: - //! Returns status string representing data in color map. - //! @params x: mouse x-position given in axis viewport coordinates - //! @params y: mouse y-position given in axis viewport coordinates - std::string status_string(QCustomPlot* custom_plot, double x, double y) const override; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_COLORMAPINFOFORMATTER_H diff --git a/mvvm/view/mvvm/plotting/colormapplotcontroller.cpp b/mvvm/view/mvvm/plotting/colormapplotcontroller.cpp deleted file mode 100644 index 3eda5fadf32340e0d8b0a6c21319012718c00454..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/plotting/colormapplotcontroller.cpp +++ /dev/null @@ -1,131 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/plotting/colormapplotcontroller.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/plotting/colormapplotcontroller.h" -#include "mvvm/model/comboproperty.h" -#include "mvvm/plotting/data2dplotcontroller.h" -#include "mvvm/standarditems/colormapitem.h" -#include "mvvm/standarditems/data2ditem.h" -#include "qcustomplot.h" -#include <map> - -namespace { -using gradient_map_t = std::map<std::string, QCPColorGradient::GradientPreset>; -gradient_map_t createGradientMap() -{ - gradient_map_t result; - - result["Grayscale"] = QCPColorGradient::gpGrayscale; - result["Hot"] = QCPColorGradient::gpHot; - result["Cold"] = QCPColorGradient::gpCold; - result["Night"] = QCPColorGradient::gpNight; - result["Candy"] = QCPColorGradient::gpCandy; - result["Geography"] = QCPColorGradient::gpGeography; - result["Ion"] = QCPColorGradient::gpIon; - result["Thermal"] = QCPColorGradient::gpThermal; - result["Polar"] = QCPColorGradient::gpPolar; - result["Spectrum"] = QCPColorGradient::gpSpectrum; - result["Jet"] = QCPColorGradient::gpJet; - result["Hues"] = QCPColorGradient::gpHues; - - return result; -} - -QCPColorGradient getGradient(const std::string& gradientName) -{ - static gradient_map_t gradient_map = createGradientMap(); - auto it = gradient_map.find(gradientName); - return it != gradient_map.end() ? QCPColorGradient(it->second) : QCPColorGradient::gpSpectrum; -} - -} // namespace - -using namespace ModelView; - -struct ColorMapPlotController::ColorMapPlotControllerImpl { - ColorMapPlotController* master{nullptr}; - QCustomPlot* custom_plot{nullptr}; - QCPColorMap* color_map{nullptr}; - std::unique_ptr<Data2DPlotController> data_controller; - - ColorMapPlotControllerImpl(ColorMapPlotController* master, QCustomPlot* plot, - QCPColorScale* color_scale) - : master(master), custom_plot(plot) - { - color_map = new QCPColorMap(custom_plot->xAxis, custom_plot->yAxis); - data_controller = std::make_unique<Data2DPlotController>(color_map); - - if (color_scale) - color_map->setColorScale(color_scale); - } - - ~ColorMapPlotControllerImpl() { custom_plot->removePlottable(color_map); } - - ColorMapItem* colormap_item() { return master->currentItem(); } - - void update_colormap() - { - update_data_controller(); - update_interpolation(); - update_gradient(); - custom_plot->replot(); - } - - void update_data_controller() { data_controller->setItem(colormap_item()->dataItem()); } - - //! Updates QCPColorMap's interpolation when corresponding property of ColorMapItem changed. - - void update_interpolation() - { - auto is_interpolated = colormap_item()->property<bool>(ColorMapItem::P_INTERPOLATION); - color_map->setInterpolate(is_interpolated); - } - - void update_gradient() - { - auto combo = colormap_item()->property<ComboProperty>(ColorMapItem::P_GRADIENT); - color_map->setGradient(getGradient(combo.value())); - } -}; - -ColorMapPlotController::ColorMapPlotController(QCustomPlot* custom_plot, QCPColorScale* color_scale) - : p_impl(std::make_unique<ColorMapPlotControllerImpl>(this, custom_plot, color_scale)) -{ -} - -void ColorMapPlotController::subscribe() -{ - auto on_property_change = [this](SessionItem*, std::string property_name) { - if (property_name == ColorMapItem::P_INTERPOLATION) - p_impl->update_interpolation(); - - if (property_name == ColorMapItem::P_GRADIENT) - p_impl->update_gradient(); - - if (property_name == ColorMapItem::P_LINK) - p_impl->update_data_controller(); - - p_impl->custom_plot->replot(); - }; - setOnPropertyChange(on_property_change); - - p_impl->update_colormap(); -} - -void ColorMapPlotController::unsubscribe() -{ - p_impl->data_controller->setItem(nullptr); -} - -ColorMapPlotController::~ColorMapPlotController() = default; diff --git a/mvvm/view/mvvm/plotting/colormapplotcontroller.h b/mvvm/view/mvvm/plotting/colormapplotcontroller.h deleted file mode 100644 index a169eae79410bd7a9ff11f7d9f8366592e00239f..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/plotting/colormapplotcontroller.h +++ /dev/null @@ -1,50 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/plotting/colormapplotcontroller.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_COLORMAPPLOTCONTROLLER_H -#define BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_COLORMAPPLOTCONTROLLER_H - -#include "mvvm/signals/itemlistener.h" -#include "mvvm/view_export.h" -#include <memory> - -class QCustomPlot; -class QCPColorScale; - -namespace ModelView { - -class ColorMapItem; - -//! Establish communication between QCPColorMap and ColorMapItem. -//! Provide update on QCPColorMap when ColorMapItem is changed. QCPColorMap is added to -//! QCustomPlot plottables, when controller is created, and removed from plottables, when controller -//! is destroyed. - -class MVVM_VIEW_EXPORT ColorMapPlotController : public ItemListener<ColorMapItem> { -public: - explicit ColorMapPlotController(QCustomPlot* plot, QCPColorScale* color_scale = nullptr); - ~ColorMapPlotController() override; - -protected: - void subscribe() override; - void unsubscribe() override; - -private: - struct ColorMapPlotControllerImpl; - std::unique_ptr<ColorMapPlotControllerImpl> p_impl; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_COLORMAPPLOTCONTROLLER_H diff --git a/mvvm/view/mvvm/plotting/colormapviewportplotcontroller.cpp b/mvvm/view/mvvm/plotting/colormapviewportplotcontroller.cpp deleted file mode 100644 index 5b3b2aa654ec0225d4d3dfbd7c6e3953a304f9bf..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/plotting/colormapviewportplotcontroller.cpp +++ /dev/null @@ -1,87 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/plotting/colormapviewportplotcontroller.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/plotting/colormapviewportplotcontroller.h" -#include "mvvm/plotting/colormapplotcontroller.h" -#include "mvvm/plotting/colorscaleplotcontroller.h" -#include "mvvm/plotting/viewportaxisplotcontroller.h" -#include "mvvm/standarditems/axisitems.h" -#include "mvvm/standarditems/colormapitem.h" -#include "mvvm/standarditems/colormapviewportitem.h" -#include <list> -#include <qcustomplot.h> - -using namespace ModelView; - -struct ColorMapViewportPlotController::ColorMapViewportPlotControllerImpl { - ColorMapViewportPlotController* m_self{nullptr}; - QCustomPlot* m_customPlot{nullptr}; - QCPColorScale* m_colorScale{nullptr}; - std::unique_ptr<ViewportAxisPlotController> m_xAxisController; - std::unique_ptr<ViewportAxisPlotController> m_yAxisController; - std::unique_ptr<ColorScalePlotController> m_colorScaleController; - std::unique_ptr<ColorMapPlotController> m_colorMapController; - - ColorMapViewportPlotControllerImpl(ColorMapViewportPlotController* master, QCustomPlot* plot) - : m_self(master), m_customPlot(plot), m_colorScale(new QCPColorScale(m_customPlot)) - { - m_xAxisController = std::make_unique<ViewportAxisPlotController>(m_customPlot->xAxis); - m_yAxisController = std::make_unique<ViewportAxisPlotController>(m_customPlot->yAxis); - m_colorScaleController = std::make_unique<ColorScalePlotController>(m_colorScale); - m_colorMapController = std::make_unique<ColorMapPlotController>(m_customPlot, m_colorScale); - } - - ColorMapViewportItem* viewportItem() { return m_self->currentItem(); } - - //! Setup controller components. - - void setup_components() - { - auto viewport = viewportItem(); - m_xAxisController->setItem(viewport->xAxis()); - m_yAxisController->setItem(viewport->yAxis()); - m_colorScaleController->setItem(viewport->zAxis()); - auto colormap_item = viewportItem()->item<ColorMapItem>(ColorMapViewportItem::T_ITEMS); - m_colorMapController->setItem(colormap_item); - viewportItem()->setViewportToContent(); - } - - void unsubscribe_components() - { - m_xAxisController->setItem(nullptr); - m_yAxisController->setItem(nullptr); - m_colorScaleController->setItem(nullptr); - m_colorMapController->setItem(nullptr); - } -}; - -ColorMapViewportPlotController::ColorMapViewportPlotController(QCustomPlot* custom_plot) - : p_impl(std::make_unique<ColorMapViewportPlotControllerImpl>(this, custom_plot)) -{ -} - -void ColorMapViewportPlotController::subscribe() -{ - auto on_item_inserted = [this](SessionItem*, TagRow) { p_impl->setup_components(); }; - setOnItemInserted(on_item_inserted); - - p_impl->setup_components(); -} - -void ColorMapViewportPlotController::unsubscribe() -{ - p_impl->unsubscribe_components(); -} - -ColorMapViewportPlotController::~ColorMapViewportPlotController() = default; diff --git a/mvvm/view/mvvm/plotting/colormapviewportplotcontroller.h b/mvvm/view/mvvm/plotting/colormapviewportplotcontroller.h deleted file mode 100644 index 91fe056782fa2d0cd75b48bcd12001120d36c2b8..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/plotting/colormapviewportplotcontroller.h +++ /dev/null @@ -1,47 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/plotting/colormapviewportplotcontroller.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_COLORMAPVIEWPORTPLOTCONTROLLER_H -#define BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_COLORMAPVIEWPORTPLOTCONTROLLER_H - -#include "mvvm/signals/itemlistener.h" -#include "mvvm/view_export.h" -#include <memory> - -class QCustomPlot; - -namespace ModelView { - -class ColorMapViewportItem; - -//! Establishes communications and mutual updates for ColorMapViewportItem and QCutomPlot. -//! Populates custom plot with color map and tracks updates in items. - -class MVVM_VIEW_EXPORT ColorMapViewportPlotController : public ItemListener<ColorMapViewportItem> { -public: - explicit ColorMapViewportPlotController(QCustomPlot* plot); - ~ColorMapViewportPlotController() override; - -protected: - void subscribe() override; - void unsubscribe() override; - -private: - struct ColorMapViewportPlotControllerImpl; - std::unique_ptr<ColorMapViewportPlotControllerImpl> p_impl; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_COLORMAPVIEWPORTPLOTCONTROLLER_H diff --git a/mvvm/view/mvvm/plotting/colorscaleplotcontroller.cpp b/mvvm/view/mvvm/plotting/colorscaleplotcontroller.cpp deleted file mode 100644 index cedd354f2e7cb91bd98fc8c6156f1a0647a22ecc..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/plotting/colorscaleplotcontroller.cpp +++ /dev/null @@ -1,106 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/plotting/colorscaleplotcontroller.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/plotting/colorscaleplotcontroller.h" -#include "mvvm/plotting/viewportaxisplotcontroller.h" -#include "mvvm/standarditems/axisitems.h" -#include "qcustomplot.h" -#include <stdexcept> - -using namespace ModelView; - -struct ColorScalePlotController::ColorScalePlotControllerImpl { - - ColorScalePlotController* controller{nullptr}; - QCPColorScale* color_scale{nullptr}; - QCPLayoutGrid* layout_grid{new QCPLayoutGrid}; - std::unique_ptr<ViewportAxisPlotController> axisController; - QCPMarginGroup* margin_group{nullptr}; - - ColorScalePlotControllerImpl(ColorScalePlotController* controller, QCPColorScale* color_scale) - : controller(controller), color_scale(color_scale) - { - if (!color_scale) - throw std::runtime_error("ColorScalePlotController: axis is not initialized."); - - axisController = std::make_unique<ViewportAxisPlotController>(color_scale->axis()); - } - - void setup_components() - { - axisController->setItem(controller->currentItem()); - update_log_scale(); - show_colorscale(); - setup_margins(); - } - - //! Updates color scale for log10. - - void update_log_scale() - { - const bool is_log = controller->currentItem()->is_in_log(); - color_scale->setDataScaleType(is_log ? QCPAxis::stLogarithmic : QCPAxis::stLinear); - } - - void show_colorscale() - { - if (!layout_grid->hasElement(0, 0)) - layout_grid->addElement(0, 0, color_scale); - - layout_grid->setVisible(true); - customPlot()->plotLayout()->addElement(0, 1, layout_grid); - } - - void hide_colorscale() - { - layout_grid->setVisible(false); - customPlot()->plotLayout()->take(layout_grid); - customPlot()->plotLayout()->simplify(); - } - - //! Setup margins of color scale to match top/bottom margins of axis rectangle. - - void setup_margins() - { - if (margin_group) - return; - - if (!customPlot()->axisRect()) - return; - margin_group = new QCPMarginGroup(customPlot()); - customPlot()->axisRect()->setMarginGroup(QCP::msBottom | QCP::msTop, margin_group); - color_scale->setMarginGroup(QCP::msBottom | QCP::msTop, margin_group); - } - - QCustomPlot* customPlot() { return color_scale->parentPlot(); } -}; - -ColorScalePlotController::ColorScalePlotController(QCPColorScale* color_scale) - : p_impl(std::make_unique<ColorScalePlotControllerImpl>(this, color_scale)) - -{ -} - -ColorScalePlotController::~ColorScalePlotController() = default; - -void ColorScalePlotController::subscribe() -{ - auto on_property_change = [this](SessionItem*, std::string property_name) { - if (property_name == ViewportAxisItem::P_IS_LOG) - p_impl->update_log_scale(); - }; - setOnPropertyChange(on_property_change); - - p_impl->setup_components(); -} diff --git a/mvvm/view/mvvm/plotting/colorscaleplotcontroller.h b/mvvm/view/mvvm/plotting/colorscaleplotcontroller.h deleted file mode 100644 index 5dc13381fef9301c001a6e3f18f1d434ae206a73..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/plotting/colorscaleplotcontroller.h +++ /dev/null @@ -1,45 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/plotting/colorscaleplotcontroller.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_COLORSCALEPLOTCONTROLLER_H -#define BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_COLORSCALEPLOTCONTROLLER_H - -#include "mvvm/signals/itemlistener.h" -#include "mvvm/view_export.h" -#include <memory> - -class QCPColorScale; - -namespace ModelView { - -class ViewportAxisItem; - -//! Establishes communication between QCPColorScale and ViewportAxisItem. - -class MVVM_VIEW_EXPORT ColorScalePlotController : public ItemListener<ViewportAxisItem> { -public: - explicit ColorScalePlotController(QCPColorScale* color_scale); - ~ColorScalePlotController() override; - -protected: - void subscribe() override; - -public: - struct ColorScalePlotControllerImpl; - std::unique_ptr<ColorScalePlotControllerImpl> p_impl; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_COLORSCALEPLOTCONTROLLER_H diff --git a/mvvm/view/mvvm/plotting/customplotproxywidget.cpp b/mvvm/view/mvvm/plotting/customplotproxywidget.cpp deleted file mode 100644 index e077d6335521c1a2037b836acad5c9c788db6a78..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/plotting/customplotproxywidget.cpp +++ /dev/null @@ -1,75 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/plotting/customplotproxywidget.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/plotting/customplotproxywidget.h" -#include <QEvent> -#include <QGraphicsScene> -#include <QGraphicsSceneMouseEvent> -#include <QGraphicsSceneWheelEvent> -#include <QWidget> - -using namespace ModelView; - -CustomPlotProxyWidget::CustomPlotProxyWidget(QWidget* colormap) -{ - setWidget(colormap); - colormap->installEventFilter(this); -} - -//! Notifies all graphics items about axes viewport change in QCustomPlot. -//! Used in RegionOfInterestView to recalculate bounding box and scene positions depending on -//! current state of CustomPlotSceneAdapter. - -bool CustomPlotProxyWidget::eventFilter(QObject* /*object*/, QEvent* event) -{ - // catching zoom/resize events in QCustomPlot - if (event->type() == QEvent::Resize || event->type() == QEvent::UpdateRequest) { - scene()->advance(); // notifying all graphics items - return false; - } - return true; -} - -void CustomPlotProxyWidget::setBlockSignalsToProxy(bool value) -{ - block_signals_to_proxy = value; -} - -void CustomPlotProxyWidget::mousePressEvent(QGraphicsSceneMouseEvent* event) -{ - if (block_signals_to_proxy) - return; - QGraphicsProxyWidget::mousePressEvent(event); -} - -void CustomPlotProxyWidget::mouseMoveEvent(QGraphicsSceneMouseEvent* event) -{ - if (block_signals_to_proxy) - return; - QGraphicsProxyWidget::mouseMoveEvent(event); -} - -void CustomPlotProxyWidget::mouseReleaseEvent(QGraphicsSceneMouseEvent* event) -{ - if (block_signals_to_proxy) - return; - QGraphicsProxyWidget::mouseReleaseEvent(event); -} - -void CustomPlotProxyWidget::wheelEvent(QGraphicsSceneWheelEvent* event) -{ - if (block_signals_to_proxy) - return; - QGraphicsProxyWidget::wheelEvent(event); -} diff --git a/mvvm/view/mvvm/plotting/customplotproxywidget.h b/mvvm/view/mvvm/plotting/customplotproxywidget.h deleted file mode 100644 index 09d999a063d430cc82f5b38bc4a6a0b0f195114b..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/plotting/customplotproxywidget.h +++ /dev/null @@ -1,49 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/plotting/customplotproxywidget.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_CUSTOMPLOTPROXYWIDGET_H -#define BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_CUSTOMPLOTPROXYWIDGET_H - -#include "mvvm/view_export.h" -#include <QGraphicsProxyWidget> - -class QWidget; - -namespace ModelView { - -//! Custom proxy widget to embed color map in graphics scene. - -class MVVM_VIEW_EXPORT CustomPlotProxyWidget : public QGraphicsProxyWidget { - Q_OBJECT - -public: - CustomPlotProxyWidget(QWidget* colormap); - - bool eventFilter(QObject* object, QEvent* event); - - void setBlockSignalsToProxy(bool value); - -protected: - void mousePressEvent(QGraphicsSceneMouseEvent* event); - void mouseMoveEvent(QGraphicsSceneMouseEvent* event); - void mouseReleaseEvent(QGraphicsSceneMouseEvent* event); - void wheelEvent(QGraphicsSceneWheelEvent* event); - -private: - bool block_signals_to_proxy{false}; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_CUSTOMPLOTPROXYWIDGET_H diff --git a/mvvm/view/mvvm/plotting/customplotsceneadapter.cpp b/mvvm/view/mvvm/plotting/customplotsceneadapter.cpp deleted file mode 100644 index 5811f1a6d8943acdd7f5709247a711018ba2dd65..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/plotting/customplotsceneadapter.cpp +++ /dev/null @@ -1,100 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/plotting/customplotsceneadapter.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "customplotsceneadapter.h" -#include "qcustomplot.h" -#include <QObject> - -using namespace ModelView; - -struct CustomPlotSceneAdapter::CustomPlotSceneAdapterImpl { - QCustomPlot* custom_plot{nullptr}; - std::unique_ptr<QMetaObject::Connection> conn_to_customplot; - CustomPlotSceneAdapterImpl(QCustomPlot* custom_plot) : custom_plot(custom_plot) - { - conn_to_customplot = std::make_unique<QMetaObject::Connection>(); - } - - double toSceneX(double customplot_x) const - { - return custom_plot ? custom_plot->xAxis->coordToPixel(customplot_x) : customplot_x; - } - - double toSceneY(double customplot_y) const - { - return custom_plot ? custom_plot->yAxis->coordToPixel(customplot_y) : customplot_y; - } - - double fromSceneX(double scene_x) const - { - return custom_plot ? custom_plot->xAxis->pixelToCoord(scene_x) : scene_x; - } - - double fromSceneY(double scene_y) const - { - return custom_plot ? custom_plot->yAxis->pixelToCoord(scene_y) : scene_y; - } - - QRectF viewportRectangle() const - { - if (!custom_plot) - return {}; - - auto xrange = custom_plot->xAxis->range(); - auto yrange = custom_plot->yAxis->range(); - - return QRectF(toSceneX(xrange.lower), toSceneY(yrange.upper), - toSceneX(xrange.upper) - toSceneX(xrange.lower), - toSceneY(yrange.lower) - toSceneY(yrange.upper)); - } -}; - -CustomPlotSceneAdapter::CustomPlotSceneAdapter(QCustomPlot* custom_plot) - : p_impl(std::make_unique<CustomPlotSceneAdapterImpl>(custom_plot)) -{ - auto on_customplot_destroy = [this]() { p_impl->custom_plot = nullptr; }; - *p_impl->conn_to_customplot = - QObject::connect(custom_plot, &QCustomPlot::destroyed, on_customplot_destroy); -} - -CustomPlotSceneAdapter::~CustomPlotSceneAdapter() -{ - if (p_impl->custom_plot) - QObject::disconnect(*p_impl->conn_to_customplot); -} - -double CustomPlotSceneAdapter::toSceneX(double customplot_x) const -{ - return p_impl->toSceneX(customplot_x); -} - -double CustomPlotSceneAdapter::toSceneY(double customplot_y) const -{ - return p_impl->toSceneY(customplot_y); -} - -double CustomPlotSceneAdapter::fromSceneX(double scene_x) const -{ - return p_impl->fromSceneX(scene_x); -} - -double CustomPlotSceneAdapter::fromSceneY(double scene_y) const -{ - return p_impl->fromSceneY(scene_y); -} - -QRectF CustomPlotSceneAdapter::viewportRectangle() const -{ - return p_impl->viewportRectangle(); -} diff --git a/mvvm/view/mvvm/plotting/customplotsceneadapter.h b/mvvm/view/mvvm/plotting/customplotsceneadapter.h deleted file mode 100644 index 56028a8db7960c8db1839341f96be2297fb1b841..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/plotting/customplotsceneadapter.h +++ /dev/null @@ -1,50 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/plotting/customplotsceneadapter.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_CUSTOMPLOTSCENEADAPTER_H -#define BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_CUSTOMPLOTSCENEADAPTER_H - -#include "mvvm/plotting/sceneadapterinterface.h" -#include <memory> - -class QCustomPlot; - -namespace ModelView { - -//! Converts QGraphicsScene coordinates in the coordinates of local system of QCustomPlot -//! and vice versa. - -class MVVM_VIEW_EXPORT CustomPlotSceneAdapter : public SceneAdapterInterface { -public: - explicit CustomPlotSceneAdapter(QCustomPlot* custom_plot); - ~CustomPlotSceneAdapter() override; - - double toSceneX(double customplot_x) const override; - - double toSceneY(double customplot_y) const override; - - double fromSceneX(double scene_x) const override; - - double fromSceneY(double scene_y) const override; - - QRectF viewportRectangle() const override; - -private: - struct CustomPlotSceneAdapterImpl; - std::unique_ptr<CustomPlotSceneAdapterImpl> p_impl; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_CUSTOMPLOTSCENEADAPTER_H diff --git a/mvvm/view/mvvm/plotting/customplotutils.cpp b/mvvm/view/mvvm/plotting/customplotutils.cpp deleted file mode 100644 index f12d1cc7dc784990b2931a0b9851896cfdc7bd6d..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/plotting/customplotutils.cpp +++ /dev/null @@ -1,44 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/plotting/customplotutils.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/plotting/customplotutils.h" -#include <qcustomplot.h> - -void ModelView::Utils::SetLogarithmicScale(QCPColorScale* axis, bool is_log_scale) -{ - if (is_log_scale && axis->dataScaleType() != QCPAxis::stLogarithmic) - axis->setDataScaleType(QCPAxis::stLogarithmic); - - else if (!is_log_scale && axis->dataScaleType() != QCPAxis::stLinear) - axis->setDataScaleType(QCPAxis::stLinear); - - SetLogarithmicScale(axis->axis(), is_log_scale); -} - -void ModelView::Utils::SetLogarithmicScale(QCPAxis* axis, bool is_log_scale) -{ - if (is_log_scale) { - axis->setNumberFormat("eb"); - axis->setNumberPrecision(0); - axis->setScaleType(QCPAxis::stLogarithmic); - QSharedPointer<QCPAxisTicker> ticker(new QCPAxisTickerLog); - axis->setTicker(ticker); - } else { - axis->setNumberFormat("g"); - axis->setNumberPrecision(6); - axis->setScaleType(QCPAxis::stLinear); - QSharedPointer<QCPAxisTicker> ticker(new QCPAxisTicker); - axis->setTicker(ticker); - } -} diff --git a/mvvm/view/mvvm/plotting/customplotutils.h b/mvvm/view/mvvm/plotting/customplotutils.h deleted file mode 100644 index 8dbfa648e589bbf664601e0edbd69740e348bc68..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/plotting/customplotutils.h +++ /dev/null @@ -1,35 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/plotting/customplotutils.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_CUSTOMPLOTUTILS_H -#define BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_CUSTOMPLOTUTILS_H - -#include "mvvm/view_export.h" - -class QCPColorScale; -class QCPAxis; - -namespace ModelView::Utils { - -//! Switch axis to logarithmic scale mode. - -MVVM_VIEW_EXPORT void SetLogarithmicScale(QCPColorScale* axis, bool is_log_scale); - -//! Switch axis to logarithmic scale mode. - -MVVM_VIEW_EXPORT void SetLogarithmicScale(QCPAxis* axis, bool is_log_scale); - -} // namespace ModelView::Utils - -#endif // BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_CUSTOMPLOTUTILS_H diff --git a/mvvm/view/mvvm/plotting/data1dplotcontroller.cpp b/mvvm/view/mvvm/plotting/data1dplotcontroller.cpp deleted file mode 100644 index c9320507315d573f1dc700ad5219e63f4a3201f8..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/plotting/data1dplotcontroller.cpp +++ /dev/null @@ -1,114 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/plotting/data1dplotcontroller.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/plotting/data1dplotcontroller.h" -#include "mvvm/standarditems/data1ditem.h" -#include "qcustomplot.h" -#include <stdexcept> - -namespace { -template <typename T> QVector<T> fromStdVector(const std::vector<T>& vec) -{ -#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) - return QVector<T>(vec.begin(), vec.end()); -#else - return QVector<T>::fromStdVector(vec); -#endif -} -} // namespace - -using namespace ModelView; - -struct Data1DPlotController::Data1DPlotControllerImpl { - QCPGraph* m_graph{nullptr}; - QCPErrorBars* m_errorBars{nullptr}; - - Data1DPlotControllerImpl(QCPGraph* graph) : m_graph(graph) - { - if (!m_graph) - throw std::runtime_error("Uninitialized graph in Data1DPlotController"); - } - - void initGraphFromItem(Data1DItem* item) - { - assert(item); - updateGraphPointsFromItem(item); - updateErrorBarsFromItem(item); - } - - void updateGraphPointsFromItem(Data1DItem* item) - { - m_graph->setData(fromStdVector<double>(item->binCenters()), - fromStdVector<double>(item->binValues())); - customPlot()->replot(); - } - - void updateErrorBarsFromItem(Data1DItem* item) - { - auto errors = item->binErrors(); - if (errors.empty()) { - resetErrorBars(); - return; - } - - if (!m_errorBars) - m_errorBars = new QCPErrorBars(customPlot()->xAxis, customPlot()->yAxis); - - m_errorBars->setData(fromStdVector<double>(errors)); - m_errorBars->setDataPlottable(m_graph); - } - - void resetGraph() - { - m_graph->setData(QVector<double>{}, QVector<double>{}); - customPlot()->replot(); - } - - void resetErrorBars() - { - delete m_errorBars; - m_errorBars = nullptr; - } - - QCustomPlot* customPlot() - { - assert(m_graph); - return m_graph->parentPlot(); - } -}; - -Data1DPlotController::Data1DPlotController(QCPGraph* graph) - : p_impl(std::make_unique<Data1DPlotControllerImpl>(graph)) -{ -} - -Data1DPlotController::~Data1DPlotController() = default; - -void Data1DPlotController::subscribe() -{ - auto on_property_change = [this](SessionItem*, std::string property_name) { - if (property_name == Data1DItem::P_VALUES) - p_impl->updateGraphPointsFromItem(currentItem()); - if (property_name == Data1DItem::P_ERRORS) - p_impl->updateErrorBarsFromItem(currentItem()); - }; - setOnPropertyChange(on_property_change); - - p_impl->initGraphFromItem(currentItem()); -} - -void Data1DPlotController::unsubscribe() -{ - p_impl->resetGraph(); -} diff --git a/mvvm/view/mvvm/plotting/data1dplotcontroller.h b/mvvm/view/mvvm/plotting/data1dplotcontroller.h deleted file mode 100644 index e1d9a7f561680ae25e258be77b98b61597897556..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/plotting/data1dplotcontroller.h +++ /dev/null @@ -1,47 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/plotting/data1dplotcontroller.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_DATA1DPLOTCONTROLLER_H -#define BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_DATA1DPLOTCONTROLLER_H - -#include "mvvm/signals/itemlistener.h" -#include "mvvm/view_export.h" -#include <memory> - -class QCPGraph; - -namespace ModelView { - -class Data1DItem; - -//! Establishes communication between QCPGraph and Data1DItem. -//! Provides update of data points on QCPGraph when Graph1DItem is changed. - -class MVVM_VIEW_EXPORT Data1DPlotController : public ItemListener<Data1DItem> { -public: - explicit Data1DPlotController(QCPGraph* graph); - ~Data1DPlotController() override; - -protected: - void subscribe() override; - void unsubscribe() override; - -private: - struct Data1DPlotControllerImpl; - std::unique_ptr<Data1DPlotControllerImpl> p_impl; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_DATA1DPLOTCONTROLLER_H diff --git a/mvvm/view/mvvm/plotting/data2dplotcontroller.cpp b/mvvm/view/mvvm/plotting/data2dplotcontroller.cpp deleted file mode 100644 index 3f96016822e76a73b40339dca65e02279345ec5b..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/plotting/data2dplotcontroller.cpp +++ /dev/null @@ -1,93 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/plotting/data2dplotcontroller.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/plotting/data2dplotcontroller.h" -#include "mvvm/standarditems/axisitems.h" -#include "mvvm/standarditems/data2ditem.h" -#include "qcustomplot.h" -#include <algorithm> -#include <stdexcept> - -using namespace ModelView; - -namespace { -//! Returns QCPRange of axis. -QCPRange qcpRange(const BinnedAxisItem* axis) -{ - auto centers = axis->binCenters(); // QCPColorMapData expects centers of bin - return centers.empty() ? QCPRange() : QCPRange(centers.front(), centers.back()); -} -} // namespace - -struct Data2DPlotController::Data2DPlotControllerImpl { - Data2DPlotController* master{nullptr}; - QCPColorMap* color_map{nullptr}; - Data2DPlotControllerImpl(Data2DPlotController* master, QCPColorMap* color_map) - : master(master), color_map(color_map) - { - if (!color_map) - throw std::runtime_error("Uninitialized colormap in Data2DPlotController"); - } - - Data2DItem* dataItem() { return master->currentItem(); } - - void update_data_points() - { - reset_colormap(); - - if (auto data_item = dataItem(); data_item) { - auto xAxis = data_item->xAxis(); - auto yAxis = data_item->yAxis(); - if (xAxis && yAxis) { - const int nbinsx = xAxis->size(); - const int nbinsy = yAxis->size(); - - color_map->data()->setSize(nbinsx, nbinsy); - color_map->data()->setRange(qcpRange(xAxis), qcpRange(yAxis)); - - auto values = data_item->content(); - for (int ix = 0; ix < nbinsx; ++ix) - for (int iy = 0; iy < nbinsy; ++iy) - color_map->data()->setCell(ix, iy, - values[static_cast<size_t>(ix + iy * nbinsx)]); - - auto [min, max] = std::minmax_element(std::begin(values), std::end(values)); - color_map->setDataRange(QCPRange(*min, *max)); - } - } - color_map->parentPlot()->replot(); - } - - void reset_colormap() { color_map->data()->clear(); } -}; - -Data2DPlotController::Data2DPlotController(QCPColorMap* color_map) - : p_impl(std::make_unique<Data2DPlotControllerImpl>(this, color_map)) -{ -} - -Data2DPlotController::~Data2DPlotController() = default; - -void Data2DPlotController::subscribe() -{ - auto on_data_change = [this](SessionItem*, int) { p_impl->update_data_points(); }; - setOnDataChange(on_data_change); - - p_impl->update_data_points(); -} - -void Data2DPlotController::unsubscribe() -{ - p_impl->reset_colormap(); -} diff --git a/mvvm/view/mvvm/plotting/data2dplotcontroller.h b/mvvm/view/mvvm/plotting/data2dplotcontroller.h deleted file mode 100644 index 64a7abd3222e0d56335a70122052ec48afc42c4b..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/plotting/data2dplotcontroller.h +++ /dev/null @@ -1,47 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/plotting/data2dplotcontroller.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_DATA2DPLOTCONTROLLER_H -#define BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_DATA2DPLOTCONTROLLER_H - -#include "mvvm/signals/itemlistener.h" -#include "mvvm/view_export.h" -#include <memory> - -class QCPColorMap; - -namespace ModelView { - -class Data2DItem; - -//! Establish communication between QCPColorMap and Data2DItem. -//! Provide update of data points on QCPColorMap when Graph2DItem is changed. - -class MVVM_VIEW_EXPORT Data2DPlotController : public ItemListener<Data2DItem> { -public: - explicit Data2DPlotController(QCPColorMap* color_map); - ~Data2DPlotController() override; - -protected: - void subscribe() override; - void unsubscribe() override; - -private: - struct Data2DPlotControllerImpl; - std::unique_ptr<Data2DPlotControllerImpl> p_impl; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_DATA2DPLOTCONTROLLER_H diff --git a/mvvm/view/mvvm/plotting/graphcanvas.cpp b/mvvm/view/mvvm/plotting/graphcanvas.cpp deleted file mode 100644 index 7abd62e4c1b1040182138a55778127472b69387d..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/plotting/graphcanvas.cpp +++ /dev/null @@ -1,143 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/plotting/graphcanvas.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/plotting/graphcanvas.h" -#include "mvvm/plotting/customplotsceneadapter.h" -#include "mvvm/plotting/graphviewportplotcontroller.h" -#include "mvvm/plotting/statusstringreporter.h" -#include "mvvm/plotting/statusstringreporterfactory.h" -#include "mvvm/standarditems/graphviewportitem.h" -#include "mvvm/widgets/statuslabel.h" -#include "qcustomplot.h" -#include <QBoxLayout> - -namespace { - -//! Returns policy to which side of the axes box margins can be applied. -//! If number is negative, this side will be callulated automatically. - -// FIXME move to utils, provide unit tests -QCP::MarginSides autoMarginPolicy(int left, int top, int right, int bottom) -{ - QCP::MarginSides result{QCP::msAll}; - if (left >= 0) - result &= ~QCP::msLeft; - if (top >= 0) - result &= ~QCP::msTop; - if (right >= 0) - result &= ~QCP::msRight; - if (bottom >= 0) - result &= ~QCP::msBottom; - return result; -} -} // namespace - -using namespace ModelView; - -struct GraphCanvas::GraphCanvasImpl { - QCustomPlot* custom_plot{nullptr}; - std::unique_ptr<GraphViewportPlotController> viewport_controller; - std::unique_ptr<StatusStringReporter> reporter; - StatusLabel* status_label{nullptr}; - - GraphCanvasImpl() : custom_plot(new QCustomPlot), status_label(new StatusLabel) - { - viewport_controller = std::make_unique<GraphViewportPlotController>(custom_plot); - - auto on_mouse_move = [this](const std::string& str) { - status_label->setText(QString::fromStdString(str)); - }; - reporter = CreateGraphReporter(custom_plot, on_mouse_move); - } - - //! Updates viewport. - void setViewportToContent() - { - if (!viewport_controller->currentItem()) - return; - viewport_controller->currentItem()->setViewportToContent(); - } - - //! Updates viewport. - void setViewportToContent(double left, double top, double right, double bottom) - { - if (!viewport_controller->currentItem()) - return; - viewport_controller->currentItem()->setViewportToContent(left, top, right, bottom); - } - - QCustomPlot* customPlot() { return custom_plot; } -}; - -GraphCanvas::GraphCanvas(QWidget* parent) - : QWidget(parent), p_impl(std::make_unique<GraphCanvasImpl>()) -{ - auto layout = new QVBoxLayout(this); - layout->setMargin(0); - layout->setSpacing(0); - layout->addWidget(p_impl->custom_plot); - layout->addWidget(p_impl->status_label); - setLayout(layout); - - setMouseTracking(true); - p_impl->customPlot()->setMouseTracking(true); - p_impl->customPlot()->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); - p_impl->customPlot()->axisRect()->setupFullAxesBox(true); - - auto on_replot = [this]() { - QMargins margins = p_impl->customPlot()->axisRect()->margins(); - axisMarginsChanged(margins.left(), margins.top(), margins.right(), margins.bottom()); - }; - connect(p_impl->customPlot(), &QCustomPlot::afterReplot, this, on_replot); -} - -GraphCanvas::~GraphCanvas() = default; - -void GraphCanvas::setItem(GraphViewportItem* viewport_item) -{ - p_impl->viewport_controller->setItem(viewport_item); -} - -std::unique_ptr<SceneAdapterInterface> GraphCanvas::createSceneAdapter() const -{ - return std::make_unique<CustomPlotSceneAdapter>(p_impl->customPlot()); -} - -void GraphCanvas::setViewportToContent(double left, double top, double right, double bottom) -{ - p_impl->setViewportToContent(left, top, right, bottom); -} - -void GraphCanvas::setViewportToContent() -{ - p_impl->setViewportToContent(); -} - -//! Set margins between axes rectangle and widget borders. -//! If the value is negative, leave old margin intact and allow automatic margin adjustment. - -void GraphCanvas::setAxisMargins(int left, int top, int right, int bottom) -{ - auto customPlot = p_impl->customPlot(); - customPlot->axisRect()->setAutoMargins(autoMarginPolicy(left, top, right, bottom)); - - QMargins orig = customPlot->axisRect()->margins(); - int new_left = left >= 0 ? left : orig.left(); - int new_top = top >= 0 ? top : orig.top(); - int new_right = right >= 0 ? right : orig.right(); - int new_bottom = bottom >= 0 ? bottom : orig.bottom(); - customPlot->axisRect()->setMargins(QMargins(new_left, new_top, new_right, new_bottom)); - - customPlot->replot(); -} diff --git a/mvvm/view/mvvm/plotting/graphcanvas.h b/mvvm/view/mvvm/plotting/graphcanvas.h deleted file mode 100644 index d0d42c4013b5f0b180ff91c89f412282eace1a5a..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/plotting/graphcanvas.h +++ /dev/null @@ -1,57 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/plotting/graphcanvas.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_GRAPHCANVAS_H -#define BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_GRAPHCANVAS_H - -#include "mvvm/view_export.h" -#include <QWidget> -#include <memory> - -namespace ModelView { - -class GraphViewportItem; -class SceneAdapterInterface; - -//! Widget to show scientific figure with multiple 1D graphs. -//! Contains embedded QCustomPlot widget, shows content of GraphViewportItem. - -class MVVM_VIEW_EXPORT GraphCanvas : public QWidget { - Q_OBJECT - -public: - explicit GraphCanvas(QWidget* parent = nullptr); - ~GraphCanvas() override; - - void setItem(GraphViewportItem* viewport_item); - - std::unique_ptr<SceneAdapterInterface> createSceneAdapter() const; - - void setViewportToContent(double left, double top, double right, double bottom); - - void setViewportToContent(); - - void setAxisMargins(int left, int top, int right, int bottom); - -signals: - void axisMarginsChanged(int left, int top, int right, int bottom); - -private: - struct GraphCanvasImpl; - std::unique_ptr<GraphCanvasImpl> p_impl; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_GRAPHCANVAS_H diff --git a/mvvm/view/mvvm/plotting/graphinfoformatter.cpp b/mvvm/view/mvvm/plotting/graphinfoformatter.cpp deleted file mode 100644 index c26869cf2330abf529969fe377d6aa7835c1b3c8..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/plotting/graphinfoformatter.cpp +++ /dev/null @@ -1,74 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/plotting/graphinfoformatter.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/plotting/graphinfoformatter.h" -#include "mvvm/utils/stringutils.h" -#include <qcustomplot.h> -#include <sstream> - -using namespace ModelView; - -namespace { - -QCPGraph* find_graph_nearby(QCustomPlot* custom_plot, double x, double y) -{ - double widget_px = custom_plot->xAxis->coordToPixel(x); - double widget_py = custom_plot->yAxis->coordToPixel(y); - return dynamic_cast<QCPGraph*>(custom_plot->plottableAt(QPointF(widget_px, widget_py))); -} - -int getBin(const QCPGraph* graph, double x) -{ - const int key_start = graph->findBegin(x); - const int key_end = graph->findBegin(x, false); // false = do not expand range - if (key_end == key_start || key_end == graph->dataCount()) - return key_start; - return (x - graph->dataSortKey(key_start)) <= (graph->dataSortKey(key_end) - x) ? key_start - : key_end; -} - -struct Context { - double xpos{0.0}; - double ypos{0.0}; - bool close_to_graph{false}; - int nx{0}; - double value{0.0}; -}; - -std::string compose_string(const Context& context) -{ - std::ostringstream ostr; - ostr << "[x: " << Utils::DoubleToString(context.xpos, 3) << ", "; - ostr << "y: " << Utils::DoubleToString(context.ypos, 3) << "] "; - if (context.close_to_graph) { - ostr << "[binx: " << context.nx << "] "; - ostr << "[value: " << Utils::ScientificDoubleToString(context.value) << "]"; - } - return ostr.str(); -} - -} // namespace - -std::string GraphInfoFormatter::status_string(QCustomPlot* custom_plot, double x, double y) const -{ - Context context{x, y}; - - if (auto qcp_graph = find_graph_nearby(custom_plot, x, y); qcp_graph) { - context.close_to_graph = true; - context.nx = getBin(qcp_graph, x); - context.value = qcp_graph->dataMainValue(context.nx); - } - - return compose_string(context); -} diff --git a/mvvm/view/mvvm/plotting/graphinfoformatter.h b/mvvm/view/mvvm/plotting/graphinfoformatter.h deleted file mode 100644 index 5f9f34eb9a02e998dec9a5f5946a588407a7a221..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/plotting/graphinfoformatter.h +++ /dev/null @@ -1,38 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/plotting/graphinfoformatter.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_GRAPHINFOFORMATTER_H -#define BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_GRAPHINFOFORMATTER_H - -#include "mvvm/plotting/statusstringformatterinterface.h" - -class QCustomPlot; - -namespace ModelView { - -//! Formats status string for current mouse position in QCustomPlot with QCPGraph's. -//! Includes coordinates of mouse pointer in viewport axes coordinates, add graph info if there is -//! one nearby. - -class MVVM_VIEW_EXPORT GraphInfoFormatter : public StatusStringFormatterInterface { -public: - //! Returns status string representing graph nearby. - //! @params x: mouse x-position given in axis viewport coordinates - //! @params y: mouse y-position given in axis viewport coordinates - std::string status_string(QCustomPlot* custom_plot, double x, double y) const override; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_GRAPHINFOFORMATTER_H diff --git a/mvvm/view/mvvm/plotting/graphplotcontroller.cpp b/mvvm/view/mvvm/plotting/graphplotcontroller.cpp deleted file mode 100644 index 77f09297a4ac8d2bff7b2052c69364211e746d05..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/plotting/graphplotcontroller.cpp +++ /dev/null @@ -1,106 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/plotting/graphplotcontroller.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/plotting/graphplotcontroller.h" -#include "mvvm/model/comboproperty.h" -#include "mvvm/plotting/data1dplotcontroller.h" -#include "mvvm/plotting/pencontroller.h" -#include "mvvm/standarditems/data1ditem.h" -#include "mvvm/standarditems/graphitem.h" -#include "mvvm/standarditems/plottableitems.h" -#include "qcustomplot.h" - -using namespace ModelView; - -struct GraphPlotController::GraphItemControllerImpl { - GraphPlotController* m_self{nullptr}; - QCustomPlot* m_customPlot{nullptr}; - QCPGraph* m_graph{nullptr}; - std::unique_ptr<Data1DPlotController> m_dataController; - std::unique_ptr<PenController> m_penController; - - GraphItemControllerImpl(GraphPlotController* master, QCustomPlot* plot) - : m_self(master), m_customPlot(plot) - { - } - - //! Setups controllers and updates graph properties. - - void init_graph() - { - m_graph = m_customPlot->addGraph(); - m_dataController = std::make_unique<Data1DPlotController>(m_graph); - m_penController = std::make_unique<PenController>(m_graph); - - update_data_controller(); - update_graph_pen(); - update_visible(); - } - - ~GraphItemControllerImpl() - { - if (m_graph) - m_customPlot->removePlottable(m_graph); - } - - GraphItem* graph_item() { return m_self->currentItem(); } - - void update_data_controller() { m_dataController->setItem(graph_item()->dataItem()); } - - //! Updates graph pen from GraphItem. - - void update_graph_pen() { m_penController->setItem(graph_item()->penItem()); } - - //! Update visible - void update_visible() - { - m_graph->setVisible(graph_item()->property<bool>(GraphItem::P_DISPLAYED)); - m_customPlot->replot(); - } - - void reset_graph() - { - m_dataController->setItem(nullptr); - m_penController->setItem(nullptr); - m_customPlot->removePlottable(m_graph); - m_graph = nullptr; - m_customPlot->replot(); - } -}; - -GraphPlotController::GraphPlotController(QCustomPlot* custom_plot) - : p_impl(std::make_unique<GraphItemControllerImpl>(this, custom_plot)) -{ -} - -void GraphPlotController::subscribe() -{ - auto on_property_change = [this](SessionItem*, const std::string& property_name) { - if (property_name == GraphItem::P_LINK) - p_impl->update_data_controller(); - - if (property_name == GraphItem::P_DISPLAYED) - p_impl->update_visible(); - }; - setOnPropertyChange(on_property_change); - - p_impl->init_graph(); -} - -void GraphPlotController::unsubscribe() -{ - p_impl->reset_graph(); -} - -GraphPlotController::~GraphPlotController() = default; diff --git a/mvvm/view/mvvm/plotting/graphplotcontroller.h b/mvvm/view/mvvm/plotting/graphplotcontroller.h deleted file mode 100644 index 6c76c1466d10be0c1197ba6408039f11e4b823c7..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/plotting/graphplotcontroller.h +++ /dev/null @@ -1,49 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/plotting/graphplotcontroller.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_GRAPHPLOTCONTROLLER_H -#define BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_GRAPHPLOTCONTROLLER_H - -#include "mvvm/signals/itemlistener.h" -#include "mvvm/view_export.h" -#include <memory> - -class QCustomPlot; - -namespace ModelView { - -class GraphItem; - -//! Establish communication between QCPGraph and GraphItem. -//! Provides update on QCPGraph (data points, line style, color, etc) when GraphItem is changed. -//! QCPGraph is added to QCustomPlot plottables, when controller is created, and removed from -//! plottables when controller is destroyed. - -class MVVM_VIEW_EXPORT GraphPlotController : public ItemListener<GraphItem> { -public: - explicit GraphPlotController(QCustomPlot* plot); - ~GraphPlotController() override; - -protected: - void subscribe() override; - void unsubscribe() override; - -private: - struct GraphItemControllerImpl; - std::unique_ptr<GraphItemControllerImpl> p_impl; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_GRAPHPLOTCONTROLLER_H diff --git a/mvvm/view/mvvm/plotting/graphviewportplotcontroller.cpp b/mvvm/view/mvvm/plotting/graphviewportplotcontroller.cpp deleted file mode 100644 index df80cdb7db0a6cbe9860ae333ca10614cd8b13c6..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/plotting/graphviewportplotcontroller.cpp +++ /dev/null @@ -1,123 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/plotting/graphviewportplotcontroller.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/plotting/graphviewportplotcontroller.h" -#include "mvvm/plotting/graphplotcontroller.h" -#include "mvvm/plotting/viewportaxisplotcontroller.h" -#include "mvvm/standarditems/axisitems.h" -#include "mvvm/standarditems/graphitem.h" -#include "mvvm/standarditems/graphviewportitem.h" -#include <list> -#include <qcustomplot.h> -#include <stdexcept> - -using namespace ModelView; - -struct GraphViewportPlotController::GraphViewportPlotControllerImpl { - GraphViewportPlotController* master{nullptr}; - QCustomPlot* custom_plot{nullptr}; - std::list<std::unique_ptr<GraphPlotController>> graph_controllers; - std::unique_ptr<ViewportAxisPlotController> xAxisController; - std::unique_ptr<ViewportAxisPlotController> yAxisController; - - GraphViewportPlotControllerImpl(GraphViewportPlotController* master, QCustomPlot* plot) - : master(master), custom_plot(plot) - { - } - - GraphViewportItem* viewport_item() { return master->currentItem(); } - - //! Setup controller components. - void setup_components() - { - create_axis_controllers(); - create_graph_controllers(); - } - - //! Creates axes controllers. - - void create_axis_controllers() - { - auto viewport = viewport_item(); - - xAxisController = std::make_unique<ViewportAxisPlotController>(custom_plot->xAxis); - xAxisController->setItem(viewport->xAxis()); - - yAxisController = std::make_unique<ViewportAxisPlotController>(custom_plot->yAxis); - yAxisController->setItem(viewport->yAxis()); - } - - //! Run through all GraphItem's and create graph controllers for QCustomPlot. - - void create_graph_controllers() - { - graph_controllers.clear(); - auto viewport = viewport_item(); - for (auto graph_item : viewport->graphItems()) { - auto controller = std::make_unique<GraphPlotController>(custom_plot); - controller->setItem(graph_item); - graph_controllers.push_back(std::move(controller)); - } - viewport->setViewportToContent(); - } - - //! Adds controller for item. - void add_controller_for_item(SessionItem* parent, const TagRow& tagrow) - { - auto added_child = dynamic_cast<GraphItem*>(parent->getItem(tagrow.tag, tagrow.row)); - - for (auto& controller : graph_controllers) - if (controller->currentItem() == added_child) - throw std::runtime_error("Attempt to create second controller"); - - auto controller = std::make_unique<GraphPlotController>(custom_plot); - controller->setItem(added_child); - graph_controllers.push_back(std::move(controller)); - custom_plot->replot(); - } - - //! Remove GraphPlotController corresponding to GraphItem. - - void remove_controller_for_item(SessionItem* parent, const TagRow& tagrow) - { - auto child_about_to_be_removed = parent->getItem(tagrow.tag, tagrow.row); - auto if_func = [&](const std::unique_ptr<GraphPlotController>& cntrl) -> bool { - return cntrl->currentItem() == child_about_to_be_removed; - }; - graph_controllers.remove_if(if_func); - custom_plot->replot(); - } -}; - -GraphViewportPlotController::GraphViewportPlotController(QCustomPlot* custom_plot) - : p_impl(std::make_unique<GraphViewportPlotControllerImpl>(this, custom_plot)) -{ -} - -void GraphViewportPlotController::subscribe() -{ - auto on_item_inserted = [this](SessionItem* parent, TagRow tagrow) { - p_impl->add_controller_for_item(parent, tagrow); - }; - setOnItemInserted(on_item_inserted); - - auto on_about_to_remove_item = [this](SessionItem* parent, TagRow tagrow) { - p_impl->remove_controller_for_item(parent, tagrow); - }; - setOnAboutToRemoveItem(on_about_to_remove_item); - - p_impl->setup_components(); -} - -GraphViewportPlotController::~GraphViewportPlotController() = default; diff --git a/mvvm/view/mvvm/plotting/graphviewportplotcontroller.h b/mvvm/view/mvvm/plotting/graphviewportplotcontroller.h deleted file mode 100644 index 681154843b2cfb20842e5c36f74399ca74a9b8a2..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/plotting/graphviewportplotcontroller.h +++ /dev/null @@ -1,46 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/plotting/graphviewportplotcontroller.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_GRAPHVIEWPORTPLOTCONTROLLER_H -#define BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_GRAPHVIEWPORTPLOTCONTROLLER_H - -#include "mvvm/signals/itemlistener.h" -#include "mvvm/view_export.h" -#include <memory> - -class QCustomPlot; - -namespace ModelView { - -class GraphViewportItem; - -//! Establishes communications and mutual updates for GraphViewportItem and QCutomPlot. -//! Populates custom plot with all graphs found in GraphViewportItem. - -class MVVM_VIEW_EXPORT GraphViewportPlotController : public ItemListener<GraphViewportItem> { -public: - explicit GraphViewportPlotController(QCustomPlot* plot); - ~GraphViewportPlotController() override; - -protected: - void subscribe() override; - -private: - struct GraphViewportPlotControllerImpl; - std::unique_ptr<GraphViewportPlotControllerImpl> p_impl; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_GRAPHVIEWPORTPLOTCONTROLLER_H diff --git a/mvvm/view/mvvm/plotting/mousemovereporter.cpp b/mvvm/view/mvvm/plotting/mousemovereporter.cpp deleted file mode 100644 index 6e7f136db3d6beb547c4a1bfdbe4d1d0b7232365..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/plotting/mousemovereporter.cpp +++ /dev/null @@ -1,66 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/plotting/mousemovereporter.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/plotting/mousemovereporter.h" -#include "mvvm/plotting/mouseposinfo.h" -#include <QMouseEvent> -#include <qcustomplot.h> -#include <stdexcept> - -using namespace ModelView; - -struct MouseMoveReporter::MouseMoveReporterImpl { - MouseMoveReporter* reporter{nullptr}; - QCustomPlot* custom_plot{nullptr}; - callback_t callback; - MouseMoveReporterImpl(MouseMoveReporter* reporter, QCustomPlot* custom_plot, - callback_t callback) - : reporter(reporter), custom_plot(custom_plot), callback(std::move(callback)) - { - if (!custom_plot) - throw std::runtime_error("MouseMoveReporter: not initialized custom plot."); - - custom_plot->setMouseTracking(true); - set_connected(); - } - - void set_connected() - { - auto on_mouse_move = [this](QMouseEvent* event) { - double x = pixelToXaxisCoord(event->pos().x()); - double y = pixelToYaxisCoord(event->pos().y()); - if (callback) - callback({x, y, axesRangeContains(x, y)}); - }; - - QObject::connect(custom_plot, &QCustomPlot::mouseMove, on_mouse_move); - } - - double pixelToXaxisCoord(double pixel) const { return custom_plot->xAxis->pixelToCoord(pixel); } - - double pixelToYaxisCoord(double pixel) const { return custom_plot->yAxis->pixelToCoord(pixel); } - - bool axesRangeContains(double xpos, double ypos) const - { - return custom_plot->xAxis->range().contains(xpos) - && custom_plot->yAxis->range().contains(ypos); - } -}; - -MouseMoveReporter::MouseMoveReporter(QCustomPlot* custom_plot, callback_t callback) - : p_impl(std::make_unique<MouseMoveReporterImpl>(this, custom_plot, callback)) -{ -} - -MouseMoveReporter::~MouseMoveReporter() = default; diff --git a/mvvm/view/mvvm/plotting/mousemovereporter.h b/mvvm/view/mvvm/plotting/mousemovereporter.h deleted file mode 100644 index 9bb180820c4d056f1beae9e12d09f8892f57090b..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/plotting/mousemovereporter.h +++ /dev/null @@ -1,45 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/plotting/mousemovereporter.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_MOUSEMOVEREPORTER_H -#define BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_MOUSEMOVEREPORTER_H - -#include "mvvm/view_export.h" -#include <functional> -#include <memory> - -class QCustomPlot; - -namespace ModelView { - -struct MousePosInfo; - -//! Tracks mouse moves in QCustomPlot canvas. -//! Notifies client about mouse moves and corresponding pointer coordinates expressed in axes units -//! at current zoom level. - -class MVVM_VIEW_EXPORT MouseMoveReporter { -public: - using callback_t = std::function<void(const MousePosInfo& pos_info)>; - MouseMoveReporter(QCustomPlot* custom_plot, callback_t callback); - ~MouseMoveReporter(); - -private: - struct MouseMoveReporterImpl; - std::unique_ptr<MouseMoveReporterImpl> p_impl; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_MOUSEMOVEREPORTER_H diff --git a/mvvm/view/mvvm/plotting/mouseposinfo.h b/mvvm/view/mvvm/plotting/mouseposinfo.h deleted file mode 100644 index 20f8ba700b643923666f843c2b49b73c92ff9077..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/plotting/mouseposinfo.h +++ /dev/null @@ -1,35 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/plotting/mouseposinfo.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_MOUSEPOSINFO_H -#define BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_MOUSEPOSINFO_H - -#include "mvvm/view_export.h" - -class QCustomPlot; - -namespace ModelView { - -//! Aggregate to hold mouse position info in QCustomPlot context. -//! Position is given in axis coordinates corresponding to the current zoom level. - -struct MVVM_VIEW_EXPORT MousePosInfo { - double xpos{0.0}; - double ypos{0.0}; - bool in_axes_range{false}; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_MOUSEPOSINFO_H diff --git a/mvvm/view/mvvm/plotting/pencontroller.cpp b/mvvm/view/mvvm/plotting/pencontroller.cpp deleted file mode 100644 index 739632538e31feee2ac10b6e9ec49ad313a4f3ff..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/plotting/pencontroller.cpp +++ /dev/null @@ -1,68 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/plotting/pencontroller.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/plotting/pencontroller.h" -#include "mvvm/model/comboproperty.h" -#include "mvvm/standarditems/plottableitems.h" -#include "qcustomplot.h" -#include <stdexcept> - -using namespace ModelView; - -namespace { -//! Returns Qt pen style from current ComboProperty index. -Qt::PenStyle getQtPenFromComboIndex(const ComboProperty& combo) -{ - // our ComboProperty for pens coincide with Qt definition - return static_cast<Qt::PenStyle>(combo.currentIndex()); -} -} // namespace - -struct PenController::PenControllerImpl { - QCPGraph* m_graph{nullptr}; - PenControllerImpl(QCPGraph* graph) : m_graph(graph) - { - if (!m_graph) - throw std::runtime_error("Error in PenController: uninitialized graph."); - } - - void update_graph_from_item(PenItem* item) - { - QColor color(QString::fromStdString(item->colorName())); - auto pencombo = item->property<ComboProperty>(PenItem::P_STYLE); - auto penwidth = item->property<int>(PenItem::P_WIDTH); - - QPen pen; - pen.setColor(color); - pen.setStyle(getQtPenFromComboIndex(pencombo)); - pen.setWidth(penwidth); - m_graph->setPen(pen); - - m_graph->parentPlot()->replot(); - } -}; - -PenController::PenController(QCPGraph* graph) : p_impl(std::make_unique<PenControllerImpl>(graph)) -{ -} - -PenController::~PenController() = default; - -void PenController::subscribe() -{ - auto on_property_change = [this](auto, auto) { p_impl->update_graph_from_item(currentItem()); }; - setOnPropertyChange(on_property_change); - - p_impl->update_graph_from_item(currentItem()); -} diff --git a/mvvm/view/mvvm/plotting/pencontroller.h b/mvvm/view/mvvm/plotting/pencontroller.h deleted file mode 100644 index 6cfbc95c928b73bfd1066d0e506dea75af2a6069..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/plotting/pencontroller.h +++ /dev/null @@ -1,46 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/plotting/pencontroller.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_PENCONTROLLER_H -#define BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_PENCONTROLLER_H - -#include "mvvm/signals/itemlistener.h" -#include "mvvm/view_export.h" -#include <memory> - -class QCPGraph; - -namespace ModelView { - -class PenItem; - -//! Establishes communication between QCPGraph and PenItem. -//! Provides update of QCPGraph's color, line style and width when PenItem is changed. - -class MVVM_VIEW_EXPORT PenController : public ItemListener<PenItem> { -public: - explicit PenController(QCPGraph* graph); - ~PenController() override; - -protected: - void subscribe() override; - -private: - struct PenControllerImpl; - std::unique_ptr<PenControllerImpl> p_impl; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_PENCONTROLLER_H diff --git a/mvvm/view/mvvm/plotting/sceneadapterinterface.h b/mvvm/view/mvvm/plotting/sceneadapterinterface.h deleted file mode 100644 index 1f51f21079c98ad605026673a84504fce1d050fd..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/plotting/sceneadapterinterface.h +++ /dev/null @@ -1,50 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/plotting/sceneadapterinterface.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_SCENEADAPTERINTERFACE_H -#define BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_SCENEADAPTERINTERFACE_H - -#include "mvvm/view_export.h" - -class QRectF; - -namespace ModelView { - -//! Interface to convert coordinates of "scene" to coordinates of "widget". -//! Used in the context of QCustomPlot being embedded into QGraphicsScene. Converts QGraphicsScene -//! coordinates in the coordinates of local system of QCustomPlot and vice versa. - -class MVVM_VIEW_EXPORT SceneAdapterInterface { -public: - virtual ~SceneAdapterInterface() = default; - - //! convert local x-coordinate to scene coordinate - virtual double toSceneX(double) const = 0; - - //! convert local y-coordinate to scene coordinate - virtual double toSceneY(double) const = 0; - - //! convert scene x-coordinate to local axis coordinate - virtual double fromSceneX(double) const = 0; - - //! convert scene y-coordinate to local axis coordinate - virtual double fromSceneY(double) const = 0; - - //! returns viewport rectangle in scene coordinates - virtual QRectF viewportRectangle() const = 0; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_SCENEADAPTERINTERFACE_H diff --git a/mvvm/view/mvvm/plotting/statusstringformatterinterface.h b/mvvm/view/mvvm/plotting/statusstringformatterinterface.h deleted file mode 100644 index b9214cb96017f2f1083391507b574cd0e638dcff..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/plotting/statusstringformatterinterface.h +++ /dev/null @@ -1,37 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/plotting/statusstringformatterinterface.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_STATUSSTRINGFORMATTERINTERFACE_H -#define BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_STATUSSTRINGFORMATTERINTERFACE_H - -#include "mvvm/view_export.h" -#include <string> - -class QCustomPlot; - -namespace ModelView { - -//! Pure virtual interface to format string with status info corresponding to the current mouse -//! position on QCustomPlot. - -class MVVM_VIEW_EXPORT StatusStringFormatterInterface { -public: - virtual ~StatusStringFormatterInterface() = default; - - virtual std::string status_string(QCustomPlot* custom_plot, double x, double y) const = 0; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_STATUSSTRINGFORMATTERINTERFACE_H diff --git a/mvvm/view/mvvm/plotting/statusstringreporter.cpp b/mvvm/view/mvvm/plotting/statusstringreporter.cpp deleted file mode 100644 index 5d00ded66a4f3316d92317850a8bc4773426c36f..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/plotting/statusstringreporter.cpp +++ /dev/null @@ -1,88 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/plotting/statusstringreporter.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/plotting/statusstringreporter.h" -#include "mvvm/plotting/mousemovereporter.h" -#include "mvvm/plotting/mouseposinfo.h" -#include "mvvm/plotting/statusstringformatterinterface.h" -#include <stdexcept> - -using namespace ModelView; - -struct StatusStringReporter::StatusStringReporterImpl { - StatusStringReporter* parent{nullptr}; - QCustomPlot* custom_plot{nullptr}; - callback_t callback; - std::unique_ptr<StatusStringFormatterInterface> fmt; - std::unique_ptr<MouseMoveReporter> mouse_reporter; - MousePosInfo prevPos; - - StatusStringReporterImpl(StatusStringReporter* parent, QCustomPlot* custom_plot, - callback_t callback, - std::unique_ptr<StatusStringFormatterInterface> formatter) - : parent(parent) - , custom_plot(custom_plot) - , callback(std::move(callback)) - , fmt(std::move(formatter)) - { - if (!custom_plot) - throw std::runtime_error("StatusStringReporter: not initialized custom plot."); - - auto on_mouse_move = [this](const MousePosInfo& pos) { - if (pos.in_axes_range) { - notify_client(pos); - if (!prevPos.in_axes_range) - entering_the_area(); - } else { - if (prevPos.in_axes_range) - leaving_the_area(); - } - - prevPos = pos; - }; - mouse_reporter = std::make_unique<MouseMoveReporter>(custom_plot, on_mouse_move); - } - - //! Notify client about mouse move with formatted status string. - - void notify_client(const MousePosInfo& pos) - { - callback(fmt->status_string(this->custom_plot, pos.xpos, pos.ypos)); - } - - //! Notify client on leaving axes area. - - void leaving_the_area() - { - // notifying client with empty string as a sign that we have left the area - callback({}); - } - - //! Notify client on entering axes area. - - void entering_the_area() - { - // for future improvements - } -}; - -StatusStringReporter::StatusStringReporter( - QCustomPlot* custom_plot, callback_t callback, - std::unique_ptr<StatusStringFormatterInterface> formatter) - : p_impl(std::make_unique<StatusStringReporterImpl>(this, custom_plot, callback, - std::move(formatter))) -{ -} - -StatusStringReporter::~StatusStringReporter() = default; diff --git a/mvvm/view/mvvm/plotting/statusstringreporter.h b/mvvm/view/mvvm/plotting/statusstringreporter.h deleted file mode 100644 index 82a204e84778e78e5f558182186962f46c97205a..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/plotting/statusstringreporter.h +++ /dev/null @@ -1,46 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/plotting/statusstringreporter.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_STATUSSTRINGREPORTER_H -#define BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_STATUSSTRINGREPORTER_H - -#include "mvvm/view_export.h" -#include <functional> -#include <memory> -#include <string> - -class QCustomPlot; - -namespace ModelView { - -class StatusStringFormatterInterface; - -//! Reports back status string composed for current mouse position in QCustomPlot. -//! Doesn't report if cursor is outside of the axes range. - -class MVVM_VIEW_EXPORT StatusStringReporter { -public: - using callback_t = std::function<void(const std::string&)>; - StatusStringReporter(QCustomPlot* custom_plot, callback_t callback, - std::unique_ptr<StatusStringFormatterInterface> formatter); - ~StatusStringReporter(); - -private: - struct StatusStringReporterImpl; - std::unique_ptr<StatusStringReporterImpl> p_impl; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_STATUSSTRINGREPORTER_H diff --git a/mvvm/view/mvvm/plotting/statusstringreporterfactory.cpp b/mvvm/view/mvvm/plotting/statusstringreporterfactory.cpp deleted file mode 100644 index 6cb0e50d598c21bbb2d9731a5be4f62ab457218f..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/plotting/statusstringreporterfactory.cpp +++ /dev/null @@ -1,36 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/plotting/statusstringreporterfactory.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/plotting/statusstringreporterfactory.h" -#include "mvvm/plotting/colormapinfoformatter.h" -#include "mvvm/plotting/graphinfoformatter.h" -#include "mvvm/plotting/statusstringreporter.h" - -namespace ModelView { - -std::unique_ptr<StatusStringReporter> -CreateGraphReporter(QCustomPlot* custom_plot, std::function<void(const std::string&)> callback) -{ - return std::make_unique<StatusStringReporter>(custom_plot, callback, - std::make_unique<GraphInfoFormatter>()); -} - -std::unique_ptr<StatusStringReporter> -CreateColorMapReporter(QCustomPlot* custom_plot, std::function<void(const std::string&)> callback) -{ - return std::make_unique<StatusStringReporter>(custom_plot, callback, - std::make_unique<ColorMapInfoFormatter>()); -} - -} // namespace ModelView diff --git a/mvvm/view/mvvm/plotting/statusstringreporterfactory.h b/mvvm/view/mvvm/plotting/statusstringreporterfactory.h deleted file mode 100644 index a63be85ccd1dc588ad9083e179f1a6fa0092f3cf..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/plotting/statusstringreporterfactory.h +++ /dev/null @@ -1,40 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/plotting/statusstringreporterfactory.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_STATUSSTRINGREPORTERFACTORY_H -#define BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_STATUSSTRINGREPORTERFACTORY_H - -//! Contains factory methods to create StatusStringReporter - -#include "mvvm/view_export.h" -#include <functional> -#include <memory> - -class QCustomPlot; - -namespace ModelView { - -class StatusStringReporter; - -//! Creates reporter for status string in QCustomPlot containing graphs. -MVVM_VIEW_EXPORT std::unique_ptr<StatusStringReporter> -CreateGraphReporter(QCustomPlot* custom_plot, std::function<void(const std::string&)> callback); - -//! Creates reporter for status string in QCustomPlot containing QCPColorMap. -MVVM_VIEW_EXPORT std::unique_ptr<StatusStringReporter> -CreateColorMapReporter(QCustomPlot* custom_plot, std::function<void(const std::string&)> callback); - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_STATUSSTRINGREPORTERFACTORY_H diff --git a/mvvm/view/mvvm/plotting/viewportaxisplotcontroller.cpp b/mvvm/view/mvvm/plotting/viewportaxisplotcontroller.cpp deleted file mode 100644 index 576c4f7810bbf5062f56c15a4cd50e86d2b272fe..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/plotting/viewportaxisplotcontroller.cpp +++ /dev/null @@ -1,137 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/plotting/viewportaxisplotcontroller.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/plotting/viewportaxisplotcontroller.h" -#include "mvvm/plotting/axistitlecontroller.h" -#include "mvvm/plotting/customplotutils.h" -#include "mvvm/standarditems/axisitems.h" -#include "mvvm/standarditems/plottableitems.h" -#include "qcustomplot.h" -#include <QObject> -#include <stdexcept> - -using namespace ModelView; - -struct ViewportAxisPlotController::AxesPlotControllerImpl { - - ViewportAxisPlotController* m_self{nullptr}; - QCPAxis* m_axis{nullptr}; - bool m_blockUpdate{false}; - std::unique_ptr<QMetaObject::Connection> m_axisConn; - std::unique_ptr<AxisTitleController> m_titleController; - - AxesPlotControllerImpl(ViewportAxisPlotController* controller, QCPAxis* axis) - : m_self(controller), m_axis(axis) - { - if (!axis) - throw std::runtime_error("AxisPlotController: axis is not initialized."); - m_axisConn = std::make_unique<QMetaObject::Connection>(); - } - - //! Connects QCustomPlot signals with controller methods. - void setConnected() - { - auto on_axis_range = [this](const QCPRange& newRange) { - m_blockUpdate = true; - auto item = m_self->currentItem(); - item->set_range(newRange.lower, newRange.upper); - m_blockUpdate = false; - }; - - *m_axisConn = QObject::connect( - m_axis, static_cast<void (QCPAxis::*)(const QCPRange&)>(&QCPAxis::rangeChanged), - on_axis_range); - } - - //! Disonnects QCustomPlot signals. - - void setDisconnected() { QObject::disconnect(*m_axisConn); } - - //! Sets axesRange from SessionItem. - void setAxisRangeFromItem() - { - auto [lower, upper] = m_self->currentItem()->range(); - m_axis->setRange(QCPRange(lower, upper)); - } - - //! Sets log scale from item. - - void setAxisLogScaleFromItem() - { - Utils::SetLogarithmicScale(m_axis, m_self->currentItem()->is_in_log()); - } - - //! Init axis from item and setup connections. - - void init_axis() - { - m_titleController = std::make_unique<AxisTitleController>(m_axis); - auto text_item = m_self->currentItem()->item<TextItem>(ViewportAxisItem::P_TITLE); - m_titleController->setItem(text_item); - setAxisRangeFromItem(); - setAxisLogScaleFromItem(); - setConnected(); - } - - void updateLowerRange(const ViewportAxisItem* item) - { - setDisconnected(); - m_axis->setRangeLower(item->property<double>(ViewportAxisItem::P_MIN)); - setConnected(); - } - - void updateUpperRange(const ViewportAxisItem* item) - { - setDisconnected(); - m_axis->setRangeUpper(item->property<double>(ViewportAxisItem::P_MAX)); - setConnected(); - } - - ~AxesPlotControllerImpl() { setDisconnected(); } -}; - -ViewportAxisPlotController::ViewportAxisPlotController(QCPAxis* axis) - : p_impl(std::make_unique<AxesPlotControllerImpl>(this, axis)) - -{ -} - -ViewportAxisPlotController::~ViewportAxisPlotController() = default; - -void ViewportAxisPlotController::subscribe() -{ - auto on_property_change = [this](SessionItem*, std::string name) { - if (p_impl->m_blockUpdate) - return; - - if (name == ViewportAxisItem::P_MIN) - p_impl->updateLowerRange(currentItem()); - - if (name == ViewportAxisItem::P_MAX) - p_impl->updateUpperRange(currentItem()); - - if (name == ViewportAxisItem::P_IS_LOG) - p_impl->setAxisLogScaleFromItem(); - - p_impl->m_axis->parentPlot()->replot(); - }; - setOnPropertyChange(on_property_change); - - p_impl->init_axis(); -} - -void ViewportAxisPlotController::unsubscribe() -{ - p_impl->setDisconnected(); -} diff --git a/mvvm/view/mvvm/plotting/viewportaxisplotcontroller.h b/mvvm/view/mvvm/plotting/viewportaxisplotcontroller.h deleted file mode 100644 index 622bc076d5302975caf8989c399fb68ddf6e6cef..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/plotting/viewportaxisplotcontroller.h +++ /dev/null @@ -1,47 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/plotting/viewportaxisplotcontroller.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_VIEWPORTAXISPLOTCONTROLLER_H -#define BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_VIEWPORTAXISPLOTCONTROLLER_H - -#include "mvvm/signals/itemlistener.h" -#include "mvvm/view_export.h" -#include <memory> - -class QCPAxis; - -namespace ModelView { - -class ViewportAxisItem; - -//! Establishes communication between QCPAxis and ViewportAxisItem. -//! Provide mutual update of axis parameters (min, max, title) for two axes representations. - -class MVVM_VIEW_EXPORT ViewportAxisPlotController : public ItemListener<ViewportAxisItem> { -public: - explicit ViewportAxisPlotController(QCPAxis* axis); - ~ViewportAxisPlotController() override; - -protected: - void subscribe() override; - void unsubscribe() override; - -public: - struct AxesPlotControllerImpl; - std::unique_ptr<AxesPlotControllerImpl> p_impl; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEW_MVVM_PLOTTING_VIEWPORTAXISPLOTCONTROLLER_H diff --git a/mvvm/view/mvvm/widgets/CMakeLists.txt b/mvvm/view/mvvm/widgets/CMakeLists.txt deleted file mode 100644 index 89c16a7c7b9a786a271d9ea591cb4d69de3f2f4c..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/widgets/CMakeLists.txt +++ /dev/null @@ -1,26 +0,0 @@ -target_sources(${library_name} PRIVATE - adjustingscrollarea.cpp - adjustingscrollarea.h - allitemstreeview.cpp - allitemstreeview.h - collapsiblebar.cpp - collapsiblebar.h - collapsiblelistwidget.cpp - collapsiblelistwidget.h - itemstreeview.cpp - itemstreeview.h - itemstreeviewinterface.h - layoututils.cpp - layoututils.h - propertyflatview.cpp - propertyflatview.h - propertytreeview.cpp - propertytreeview.h - standardtreeviews.h - statuslabel.cpp - statuslabel.h - topitemstreeview.cpp - topitemstreeview.h - widgetutils.cpp - widgetutils.h -) diff --git a/mvvm/view/mvvm/widgets/adjustingscrollarea.cpp b/mvvm/view/mvvm/widgets/adjustingscrollarea.cpp deleted file mode 100644 index f0b67df1ad3a3373c6cc93057ceb636b4e304f0c..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/widgets/adjustingscrollarea.cpp +++ /dev/null @@ -1,51 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/widgets/adjustingscrollarea.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/widgets/adjustingscrollarea.h" -#include <QEvent> -#include <QScrollBar> - -using namespace ModelView; - -AdjustingScrollArea::AdjustingScrollArea(QWidget* parent) : QScrollArea(parent) -{ - setObjectName("AdjustingScrollArea"); - setContentsMargins(0, 0, 0, 0); - setWidgetResizable(true); - setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - setStyleSheet("QScrollArea#AdjustingScrollArea {border: 0px; background-color:transparent;}"); -} - -void AdjustingScrollArea::setWidget(QWidget* w) -{ - QScrollArea::setWidget(w); - w->installEventFilter(this); -} - -QSize AdjustingScrollArea::sizeHint() const -{ - auto horizontal = horizontalScrollBar(); - QSize result(viewport()->width(), widget()->height() + horizontal->height() * 2); - return result; -} - -bool AdjustingScrollArea::eventFilter(QObject* obj, QEvent* ev) -{ - if (obj == widget() && ev->type() != QEvent::Resize) { - widget()->setMaximumWidth(viewport()->width()); - setMaximumHeight(height() - viewport()->height() + widget()->height()); - } - - return QScrollArea::eventFilter(obj, ev); -} diff --git a/mvvm/view/mvvm/widgets/adjustingscrollarea.h b/mvvm/view/mvvm/widgets/adjustingscrollarea.h deleted file mode 100644 index 6d6f11c3b0012f455c49553b4110809e164a17e1..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/widgets/adjustingscrollarea.h +++ /dev/null @@ -1,41 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/widgets/adjustingscrollarea.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEW_MVVM_WIDGETS_ADJUSTINGSCROLLAREA_H -#define BORNAGAIN_MVVM_VIEW_MVVM_WIDGETS_ADJUSTINGSCROLLAREA_H - -#include "mvvm/view_export.h" -#include <QScrollArea> - -namespace ModelView { - -//! Modification of standard scroll area, which makes widget with dynamic layout occupy the whole -//! available space. - -class MVVM_VIEW_EXPORT AdjustingScrollArea : public QScrollArea { - Q_OBJECT - -public: - AdjustingScrollArea(QWidget* parent = 0); - void setWidget(QWidget* w); - - QSize sizeHint() const; - -private: - bool eventFilter(QObject* obj, QEvent* ev); -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEW_MVVM_WIDGETS_ADJUSTINGSCROLLAREA_H diff --git a/mvvm/view/mvvm/widgets/allitemstreeview.cpp b/mvvm/view/mvvm/widgets/allitemstreeview.cpp deleted file mode 100644 index b8b09ff3842a65d15294bc3c3e0ba4cad0ebeabe..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/widgets/allitemstreeview.cpp +++ /dev/null @@ -1,27 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/widgets/allitemstreeview.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/widgets/allitemstreeview.h" -#include "mvvm/factories/viewmodelfactory.h" -#include "mvvm/viewmodel/viewmodel.h" - -namespace ModelView { -AllItemsTreeView::AllItemsTreeView(SessionModel* model, QWidget* parent) : ItemsTreeView(parent) -{ - setViewModel(Factory::CreateDefaultViewModel(model)); -} - -AllItemsTreeView::~AllItemsTreeView() = default; - -} // namespace ModelView diff --git a/mvvm/view/mvvm/widgets/allitemstreeview.h b/mvvm/view/mvvm/widgets/allitemstreeview.h deleted file mode 100644 index 80520f44fdd4c2d65da245567f15f45f1a92423c..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/widgets/allitemstreeview.h +++ /dev/null @@ -1,36 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/widgets/allitemstreeview.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEW_MVVM_WIDGETS_ALLITEMSTREEVIEW_H -#define BORNAGAIN_MVVM_VIEW_MVVM_WIDGETS_ALLITEMSTREEVIEW_H - -#include "mvvm/widgets/itemstreeview.h" - -namespace ModelView { - -class SessionModel; - -//! Widget holding standard QTreeView and intended for displaying all items of SessionModel. - -class MVVM_VIEW_EXPORT AllItemsTreeView : public ItemsTreeView { - Q_OBJECT - -public: - AllItemsTreeView(SessionModel* model, QWidget* parent = nullptr); - ~AllItemsTreeView() override; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEW_MVVM_WIDGETS_ALLITEMSTREEVIEW_H diff --git a/mvvm/view/mvvm/widgets/collapsiblebar.cpp b/mvvm/view/mvvm/widgets/collapsiblebar.cpp deleted file mode 100644 index a90ecf979edc9661d1049e863d2173ac3005dc09..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/widgets/collapsiblebar.cpp +++ /dev/null @@ -1,76 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/widgets/collapsiblebar.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/widgets/collapsiblebar.h" -#include "mvvm/widgets/widgetutils.h" -#include <QEvent> -#include <QHBoxLayout> -#include <QIcon> -#include <QLabel> -#include <QMouseEvent> - -using namespace ModelView; - -CollapsibleBar::CollapsibleBar(QWidget* parent) - : QFrame(parent), m_pixmapLabel(new QLabel), m_titleLabel(new QLabel) -{ - m_pixmapLabel->setPixmap(QPixmap(":/icons/chevron-down.svg")); - - auto layout = new QHBoxLayout(this); - layout->setContentsMargins(0, 4, 0, 0); - - layout->addWidget(m_pixmapLabel, Qt::AlignLeft); - layout->addWidget(m_titleLabel, Qt::AlignCenter); - - setFixedHeight(ModelView::Utils::HeightOfLetterM() * 2); - setFrameStyle(QFrame::StyledPanel | QFrame::Raised); -} - -void CollapsibleBar::setWidget(QWidget* widget, const QString& title) -{ - m_controlledWidget = widget; - m_titleLabel->setText(title); - widget->installEventFilter(this); - updatePixmap(); -} - -void CollapsibleBar::mousePressEvent(QMouseEvent* event) -{ - if (event->button() == Qt::LeftButton) - m_controlledWidget->setHidden(m_controlledWidget->isVisible()); - updatePixmap(); -} - -//! Listens for widget signals and update collapse/expand icon on visibility change. - -bool CollapsibleBar::eventFilter(QObject* obj, QEvent* event) -{ - bool is_event_of_interest = (event->type() == QEvent::Show || event->type() == QEvent::Hide); - if (obj == m_controlledWidget && is_event_of_interest) - updatePixmap(); - return QObject::eventFilter(obj, event); -} - -//! Set pixmap depending from the visibility of the widget. - -void CollapsibleBar::updatePixmap() -{ - if (m_controlledWidget->isVisible()) { - m_pixmapLabel->setPixmap(QPixmap(":/icons/chevron-down.svg")); - setFrameStyle(QFrame::StyledPanel); - } else { - m_pixmapLabel->setPixmap(QPixmap(":/icons/chevron-right.svg")); - setFrameStyle(QFrame::StyledPanel | QFrame::Raised); - } -} diff --git a/mvvm/view/mvvm/widgets/collapsiblebar.h b/mvvm/view/mvvm/widgets/collapsiblebar.h deleted file mode 100644 index 0c04f97bba3608b6682ad381048e2018928d65cb..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/widgets/collapsiblebar.h +++ /dev/null @@ -1,51 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/widgets/collapsiblebar.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEW_MVVM_WIDGETS_COLLAPSIBLEBAR_H -#define BORNAGAIN_MVVM_VIEW_MVVM_WIDGETS_COLLAPSIBLEBAR_H - -#include "mvvm/view_export.h" -#include <QFrame> - -class QLabel; -class QString; - -namespace ModelView { - -//! Horizontal collapsible bar, part of CollapsibleListWidget. -//! Intended for placement into the QSplitter, makes client widget visible/invisible on clicks. - -class MVVM_VIEW_EXPORT CollapsibleBar : public QFrame { - Q_OBJECT - -public: - CollapsibleBar(QWidget* parent = nullptr); - - void setWidget(QWidget* widget, const QString& title); - -protected: - void mousePressEvent(QMouseEvent* event) override; - -private: - bool eventFilter(QObject* obj, QEvent* event) override; - void updatePixmap(); - - QWidget* m_controlledWidget{nullptr}; - QLabel* m_pixmapLabel{nullptr}; - QLabel* m_titleLabel{nullptr}; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEW_MVVM_WIDGETS_COLLAPSIBLEBAR_H diff --git a/mvvm/view/mvvm/widgets/collapsiblelistwidget.cpp b/mvvm/view/mvvm/widgets/collapsiblelistwidget.cpp deleted file mode 100644 index 06d615beb318086c5823abd3b53fddb1682911c7..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/widgets/collapsiblelistwidget.cpp +++ /dev/null @@ -1,47 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/widgets/collapsiblelistwidget.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/widgets/collapsiblelistwidget.h" -#include "mvvm/widgets/collapsiblebar.h" -#include <QSplitter> -#include <QVBoxLayout> - -using namespace ModelView; - -CollapsibleListWidget::CollapsibleListWidget(QWidget* parent) - : QWidget(parent), m_splitter(new QSplitter) -{ - m_splitter->setOrientation(Qt::Vertical); - - auto layout = new QVBoxLayout(this); - layout->setContentsMargins(0, 0, 0, 0); - layout->addWidget(m_splitter); -} - -void CollapsibleListWidget::addWidget(QWidget* widget, const QString& title, bool collapsed) -{ - // add bar which will be uncollapsible and will control the appearance of our widget - auto bar = new CollapsibleBar(m_splitter); - m_splitter->addWidget(bar); - - // add widget itself - m_splitter->addWidget(widget); - - // setup bar for widget - bar->setWidget(widget, title); - m_splitter->setCollapsible(m_splitter->indexOf(bar), false); - - if (collapsed) - widget->setVisible(false); -} diff --git a/mvvm/view/mvvm/widgets/collapsiblelistwidget.h b/mvvm/view/mvvm/widgets/collapsiblelistwidget.h deleted file mode 100644 index 34482f26f87e325c1df447efee67b7392fefb053..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/widgets/collapsiblelistwidget.h +++ /dev/null @@ -1,44 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/widgets/collapsiblelistwidget.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEW_MVVM_WIDGETS_COLLAPSIBLELISTWIDGET_H -#define BORNAGAIN_MVVM_VIEW_MVVM_WIDGETS_COLLAPSIBLELISTWIDGET_H - -#include "mvvm/view_export.h" -#include <QWidget> - -class QSplitter; -class QString; - -namespace ModelView { - -//! Vertical widget with column of panels displayed one under another. -//! Each panel contains user widget and can be collapsed/expanded. When expanded, -//! the place occupied by the panel can be changed by draging a splitter. - -class MVVM_VIEW_EXPORT CollapsibleListWidget : public QWidget { - Q_OBJECT - -public: - CollapsibleListWidget(QWidget* parent = nullptr); - - void addWidget(QWidget* widget, const QString& title, bool collapsed = false); - -private: - QSplitter* m_splitter{nullptr}; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEW_MVVM_WIDGETS_COLLAPSIBLELISTWIDGET_H diff --git a/mvvm/view/mvvm/widgets/itemstreeview.cpp b/mvvm/view/mvvm/widgets/itemstreeview.cpp deleted file mode 100644 index 43be9b2f8262644385284ed2e2e71340e9d8de75..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/widgets/itemstreeview.cpp +++ /dev/null @@ -1,113 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/widgets/itemstreeview.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/widgets/itemstreeview.h" -#include "mvvm/viewmodel/viewmodel.h" -#include "mvvm/viewmodel/viewmodeldelegate.h" -#include <QTreeView> -#include <QVBoxLayout> - -using namespace ModelView; - -ItemsTreeView::ItemsTreeView(QWidget* parent) - : QWidget(parent) - , m_treeView(new QTreeView) - , m_delegate(std::make_unique<ViewModelDelegate>()) - , m_block_selection(false) -{ - auto layout = new QVBoxLayout; - layout->setMargin(0); - layout->setSpacing(0); - layout->addWidget(m_treeView); - setLayout(layout); -} - -ItemsTreeView::~ItemsTreeView() = default; - -void ItemsTreeView::setViewModel(std::unique_ptr<ViewModel> viewModel) -{ - m_viewModel = std::move(viewModel); - m_treeView->setItemDelegate(m_delegate.get()); - m_treeView->setModel(m_viewModel.get()); - m_treeView->expandAll(); - m_treeView->resizeColumnToContents(0); - set_connected(true); -} - -void ItemsTreeView::setViewModelDelegate(std::unique_ptr<ViewModelDelegate> delegate) -{ - m_delegate = std::move(delegate); -} - -//! Make given item selected in QTreeView. - -void ItemsTreeView::setSelected(SessionItem* item) -{ - if (!m_viewModel) - return; - - auto indexes = m_viewModel->indexOfSessionItem(item); - if (!indexes.empty()) - selectionModel()->select(indexes.at(0), QItemSelectionModel::SelectCurrent); -} - -void ItemsTreeView::setRootSessionItem(SessionItem* item) -{ - m_viewModel->setRootSessionItem(item); - m_treeView->expandAll(); -} - -ViewModel* ItemsTreeView::viewModel() const -{ - return m_viewModel.get(); -} - -//! Processes selections in QTreeView. Finds SessionItem corresponding to selected indexes -//! and emit itemSelected signal. - -void ItemsTreeView::onSelectionChanged(const QItemSelection&, const QItemSelection&) -{ - if (m_block_selection) - return; - - auto indexes = m_treeView->selectionModel()->selectedIndexes(); - if (!indexes.empty()) { - auto item = m_viewModel->sessionItemFromIndex(indexes.at(0)); - m_block_selection = true; - itemSelected(item); - m_block_selection = false; - } -} - -void ItemsTreeView::set_connected(bool flag) -{ - Q_ASSERT(selectionModel()); - - if (flag) - connect(selectionModel(), &QItemSelectionModel::selectionChanged, this, - &ItemsTreeView::onSelectionChanged); - else - disconnect(selectionModel(), &QItemSelectionModel::selectionChanged, this, - &ItemsTreeView::onSelectionChanged); -} - -QTreeView* ItemsTreeView::treeView() -{ - return m_treeView; -} - -QItemSelectionModel* ItemsTreeView::selectionModel() -{ - return m_treeView->selectionModel(); -} diff --git a/mvvm/view/mvvm/widgets/itemstreeview.h b/mvvm/view/mvvm/widgets/itemstreeview.h deleted file mode 100644 index 4608fd9e089ff63096fc887b01b66440961711b9..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/widgets/itemstreeview.h +++ /dev/null @@ -1,73 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/widgets/itemstreeview.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEW_MVVM_WIDGETS_ITEMSTREEVIEW_H -#define BORNAGAIN_MVVM_VIEW_MVVM_WIDGETS_ITEMSTREEVIEW_H - -#include "mvvm/view_export.h" -#include <QWidget> -#include <memory> - -class QTreeView; -class QItemSelection; -class QItemSelectionModel; - -namespace ModelView { - -class SessionItem; -class ViewModel; -class ViewModelDelegate; - -//! Tree view to show items of SessionModel via ViewModel mechanism. -//! Provides notification mechanism for SessionItem selections, use custom delegate. - -class MVVM_VIEW_EXPORT ItemsTreeView : public QWidget { - Q_OBJECT - -public: - explicit ItemsTreeView(QWidget* parent = nullptr); - ~ItemsTreeView() override; - - QTreeView* treeView(); - - void setViewModel(std::unique_ptr<ViewModel> viewModel); - - void setViewModelDelegate(std::unique_ptr<ViewModelDelegate> delegate); - - void setSelected(SessionItem* item); - - void setRootSessionItem(SessionItem* item); - - ViewModel* viewModel() const; - -signals: - void itemSelected(ModelView::SessionItem*); - -private slots: - void onSelectionChanged(const QItemSelection&, const QItemSelection&); - -private: - QItemSelectionModel* selectionModel(); - - void set_connected(bool flag); - - QTreeView* m_treeView{nullptr}; - std::unique_ptr<ViewModel> m_viewModel; - std::unique_ptr<ViewModelDelegate> m_delegate; - bool m_block_selection; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEW_MVVM_WIDGETS_ITEMSTREEVIEW_H diff --git a/mvvm/view/mvvm/widgets/itemstreeviewinterface.h b/mvvm/view/mvvm/widgets/itemstreeviewinterface.h deleted file mode 100644 index ce455c9ac8cbf09e941d674eb36af77cd0d77c56..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/widgets/itemstreeviewinterface.h +++ /dev/null @@ -1,40 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/widgets/itemstreeviewinterface.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEW_MVVM_WIDGETS_ITEMSTREEVIEWINTERFACE_H -#define BORNAGAIN_MVVM_VIEW_MVVM_WIDGETS_ITEMSTREEVIEWINTERFACE_H - -#include "mvvm/view_export.h" -#include <QWidget> - -class QTreeView; - -namespace ModelView { - -class SessionModel; - -//! Saves and restores list of SessionModel's to/from disk using json format. - -class MVVM_VIEW_EXPORT ItemsTreeViewInterface : public QWidget { - Q_OBJECT - -public: - virtual void setSessionModel(SessionModel* model) = 0; - - virtual QTreeView* treeView() const = 0; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEW_MVVM_WIDGETS_ITEMSTREEVIEWINTERFACE_H diff --git a/mvvm/view/mvvm/widgets/layoututils.cpp b/mvvm/view/mvvm/widgets/layoututils.cpp deleted file mode 100644 index ce56020ec35f623c2e44600e0069e47d8d4def3e..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/widgets/layoututils.cpp +++ /dev/null @@ -1,125 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/widgets/layoututils.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/widgets/layoututils.h" -#include <QBoxLayout> -#include <QGridLayout> -#include <QLayoutItem> -#include <QWidget> - -namespace { -void remove(QGridLayout* layout, int row, int column, bool deleteWidgets); -void deleteChildWidgets(QLayoutItem* item); -} // namespace - -void GUI::Utils::Layout::clearLayout(QLayout* layout, bool deleteWidgets) -{ - if (!layout) - return; - - while (QLayoutItem* item = layout->takeAt(0)) { - if (deleteWidgets) - delete item->widget(); - if (QLayout* childLayout = item->layout()) - GUI::Utils::Layout::clearLayout(childLayout, deleteWidgets); - delete item; - } -} - -/** - * Removes all layout items on the given row from the given grid - * layout. If deleteWidgets is true, all concerned child widgets - * become not only removed from the layout, but also deleted. Note that - * this function doesn't actually remove the row itself from the grid - * layout, as this isn't possible (i.e. the rowCount() and row indices - * will stay the same after this function has been called). - */ - -void GUI::Utils::Layout::removeRow(QGridLayout* layout, int row, bool deleteWidgets) -{ - remove(layout, row, -1, deleteWidgets); - layout->setRowMinimumHeight(row, 0); - layout->setRowStretch(row, 0); -} - -/** - * Removes all layout items on the given column from the given grid - * layout. If deleteWidgets is true, all concerned child widgets - * become not only removed from the layout, but also deleted. Note that - * this function doesn't actually remove the column itself from the grid - * layout, as this isn't possible (i.e. the columnCount() and column - * indices will stay the same after this function has been called). - */ - -void GUI::Utils::Layout::removeColumn(QGridLayout* layout, int column, bool deleteWidgets) -{ - remove(layout, -1, column, deleteWidgets); - layout->setColumnMinimumWidth(column, 0); - layout->setColumnStretch(column, 0); -} - -void GUI::Utils::Layout::clearGridLayout(QGridLayout* layout, bool deleteWidgets) -{ - for (int i_row = 0; i_row < layout->rowCount(); ++i_row) { - GUI::Utils::Layout::removeRow(layout, i_row, deleteWidgets); - } -} - -namespace { - -/** - * Helper function. Removes all layout items within the given layout - * which either span the given row or column. If deleteWidgets - * is true, all concerned child widgets become not only removed from the - * layout, but also deleted. - */ - -void remove(QGridLayout* layout, int row, int column, bool deleteWidgets) -{ - // We avoid usage of QGridLayout::itemAtPosition() here to improve performance. - for (int i = layout->count() - 1; i >= 0; i--) { - int r, c, rs, cs; - layout->getItemPosition(i, &r, &c, &rs, &cs); - if ((r <= row && r + rs - 1 >= row) || (c <= column && c + cs - 1 >= column)) { - // This layout item is subject to deletion. - QLayoutItem* item = layout->takeAt(i); - if (deleteWidgets) - deleteChildWidgets(item); - delete item; - } - } -} - -/** - * Helper function. Deletes all child widgets of the given layout item. - */ - -void deleteChildWidgets(QLayoutItem* item) -{ - if (item->layout()) { - // Process all child items recursively. - for (int i = 0; i < item->layout()->count(); i++) - deleteChildWidgets(item->layout()->itemAt(i)); - } - item->widget()->deleteLater(); -} - -} // namespace - -QWidget* GUI::Utils::Layout::placeHolder() -{ - auto result = new QWidget; - result->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - return result; -} diff --git a/mvvm/view/mvvm/widgets/layoututils.h b/mvvm/view/mvvm/widgets/layoututils.h deleted file mode 100644 index 07de55c378108f6b3110d9103e6c2294dfbc9613..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/widgets/layoututils.h +++ /dev/null @@ -1,48 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/widgets/layoututils.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEW_MVVM_WIDGETS_LAYOUTUTILS_H -#define BORNAGAIN_MVVM_VIEW_MVVM_WIDGETS_LAYOUTUTILS_H - -#include "mvvm/view_export.h" - -class QLayout; -class QGridLayout; -class QWidget; - -//! @namespace LayoutUtils -//! @brief Utility functions to add/remove widgets to the layout on the fly. -//! Taken from https://stackoverflow.com/questions/5395266/removing-widgets-from-qgridlayout -//! Caveat: according to explanations given, grid layouts can only grow and never shrink. - -namespace GUI::Utils::Layout { - -//! Removes content from box layout. -MVVM_VIEW_EXPORT void clearLayout(QLayout* layout, bool deleteWidgets = true); - -//! Removes row from grid layout (important: doesn't change row count). -MVVM_VIEW_EXPORT void removeRow(QGridLayout* layout, int row, bool deleteWidgets = true); - -//! Removes column from grid layout. -MVVM_VIEW_EXPORT void removeColumn(QGridLayout* layout, int column, bool deleteWidgets = true); - -//! Clear layout completely. -MVVM_VIEW_EXPORT void clearGridLayout(QGridLayout* layout, bool deleteWidgets = true); - -//! Returns empty widget to occupy place in layout. -MVVM_VIEW_EXPORT QWidget* placeHolder(); - -} // namespace GUI::Utils::Layout - -#endif // BORNAGAIN_MVVM_VIEW_MVVM_WIDGETS_LAYOUTUTILS_H diff --git a/mvvm/view/mvvm/widgets/propertyflatview.cpp b/mvvm/view/mvvm/widgets/propertyflatview.cpp deleted file mode 100644 index ea5b427db6a51a11f7ca127ff3d4e9b7aae14a55..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/widgets/propertyflatview.cpp +++ /dev/null @@ -1,164 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/widgets/propertyflatview.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/widgets/propertyflatview.h" -#include "mvvm/editors/customeditor.h" -#include "mvvm/editors/defaulteditorfactory.h" -#include "mvvm/factories/viewmodelfactory.h" -#include "mvvm/model/groupitem.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/viewmodel/standardviewitems.h" -#include "mvvm/viewmodel/viewmodel.h" -#include "mvvm/viewmodel/viewmodeldelegate.h" -#include "mvvm/widgets/layoututils.h" -#include <QDataWidgetMapper> -#include <QDebug> -#include <QGridLayout> -#include <QLabel> - -using namespace ModelView; - -struct PropertyFlatView::PropertyFlatViewImpl { - std::unique_ptr<ViewModel> view_model; - std::unique_ptr<ViewModelDelegate> m_delegate; - std::unique_ptr<DefaultEditorFactory> editor_factory; - std::vector<std::unique_ptr<QDataWidgetMapper>> widget_mappers; - std::map<ViewItem*, QWidget*> item_to_widget; - - QGridLayout* grid_layout{nullptr}; - PropertyFlatViewImpl() - : m_delegate(std::make_unique<ViewModelDelegate>()) - , editor_factory(std::make_unique<DefaultEditorFactory>()) - , grid_layout(new QGridLayout) - { - } - - //! Creates label for given index. - - std::unique_ptr<QLabel> create_label(ViewItem* view_item) - { - auto result = std::make_unique<QLabel>(view_item->data(Qt::DisplayRole).toString()); - result->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed)); - result->setEnabled(view_item->item()->isEnabled()); - return result; - } - - //! Creates custom editor for given index. - - std::unique_ptr<CustomEditor> create_editor(const QModelIndex& index) - { - auto editor = editor_factory->createEditor(index); - m_delegate->setEditorData(editor.get(), index); - connect(editor.get(), &CustomEditor::dataChanged, m_delegate.get(), - &ViewModelDelegate::onCustomEditorDataChanged); - editor->setEnabled(view_model->sessionItemFromIndex(index)->isEnabled()); - return editor; - } - - //! Connect model. - - void connect_model() - { - auto on_data_change = [this](const QModelIndex& topLeft, const QModelIndex&, - const QVector<int>& roles) { -#if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0) - QVector<int> expected_roles = {Qt::ForegroundRole}; -#else - QVector<int> expected_roles = {Qt::TextColorRole}; -#endif - if (roles == expected_roles) { - auto view_item = view_model->viewItemFromIndex(topLeft); - auto it = item_to_widget.find(view_item); - if (it != item_to_widget.end()) - it->second->setEnabled(view_item->item()->isEnabled()); - } - }; - connect(view_model.get(), &ViewModel::dataChanged, on_data_change); - - auto on_row_inserted = [this](const QModelIndex&, int, int) { update_grid_layout(); }; - connect(view_model.get(), &ViewModel::rowsInserted, on_row_inserted); - - auto on_row_removed = [this](const QModelIndex&, int, int) { update_grid_layout(); }; - connect(view_model.get(), &ViewModel::rowsRemoved, on_row_removed); - } - - //! Creates widget for given index to appear in grid layout. - - std::unique_ptr<QWidget> create_widget(const QModelIndex& index) - { - auto view_item = view_model->viewItemFromIndex(index); - if (auto label_item = dynamic_cast<ViewLabelItem*>(view_item); label_item) - return create_label(label_item); - - return create_editor(index); - } - - //! Creates row of widget mappers. Each widget mapper will serve all editors in a column. - - void update_mappers() - { - widget_mappers.clear(); - for (int row = 0; row < view_model->rowCount(); ++row) { - auto mapper = std::make_unique<QDataWidgetMapper>(); - mapper->setModel(view_model.get()); - mapper->setItemDelegate(m_delegate.get()); - mapper->setRootIndex(QModelIndex()); - mapper->setCurrentModelIndex(view_model->index(row, 0)); - widget_mappers.emplace_back(std::move(mapper)); - } - } - - //! Updates grid layout with all editors corresponding to the model. - - void update_grid_layout() - { - GUI::Utils::Layout::clearGridLayout(grid_layout, true); - - update_mappers(); - item_to_widget.clear(); - for (int row = 0; row < view_model->rowCount(); ++row) { - for (int col = 0; col < view_model->columnCount(); ++col) { - auto index = view_model->index(row, col); - auto widget = create_widget(index); - item_to_widget[view_model->viewItemFromIndex(index)] = widget.get(); - widget_mappers[static_cast<size_t>(row)]->addMapping(widget.get(), col); - grid_layout->addWidget(widget.release(), row, col); - } - } - } -}; - -PropertyFlatView::PropertyFlatView(QWidget* parent) - : QWidget(parent), p_impl(std::make_unique<PropertyFlatViewImpl>()) -{ - auto main_layout = new QVBoxLayout; - main_layout->setMargin(0); - main_layout->setSpacing(0); - - p_impl->grid_layout->setSpacing(6); - main_layout->addLayout(p_impl->grid_layout); - main_layout->addStretch(1); - - setLayout(main_layout); -} - -PropertyFlatView::~PropertyFlatView() = default; - -void PropertyFlatView::setItem(SessionItem* item) -{ - p_impl->view_model = Factory::CreatePropertyFlatViewModel(item->model()); - p_impl->view_model->setRootSessionItem(item); - p_impl->connect_model(); - p_impl->update_grid_layout(); -} diff --git a/mvvm/view/mvvm/widgets/propertyflatview.h b/mvvm/view/mvvm/widgets/propertyflatview.h deleted file mode 100644 index 543f1e12f9c6a54a20fa12b32a1a2f9053978028..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/widgets/propertyflatview.h +++ /dev/null @@ -1,45 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/widgets/propertyflatview.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEW_MVVM_WIDGETS_PROPERTYFLATVIEW_H -#define BORNAGAIN_MVVM_VIEW_MVVM_WIDGETS_PROPERTYFLATVIEW_H - -#include "mvvm/view_export.h" -#include <QWidget> -#include <memory> - -namespace ModelView { - -class SessionItem; - -//! Widget holding grid layout with editors and intended for displaying all properties of given -//! SessionItem. - -class MVVM_VIEW_EXPORT PropertyFlatView : public QWidget { - Q_OBJECT - -public: - PropertyFlatView(QWidget* parent = nullptr); - ~PropertyFlatView(); - - void setItem(SessionItem* item); - -private: - struct PropertyFlatViewImpl; - std::unique_ptr<PropertyFlatViewImpl> p_impl; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEW_MVVM_WIDGETS_PROPERTYFLATVIEW_H diff --git a/mvvm/view/mvvm/widgets/propertytreeview.cpp b/mvvm/view/mvvm/widgets/propertytreeview.cpp deleted file mode 100644 index c29f4320e8916d554bf78adeb06ec9d4e36ecbb0..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/widgets/propertytreeview.cpp +++ /dev/null @@ -1,44 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/widgets/propertytreeview.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/widgets/propertytreeview.h" -#include "mvvm/factories/viewmodelfactory.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/viewmodel/viewmodel.h" -#include <QTreeView> - -using namespace ModelView; - -PropertyTreeView::PropertyTreeView(QWidget* parent) : ItemsTreeView(parent) -{ - treeView()->setHeaderHidden(false); - // provide one click editing - treeView()->setEditTriggers(QAbstractItemView::AllEditTriggers); - treeView()->setAlternatingRowColors(true); -} - -void PropertyTreeView::setItem(SessionItem* item) -{ - if (!item) { - treeView()->setModel(nullptr); - return; - } - - setViewModel(Factory::CreatePropertyViewModel(item->model())); - viewModel()->setRootSessionItem(item); - treeView()->setRootIsDecorated(false); - treeView()->expandAll(); -} - -PropertyTreeView::~PropertyTreeView() = default; diff --git a/mvvm/view/mvvm/widgets/propertytreeview.h b/mvvm/view/mvvm/widgets/propertytreeview.h deleted file mode 100644 index c2576d83ffcc0da6f01415818444286b1c3bcc7c..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/widgets/propertytreeview.h +++ /dev/null @@ -1,37 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/widgets/propertytreeview.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEW_MVVM_WIDGETS_PROPERTYTREEVIEW_H -#define BORNAGAIN_MVVM_VIEW_MVVM_WIDGETS_PROPERTYTREEVIEW_H - -#include "mvvm/widgets/itemstreeview.h" - -namespace ModelView { - -//! Widget holding standard QTreeView and intended for displaying all properties of given -//! SessionItem. - -class MVVM_VIEW_EXPORT PropertyTreeView : public ItemsTreeView { - Q_OBJECT - -public: - PropertyTreeView(QWidget* parent = nullptr); - ~PropertyTreeView(); - - void setItem(SessionItem* item); -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEW_MVVM_WIDGETS_PROPERTYTREEVIEW_H diff --git a/mvvm/view/mvvm/widgets/standardtreeviews.h b/mvvm/view/mvvm/widgets/standardtreeviews.h deleted file mode 100644 index 56f8736b48d9f7b1dd6382796165a411576123d6..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/widgets/standardtreeviews.h +++ /dev/null @@ -1,25 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/widgets/standardtreeviews.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEW_MVVM_WIDGETS_STANDARDTREEVIEWS_H -#define BORNAGAIN_MVVM_VIEW_MVVM_WIDGETS_STANDARDTREEVIEWS_H - -//! @file mvvm/view/mvvm/widgets/standardtreeviews.h -//! @brief Collection of includes to get all standard tree views. - -#include "mvvm/widgets/allitemstreeview.h" -#include "mvvm/widgets/propertytreeview.h" -#include "mvvm/widgets/topitemstreeview.h" - -#endif // BORNAGAIN_MVVM_VIEW_MVVM_WIDGETS_STANDARDTREEVIEWS_H diff --git a/mvvm/view/mvvm/widgets/statuslabel.cpp b/mvvm/view/mvvm/widgets/statuslabel.cpp deleted file mode 100644 index 2950429018f00151f1e81d21e1664ce73fb5495c..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/widgets/statuslabel.cpp +++ /dev/null @@ -1,70 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/widgets/statuslabel.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/widgets/statuslabel.h" -#include "mvvm/editors/styleutils.h" -#include "mvvm/widgets/widgetutils.h" -#include <QColor> -#include <QFont> -#include <QPainter> - -using namespace ModelView; - -StatusLabel::StatusLabel(QWidget* parent) - : QFrame(parent), m_font("Monospace", Style::DefaultInfoBarTextSize(), QFont::Normal, false) -{ - setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); - setFixedHeight(Style::DefaultInfoBarHeight()); -} - -void StatusLabel::setText(const QString& text) -{ - m_text = text; - update(); -} - -void StatusLabel::setFont(const QFont& font) -{ - m_font = font; - update(); -} - -void StatusLabel::setPointSize(int pointSize) -{ - m_font.setPointSize(pointSize); - update(); -} - -void StatusLabel::setAlignment(Qt::Alignment alignment) -{ - m_alignment = alignment; - update(); -} - -void StatusLabel::paintEvent(QPaintEvent* event) -{ - QFrame::paintEvent(event); - - QPainter painter(this); - painter.setBrush(QColor(Qt::black)); - painter.setPen(QColor(Qt::black)); - painter.setFont(m_font); - - QRect bbox(0, 0, geometry().width(), geometry().height()); - const int gap(Utils::WidthOfLetterM() / 2); // make it smaller - auto textRect = bbox.adjusted(gap, 0, gap, 0); - - painter.fillRect(bbox, QColor(Qt::white)); - painter.drawText(textRect, static_cast<int>(m_alignment), m_text); -} diff --git a/mvvm/view/mvvm/widgets/statuslabel.h b/mvvm/view/mvvm/widgets/statuslabel.h deleted file mode 100644 index e36d75a35b7b22ad64b4aa9192dedec961995629..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/widgets/statuslabel.h +++ /dev/null @@ -1,51 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/widgets/statuslabel.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEW_MVVM_WIDGETS_STATUSLABEL_H -#define BORNAGAIN_MVVM_VIEW_MVVM_WIDGETS_STATUSLABEL_H - -#include "mvvm/view_export.h" -#include <QFrame> - -class QPaintEvent; - -namespace ModelView { - -//! Shows a single line of text on a white background. -//! Opposite to QLabel, doesn't trigger layout resize, being happy with place it has. If text string -//! is too long for current size, it will be clipped. - -class MVVM_VIEW_EXPORT StatusLabel : public QFrame { - Q_OBJECT - -public: - explicit StatusLabel(QWidget* parent = nullptr); - - void setText(const QString& text); - void setFont(const QFont& font); - void setPointSize(int pointSize); - void setAlignment(Qt::Alignment); - -protected: - void paintEvent(QPaintEvent* event); - -private: - QString m_text; - Qt::Alignment m_alignment; - QFont m_font; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEW_MVVM_WIDGETS_STATUSLABEL_H diff --git a/mvvm/view/mvvm/widgets/topitemstreeview.cpp b/mvvm/view/mvvm/widgets/topitemstreeview.cpp deleted file mode 100644 index c3a331875041a22b1887f4b757673060242b3547..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/widgets/topitemstreeview.cpp +++ /dev/null @@ -1,27 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/widgets/topitemstreeview.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/widgets/topitemstreeview.h" -#include "mvvm/factories/viewmodelfactory.h" -#include "mvvm/viewmodel/viewmodel.h" - -namespace ModelView { -TopItemsTreeView::TopItemsTreeView(SessionModel* model, QWidget* parent) : ItemsTreeView(parent) -{ - setViewModel(Factory::CreateTopItemsViewModel(model)); -} - -TopItemsTreeView::~TopItemsTreeView() = default; - -} // namespace ModelView diff --git a/mvvm/view/mvvm/widgets/topitemstreeview.h b/mvvm/view/mvvm/widgets/topitemstreeview.h deleted file mode 100644 index 391aff252edfd2f639fb6a204417413ddfe695e6..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/widgets/topitemstreeview.h +++ /dev/null @@ -1,40 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/widgets/topitemstreeview.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEW_MVVM_WIDGETS_TOPITEMSTREEVIEW_H -#define BORNAGAIN_MVVM_VIEW_MVVM_WIDGETS_TOPITEMSTREEVIEW_H - -#include "mvvm/widgets/itemstreeview.h" - -namespace ModelView { - -class SessionModel; - -//! Widget holding standard QTreeView and intended for displaying all top level -//! items of SessionModel. - -//! All property items (i.e. "thickness", "color" etc) will be filtered out, top level items -//! (i.e. Layer, MultiLayer, ...) will be presented as simple parent/child tree. - -class MVVM_VIEW_EXPORT TopItemsTreeView : public ItemsTreeView { - Q_OBJECT - -public: - TopItemsTreeView(SessionModel* model, QWidget* parent = nullptr); - ~TopItemsTreeView(); -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEW_MVVM_WIDGETS_TOPITEMSTREEVIEW_H diff --git a/mvvm/view/mvvm/widgets/widgetutils.cpp b/mvvm/view/mvvm/widgets/widgetutils.cpp deleted file mode 100644 index d9855e1c7921e7e48cb3c46127656aa8a129d1cd..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/widgets/widgetutils.cpp +++ /dev/null @@ -1,179 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/widgets/widgetutils.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/widgets/widgetutils.h" -#include "mvvm/utils/numericutils.h" -#include <QApplication> -#include <QColor> -#include <QDir> -#include <QFontMetrics> -#include <QLabel> -#include <QMainWindow> -#include <QSize> - -namespace { - -//! Calculates size of letter `M` for current system font settings. - -QSize FindSizeOfLetterM() -{ - QFontMetrics fontMetric(QApplication::font()); - auto em = fontMetric.horizontalAdvance('M'); - auto fontAscent = fontMetric.ascent(); - return QSize(em, fontAscent); -} - -const QString untitled_name = "Untitled"; - -} // namespace - -QColor ModelView::Utils::RandomColor() -{ - auto rndm = []() -> int { return ModelView::Utils::RandInt(0, 255); }; - return QColor(rndm(), rndm(), rndm()); -} - -std::string ModelView::Utils::RandomNamedColor() -{ - return RandomColor().name().toStdString(); -} - -bool ModelView::Utils::IsWindowsHost() -{ -#if defined(Q_OS_WIN) - return true; -#else - return false; -#endif -} - -bool ModelView::Utils::IsMacHost() -{ -#if defined(Q_OS_MAC) - return true; -#else - return false; -#endif -} - -bool ModelView::Utils::IsLinuxHost() -{ -#if defined(Q_OS_LINUX) - return true; -#else - return false; -#endif -} - -QString ModelView::Utils::WithTildeHomePath(const QString& path) -{ - if (ModelView::Utils::IsWindowsHost()) - return path; - - static const QString homePath = QDir::homePath(); - - QFileInfo fi(QDir::cleanPath(path)); - QString outPath = fi.absoluteFilePath(); - if (outPath.startsWith(homePath)) - outPath = QLatin1Char('~') + outPath.mid(homePath.size()); - else - outPath = path; - return outPath; -} - -//! Project without projectDir will be "Untitled", modified project will be "*Untitled". -//! Project with projectDir in "/home/user/project1" will get title "project1". - -QString ModelView::Utils::ProjectWindowTitle(const QString& project_dir, bool is_modified) -{ - auto pos = project_dir.lastIndexOf('/'); - auto project_name = (pos == -1) ? untitled_name : project_dir.mid(pos + 1); - auto unsaved_status = is_modified ? QString("*") : QString(); - return unsaved_status + project_name; -} - -int ModelView::Utils::WidthOfLetterM() -{ - return ModelView::Utils::SizeOfLetterM().width(); -} - -int ModelView::Utils::HeightOfLetterM() -{ - return ModelView::Utils::SizeOfLetterM().height(); -} - -QSize ModelView::Utils::SizeOfLetterM() -{ - static QSize result = FindSizeOfLetterM(); - return result; -} - -int ModelView::Utils::SystemPointSize() -{ - return QApplication::font().pointSize(); -} - -QMainWindow* ModelView::Utils::FindMainWindow() -{ - for (auto widget : qApp->topLevelWidgets()) { - if (auto result = dynamic_cast<QMainWindow*>(widget); result) - return result; - } - return nullptr; -} - -QString ModelView::Utils::ClickableText(const QString& text, const QString& tag) -{ - return QString("<a href=\"%1\">%2</a>").arg(tag.isEmpty() ? text : tag, text); -} - -void ModelView::Utils::ScaleLabelFont(QLabel* label, double scale) -{ - QFont font = label->font(); - font.setPointSize(ModelView::Utils::SystemPointSize() * scale); - label->setFont(font); -} - -QStringList ModelView::Utils::toStringList(const std::vector<std::string>& vec) -{ - QStringList result; - for (const auto& x : vec) - result.push_back(QString::fromStdString(x)); - return result; -} - -std::vector<std::string> ModelView::Utils::fromStringList(const QStringList& string_list) -{ - std::vector<std::string> result; - for (const auto& x : string_list) - result.push_back(x.toStdString()); - return result; -} - -QByteArray ModelView::Utils::serialize(const QStringList& data) -{ - QByteArray byteArray; - QDataStream out(&byteArray, QIODevice::WriteOnly); - out << data; - return byteArray; -} - -QStringList ModelView::Utils::deserialize(const QByteArray& byteArray) -{ - QByteArray array = byteArray; - QStringList result; - QDataStream in(&array, QIODevice::ReadOnly); - in >> result; - return result; -} diff --git a/mvvm/view/mvvm/widgets/widgetutils.h b/mvvm/view/mvvm/widgets/widgetutils.h deleted file mode 100644 index 2570897e1ad2863416c15482f0175e457c842f85..0000000000000000000000000000000000000000 --- a/mvvm/view/mvvm/widgets/widgetutils.h +++ /dev/null @@ -1,94 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/view/mvvm/widgets/widgetutils.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEW_MVVM_WIDGETS_WIDGETUTILS_H -#define BORNAGAIN_MVVM_VIEW_MVVM_WIDGETS_WIDGETUTILS_H - -#include "mvvm/view_export.h" -#include <QString> -#include <QStringList> -#include <string> -#include <vector> - -class QColor; -class QSize; -class QMainWindow; -class QLabel; - -namespace ModelView { - -//! Collection of various widget-related utils. - -namespace Utils { - -//! Returns random color. -MVVM_VIEW_EXPORT QColor RandomColor(); - -//! Returns the name of random color. -MVVM_VIEW_EXPORT std::string RandomNamedColor(); - -//! Returns true if it is Windows. -MVVM_VIEW_EXPORT bool IsWindowsHost(); - -//! Returns true if it is Mac. -MVVM_VIEW_EXPORT bool IsMacHost(); - -//! Returns true if it is Linux. -MVVM_VIEW_EXPORT bool IsLinuxHost(); - -//! Returns a string where Linux path to the file is striped using '~/'. -MVVM_VIEW_EXPORT QString WithTildeHomePath(const QString& path); - -//! Returns a title composed from last part of project path, and `is_modified` flag. -MVVM_VIEW_EXPORT QString ProjectWindowTitle(const QString& project_dir, bool is_modified); - -//! Returns width of the letter 'M' deduced from current font metrics. -MVVM_VIEW_EXPORT int WidthOfLetterM(); - -//! Returns height of the letter 'M' deduced from current font metrics. -MVVM_VIEW_EXPORT int HeightOfLetterM(); - -//! Returns size corresponding to actual size of letter `M` basing on current font metrics. -MVVM_VIEW_EXPORT QSize SizeOfLetterM(); - -//! Returns size in points of default system font. -MVVM_VIEW_EXPORT int SystemPointSize(); - -//! Finds main window. -MVVM_VIEW_EXPORT QMainWindow* FindMainWindow(); - -//! Returns text wrapped into 'href' tag to provide clickable links in QLabel. -//! Example: <a href="tag">text</a>, if 'tag' is empty, 'text' will be used instead. -MVVM_VIEW_EXPORT QString ClickableText(const QString& text, const QString& tag = {}); - -//! Set label's font size to system font size scaled by given factor. -MVVM_VIEW_EXPORT void ScaleLabelFont(QLabel* label, double scale); - -//! Converts vector of strings to QStringList. -MVVM_VIEW_EXPORT QStringList toStringList(const std::vector<std::string>& vec); - -//! Converts vector of strings to QStringList. -MVVM_VIEW_EXPORT std::vector<std::string> fromStringList(const QStringList& string_list); - -//! Converts vector of strings to byte array. -MVVM_VIEW_EXPORT QByteArray serialize(const QStringList& data); - -//! Converts byte array to vector of strings. -MVVM_VIEW_EXPORT QStringList deserialize(const QByteArray& byteArray); - -} // namespace Utils - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEW_MVVM_WIDGETS_WIDGETUTILS_H diff --git a/mvvm/viewmodel/CMakeLists.txt b/mvvm/viewmodel/CMakeLists.txt deleted file mode 100644 index f251797068f6bd572d2b3836d32cde609a577092..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/CMakeLists.txt +++ /dev/null @@ -1,33 +0,0 @@ -# ----------------------------------------------------------------------------- -# Library: mvvm_viewmodel -# ----------------------------------------------------------------------------- -set(library_name mvvm_viewmodel) - -add_library(${library_name} SHARED "") -add_subdirectory(mvvm) -add_library(MVVM::ViewModel ALIAS ${library_name}) # alias for build-tree usage - -# -- Generate header for export -- - -set(export_filename ${MVVM_AUTOGEN_DIR}/mvvm/viewmodel_export.h) -generate_export_header(${library_name} EXPORT_FILE_NAME ${export_filename}) - -# -- Dependencies -- - -target_link_libraries(${library_name} PUBLIC mvvm_model Qt5::Widgets) -target_include_directories(${library_name} - PUBLIC - $<INSTALL_INTERFACE:include> - $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}> $<BUILD_INTERFACE:${MVVM_AUTOGEN_DIR}> - ) - -# -- Definitions -- - -target_compile_features(${library_name} PUBLIC cxx_std_17) - -# -- Installation -- - -install(TARGETS ${library_name} EXPORT mvvm-targets LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) -set_target_properties(${library_name} PROPERTIES EXPORT_NAME ViewModel SOVERSION ${MVVM_SOVERSION} VERSION ${MVVM_BUILDVERSION}) -install(DIRECTORY mvvm/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/mvvm FILES_MATCHING PATTERN "*.h") -install(FILES ${export_filename} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/mvvm) diff --git a/mvvm/viewmodel/mvvm/CMakeLists.txt b/mvvm/viewmodel/mvvm/CMakeLists.txt deleted file mode 100644 index 4de425752649f98fe7bd92a6d140dcec04929dc7..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/CMakeLists.txt +++ /dev/null @@ -1,4 +0,0 @@ -add_subdirectory(editors) -add_subdirectory(factories) -add_subdirectory(interfaces) -add_subdirectory(viewmodel) diff --git a/mvvm/viewmodel/mvvm/editors/CMakeLists.txt b/mvvm/viewmodel/mvvm/editors/CMakeLists.txt deleted file mode 100644 index 33efd3b655e4c8a2553b9fd5213a52de8c7e42e7..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/editors/CMakeLists.txt +++ /dev/null @@ -1,35 +0,0 @@ -target_sources(${library_name} PRIVATE - booleditor.cpp - booleditor.h - coloreditor.cpp - coloreditor.h - combopropertyeditor.cpp - combopropertyeditor.h - customeditor.cpp - customeditor.h - customeventfilters.cpp - customeventfilters.h - defaulteditorfactory.cpp - defaulteditorfactory.h - doubleeditor.cpp - doubleeditor.h - editor_constants.h - editorbuilders.cpp - editorbuilders.h - externalpropertycomboeditor.cpp - externalpropertycomboeditor.h - externalpropertyeditor.cpp - externalpropertyeditor.h - integereditor.cpp - integereditor.h - scientificdoubleeditor.cpp - scientificdoubleeditor.h - scientificspinbox.cpp - scientificspinbox.h - scientificspinboxeditor.cpp - scientificspinboxeditor.h - selectablecomboboxeditor.cpp - selectablecomboboxeditor.h - styleutils.cpp - styleutils.h -) diff --git a/mvvm/viewmodel/mvvm/editors/booleditor.cpp b/mvvm/viewmodel/mvvm/editors/booleditor.cpp deleted file mode 100644 index 40618f6efd18d4316625ae23f0cf9110c8a7de58..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/editors/booleditor.cpp +++ /dev/null @@ -1,62 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/editors/booleditor.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/editors/booleditor.h" -#include <QCheckBox> -#include <QHBoxLayout> -#include <stdexcept> - -namespace { -const QString true_text = "True"; -const QString false_text = "False"; -} // namespace - -using namespace ModelView; - -BoolEditor::BoolEditor(QWidget* parent) : CustomEditor(parent), m_checkBox(new QCheckBox) - -{ - setAutoFillBackground(true); - auto layout = new QHBoxLayout; - layout->setContentsMargins(4, 0, 0, 0); - layout->addWidget(m_checkBox); - setLayout(layout); - - connect(m_checkBox, &QCheckBox::toggled, this, &BoolEditor::onCheckBoxChange); - setFocusProxy(m_checkBox); - m_checkBox->setText(true_text); -} - -bool BoolEditor::is_persistent() const -{ - return true; -} - -void BoolEditor::onCheckBoxChange(bool value) -{ - if (value != m_data.value<bool>()) - setDataIntern(QVariant(value)); -} - -void BoolEditor::update_components() -{ - if (m_data.type() != QVariant::Bool) - throw std::runtime_error("BoolEditor::update_components() -> Error. Wrong variant type"); - - bool value = m_data.value<bool>(); - m_checkBox->blockSignals(true); - m_checkBox->setChecked(value); - m_checkBox->setText(value ? true_text : false_text); - m_checkBox->blockSignals(false); -} diff --git a/mvvm/viewmodel/mvvm/editors/booleditor.h b/mvvm/viewmodel/mvvm/editors/booleditor.h deleted file mode 100644 index 6adbd8bc5d06e758855e64afad02dd4be4b3cab9..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/editors/booleditor.h +++ /dev/null @@ -1,44 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/editors/booleditor.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEWMODEL_MVVM_EDITORS_BOOLEDITOR_H -#define BORNAGAIN_MVVM_VIEWMODEL_MVVM_EDITORS_BOOLEDITOR_H - -#include "mvvm/editors/customeditor.h" - -class QCheckBox; - -namespace ModelView { - -//! Custom editor for QVariant based on bool values. - -class MVVM_VIEWMODEL_EXPORT BoolEditor : public CustomEditor { - Q_OBJECT - -public: - explicit BoolEditor(QWidget* parent = nullptr); - - bool is_persistent() const override; - -private slots: - void onCheckBoxChange(bool value); - -private: - void update_components() override; - QCheckBox* m_checkBox; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEWMODEL_MVVM_EDITORS_BOOLEDITOR_H diff --git a/mvvm/viewmodel/mvvm/editors/coloreditor.cpp b/mvvm/viewmodel/mvvm/editors/coloreditor.cpp deleted file mode 100644 index 00055b736e581b37770e96bfc9128f804da9f732..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/editors/coloreditor.cpp +++ /dev/null @@ -1,74 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/editors/coloreditor.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/editors/coloreditor.h" -#include "mvvm/editors/customeventfilters.h" -#include "mvvm/editors/styleutils.h" -#include "mvvm/model/customvariants.h" -#include <QColorDialog> -#include <QHBoxLayout> -#include <QLabel> -#include <stdexcept> - -using namespace ModelView; - -ColorEditor::ColorEditor(QWidget* parent) - : CustomEditor(parent), m_pixmapLabel(new QLabel), m_focusFilter(new LostFocusFilter(this)) - -{ - setMouseTracking(true); - setAutoFillBackground(true); - - auto layout = new QHBoxLayout; - layout->setContentsMargins(4, 0, 0, 0); - - layout->addWidget(m_pixmapLabel); - // layout->addWidget(m_textLabel); // no color name, only color rectangle - layout->addStretch(1); - setFocusPolicy(Qt::StrongFocus); - setAttribute(Qt::WA_InputMethodEnabled); - - setLayout(layout); -} - -void ColorEditor::mousePressEvent(QMouseEvent*) -{ - // temporarily installing filter to prevent loss of focus caused by too insistent dialog - installEventFilter(m_focusFilter); - - auto new_color = QColorDialog::getColor(currentColor()); - - removeEventFilter(m_focusFilter); - - if (new_color.isValid()) { - setDataIntern(new_color); - update_components(); - } -} - -QColor ColorEditor::currentColor() const -{ - return m_data.value<QColor>(); -} - -void ColorEditor::update_components() -{ - if (!Utils::IsColorVariant(m_data)) - throw std::runtime_error("ColorEditor::update_components() -> Error. Wrong variant type"); - - QPixmap pixmap(Style::DefaultPixmapSize(), Style::DefaultPixmapSize()); - pixmap.fill(currentColor()); - // m_textLabel->setText(currentColor().name()); - m_pixmapLabel->setPixmap(pixmap); -} diff --git a/mvvm/viewmodel/mvvm/editors/coloreditor.h b/mvvm/viewmodel/mvvm/editors/coloreditor.h deleted file mode 100644 index b7b1419a2291673019e2158ee031034453bcc2f1..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/editors/coloreditor.h +++ /dev/null @@ -1,48 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/editors/coloreditor.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEWMODEL_MVVM_EDITORS_COLOREDITOR_H -#define BORNAGAIN_MVVM_VIEWMODEL_MVVM_EDITORS_COLOREDITOR_H - -#include "mvvm/editors/customeditor.h" - -class QLabel; - -namespace ModelView { - -class LostFocusFilter; - -//! Custom editor for QVariant based on QColor. - -class MVVM_VIEWMODEL_EXPORT ColorEditor : public CustomEditor { - Q_OBJECT - -public: - explicit ColorEditor(QWidget* parent = nullptr); - -protected: - void mousePressEvent(QMouseEvent* event) override; - -private: - QColor currentColor() const; - - void update_components() override; - QLabel* m_textLabel{nullptr}; - QLabel* m_pixmapLabel{nullptr}; - LostFocusFilter* m_focusFilter; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEWMODEL_MVVM_EDITORS_COLOREDITOR_H diff --git a/mvvm/viewmodel/mvvm/editors/combopropertyeditor.cpp b/mvvm/viewmodel/mvvm/editors/combopropertyeditor.cpp deleted file mode 100644 index 0e1b52e18288eda042d12aa20236ca6905fbf11a..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/editors/combopropertyeditor.cpp +++ /dev/null @@ -1,111 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/editors/combopropertyeditor.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/editors/combopropertyeditor.h" -#include "mvvm/model/comboproperty.h" -#include <QComboBox> -#include <QVBoxLayout> - -namespace { -QStringList toList(const std::vector<std::string>& container) -{ - QStringList result; - for (const auto& str : container) - result.push_back(QString::fromStdString(str)); - return result; -} -} // namespace - -using namespace ModelView; - -ComboPropertyEditor::ComboPropertyEditor(QWidget* parent) - : CustomEditor(parent), m_box(new QComboBox) -{ - setAutoFillBackground(true); - setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); - - auto layout = new QVBoxLayout; - layout->setMargin(0); - layout->setSpacing(0); - layout->addWidget(m_box); - setLayout(layout); - - setConnected(true); -} - -QSize ComboPropertyEditor::sizeHint() const -{ - return m_box->sizeHint(); -} - -QSize ComboPropertyEditor::minimumSizeHint() const -{ - return m_box->minimumSizeHint(); -} - -bool ComboPropertyEditor::is_persistent() const -{ - return true; -} - -void ComboPropertyEditor::onIndexChanged(int index) -{ - auto comboProperty = m_data.value<ComboProperty>(); - - if (comboProperty.currentIndex() != index) { - comboProperty.setCurrentIndex(index); - setDataIntern(QVariant::fromValue<ComboProperty>(comboProperty)); - } -} - -void ComboPropertyEditor::update_components() -{ - setConnected(false); - - m_box->clear(); - m_box->insertItems(0, toList(internLabels())); - m_box->setCurrentIndex(internIndex()); - - setConnected(true); -} - -//! Returns list of labels for QComboBox - -std::vector<std::string> ComboPropertyEditor::internLabels() -{ - if (!m_data.canConvert<ComboProperty>()) - return {}; - auto comboProperty = m_data.value<ComboProperty>(); - return comboProperty.values(); -} - -//! Returns index for QComboBox. - -int ComboPropertyEditor::internIndex() -{ - if (!m_data.canConvert<ComboProperty>()) - return 0; - auto comboProperty = m_data.value<ComboProperty>(); - return comboProperty.currentIndex(); -} - -void ComboPropertyEditor::setConnected(bool isConnected) -{ - if (isConnected) - connect(m_box, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, - &ComboPropertyEditor::onIndexChanged, Qt::UniqueConnection); - else - disconnect(m_box, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), - this, &ComboPropertyEditor::onIndexChanged); -} diff --git a/mvvm/viewmodel/mvvm/editors/combopropertyeditor.h b/mvvm/viewmodel/mvvm/editors/combopropertyeditor.h deleted file mode 100644 index fd6683069213a4d0cc8836c906771db8f0e19fbd..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/editors/combopropertyeditor.h +++ /dev/null @@ -1,50 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/editors/combopropertyeditor.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEWMODEL_MVVM_EDITORS_COMBOPROPERTYEDITOR_H -#define BORNAGAIN_MVVM_VIEWMODEL_MVVM_EDITORS_COMBOPROPERTYEDITOR_H - -#include "mvvm/editors/customeditor.h" - -class QComboBox; - -namespace ModelView { - -//! Custom editor for QVariant based on ComboProperty. - -class MVVM_VIEWMODEL_EXPORT ComboPropertyEditor : public CustomEditor { - Q_OBJECT - -public: - explicit ComboPropertyEditor(QWidget* parent = nullptr); - - QSize sizeHint() const override; - QSize minimumSizeHint() const override; - - bool is_persistent() const override; - -protected slots: - virtual void onIndexChanged(int index); - -private: - std::vector<std::string> internLabels(); - int internIndex(); - void setConnected(bool isConnected); - void update_components() override; - QComboBox* m_box; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEWMODEL_MVVM_EDITORS_COMBOPROPERTYEDITOR_H diff --git a/mvvm/viewmodel/mvvm/editors/customeditor.cpp b/mvvm/viewmodel/mvvm/editors/customeditor.cpp deleted file mode 100644 index 191c196de3553ca2ce13e766e2bc0e93321af162..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/editors/customeditor.cpp +++ /dev/null @@ -1,47 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/editors/customeditor.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/editors/customeditor.h" - -using namespace ModelView; - -CustomEditor::CustomEditor(QWidget* parent) : QWidget(parent) {} - -QVariant CustomEditor::data() const -{ - return m_data; -} - -//! Returns true if editor should remains alive after editing finished. - -bool CustomEditor::is_persistent() const -{ - return false; -} - -//! Sets the data from model to editor. - -void CustomEditor::setData(const QVariant& data) -{ - m_data = data; - update_components(); -} - -//! Saves the data as given by editor's internal components and notifies the model. - -void CustomEditor::setDataIntern(const QVariant& data) -{ - m_data = data; - dataChanged(m_data); -} diff --git a/mvvm/viewmodel/mvvm/editors/customeditor.h b/mvvm/viewmodel/mvvm/editors/customeditor.h deleted file mode 100644 index 6059ceea18298dfc276733780457a65694a17008..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/editors/customeditor.h +++ /dev/null @@ -1,53 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/editors/customeditor.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEWMODEL_MVVM_EDITORS_CUSTOMEDITOR_H -#define BORNAGAIN_MVVM_VIEWMODEL_MVVM_EDITORS_CUSTOMEDITOR_H - -#include "mvvm/core/variant.h" -#include "mvvm/viewmodel_export.h" -#include <QWidget> - -namespace ModelView { - -//! Base class for all custom variant editors. - -class MVVM_VIEWMODEL_EXPORT CustomEditor : public QWidget { - Q_OBJECT - Q_PROPERTY(QVariant value MEMBER m_data READ data WRITE setData NOTIFY dataChanged USER true) - -public: - explicit CustomEditor(QWidget* parent = nullptr); - - QVariant data() const; - - virtual bool is_persistent() const; - -public slots: - void setData(const QVariant& data); - -signals: - //! Emmits signal when data was changed in an editor. - void dataChanged(QVariant value); - -protected: - void setDataIntern(const QVariant& data); - //! Should update widget components from m_data, if necessary. - virtual void update_components() = 0; - QVariant m_data; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEWMODEL_MVVM_EDITORS_CUSTOMEDITOR_H diff --git a/mvvm/viewmodel/mvvm/editors/customeventfilters.cpp b/mvvm/viewmodel/mvvm/editors/customeventfilters.cpp deleted file mode 100644 index 883e3c857f4e8d732e773689e72d3f586e1001d9..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/editors/customeventfilters.cpp +++ /dev/null @@ -1,63 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/editors/customeventfilters.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/editors/customeventfilters.h" -#include <QAbstractSpinBox> -#include <QComboBox> -#include <QEvent> - -using namespace ModelView; - -LostFocusFilter::LostFocusFilter(QObject* parent) : QObject(parent) {} - -bool LostFocusFilter::eventFilter(QObject* obj, QEvent* event) -{ - if (event->type() == QEvent::FocusOut) - return true; - - return QObject::eventFilter(obj, event); -} - -// ---------------------------------------------------------------------------- - -WheelEventFilter::WheelEventFilter(QObject* parent) : QObject(parent) {} - -bool WheelEventFilter::eventFilter(QObject* obj, QEvent* event) -{ - if (auto spinBox = qobject_cast<QAbstractSpinBox*>(obj); spinBox) { - if (event->type() == QEvent::Wheel) { - if (spinBox->focusPolicy() == Qt::WheelFocus) { - event->accept(); - return false; - } else { - event->ignore(); - return true; - } - } else if (event->type() == QEvent::FocusIn) { - spinBox->setFocusPolicy(Qt::WheelFocus); - } else if (event->type() == QEvent::FocusOut) { - spinBox->setFocusPolicy(Qt::StrongFocus); - } - - } else if (auto comboBox = qobject_cast<QComboBox*>(obj); comboBox) { - if (event->type() == QEvent::Wheel) { - event->ignore(); - return true; - } else { - event->accept(); - return false; - } - } - return QObject::eventFilter(obj, event); -} diff --git a/mvvm/viewmodel/mvvm/editors/customeventfilters.h b/mvvm/viewmodel/mvvm/editors/customeventfilters.h deleted file mode 100644 index a7be1b10f088c44b74b0262020702e9fe41af9b8..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/editors/customeventfilters.h +++ /dev/null @@ -1,53 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/editors/customeventfilters.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEWMODEL_MVVM_EDITORS_CUSTOMEVENTFILTERS_H -#define BORNAGAIN_MVVM_VIEWMODEL_MVVM_EDITORS_CUSTOMEVENTFILTERS_H - -#include "mvvm/viewmodel_export.h" -#include <QObject> - -namespace ModelView { - -//! Event filter to prevent loss of the focus. -//! Can be used in the context of QTreeView and similar widgets to call external editor. Such an -//! editor is created by clicking on a cell of a tree and it appears as modal window on top of a -//! tree. - -class MVVM_VIEWMODEL_EXPORT LostFocusFilter : public QObject { - Q_OBJECT - -public: - LostFocusFilter(QObject* parent = nullptr); - -protected: - bool eventFilter(QObject* obj, QEvent* event) override; -}; - -//! Event filter to install on combo boxes and spin boxes to ignore wheel events during scrolling. -//! Helpful than the spin box is a child of some larger scroll area. - -class MVVM_VIEWMODEL_EXPORT WheelEventFilter : public QObject { - Q_OBJECT - -public: - WheelEventFilter(QObject* parent = nullptr); - -protected: - bool eventFilter(QObject* obj, QEvent* event); -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEWMODEL_MVVM_EDITORS_CUSTOMEVENTFILTERS_H diff --git a/mvvm/viewmodel/mvvm/editors/defaulteditorfactory.cpp b/mvvm/viewmodel/mvvm/editors/defaulteditorfactory.cpp deleted file mode 100644 index 6dcd045a9ce5e003b815fc886e40cbf475547f8b..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/editors/defaulteditorfactory.cpp +++ /dev/null @@ -1,131 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/editors/defaulteditorfactory.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/editors/defaulteditorfactory.h" -#include "mvvm/editors/customeditor.h" -#include "mvvm/editors/editor_constants.h" -#include "mvvm/model/customvariants.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/model/variant_constants.h" -#include "mvvm/viewmodel/viewmodel.h" - -using namespace ModelView; - -namespace { - -const SessionItem* itemFromIndex(const QModelIndex& index) -{ - auto model = dynamic_cast<const ViewModel*>(index.model()); - return model ? model->sessionItemFromIndex(index) : nullptr; -} - -} // namespace - -// ---------------------------------------------------------------------------- - -void AbstractEditorFactory::registerBuilder(const std::string& name, - EditorBuilders::builder_t builder) -{ - m_nameToBuilderMap[name] = std::move(builder); -} - -EditorBuilders::builder_t AbstractEditorFactory::findBuilder(const std::string& name) const -{ - auto it = m_nameToBuilderMap.find(name); - return it != m_nameToBuilderMap.end() ? it->second : EditorBuilders::builder_t(); -} - -// ---------------------------------------------------------------------------- - -RoleDependentEditorFactory::RoleDependentEditorFactory() -{ - // registering set of builders for given editor types - registerBuilder(GUI::Constants::BoolEditorType, EditorBuilders::BoolEditorBuilder()); - registerBuilder(GUI::Constants::ColorEditorType, EditorBuilders::ColorEditorBuilder()); - registerBuilder(GUI::Constants::ComboPropertyEditorType, - EditorBuilders::ComboPropertyEditorBuilder()); - registerBuilder(GUI::Constants::DoubleEditorType, EditorBuilders::DoubleEditorBuilder()); - registerBuilder(GUI::Constants::ExternalPropertyEditorType, - EditorBuilders::ExternalPropertyEditorBuilder()); - registerBuilder(GUI::Constants::IntegerEditorType, EditorBuilders::IntegerEditorBuilder()); - registerBuilder(GUI::Constants::ScientficDoubleEditorType, - EditorBuilders::ScientificDoubleEditorBuilder()); - registerBuilder(GUI::Constants::ScientficSpinBoxEditorType, - EditorBuilders::ScientificSpinBoxEditorBuilder()); - registerBuilder(GUI::Constants::SelectableComboPropertyEditorType, - EditorBuilders::SelectableComboPropertyEditorBuilder()); -} - -//! Creates cell editor basing on item role. It is expected that the index belongs to a ViewModel. - -std::unique_ptr<CustomEditor> -RoleDependentEditorFactory::createEditor(const QModelIndex& index) const -{ - auto item = itemFromIndex(index); - return item ? createItemEditor(item) : std::unique_ptr<CustomEditor>(); -} - -//! Creates cell editor basing on editor type. - -std::unique_ptr<CustomEditor> -RoleDependentEditorFactory::createItemEditor(const SessionItem* item) const -{ - auto builder = findBuilder(item->editorType()); - return builder ? builder(item) : std::unique_ptr<CustomEditor>(); -} - -// ---------------------------------------------------------------------------- - -VariantDependentEditorFactory::VariantDependentEditorFactory() -{ - // registering set of builders for given variant names - registerBuilder(GUI::Constants::bool_type_name, EditorBuilders::BoolEditorBuilder()); - registerBuilder(GUI::Constants::int_type_name, EditorBuilders::IntegerEditorBuilder()); - registerBuilder(GUI::Constants::double_type_name, - EditorBuilders::ScientificSpinBoxEditorBuilder()); - registerBuilder(GUI::Constants::qcolor_type_name, EditorBuilders::ColorEditorBuilder()); - registerBuilder(GUI::Constants::comboproperty_type_name, - EditorBuilders::ComboPropertyEditorBuilder()); - registerBuilder(GUI::Constants::extproperty_type_name, - EditorBuilders::ExternalPropertyEditorBuilder()); -} - -//! Creates cell editor basing on variant name. - -std::unique_ptr<CustomEditor> -VariantDependentEditorFactory::createEditor(const QModelIndex& index) const -{ - auto item = itemFromIndex(index); - auto value = item ? item->data<QVariant>() : index.data(Qt::EditRole); - auto builder = findBuilder(Utils::VariantName(value)); - return builder ? builder(item) : std::unique_ptr<CustomEditor>(); -} - -// ---------------------------------------------------------------------------- - -DefaultEditorFactory::DefaultEditorFactory() - : m_roleDependentFactory(std::make_unique<RoleDependentEditorFactory>()) - , m_variantDependentFactory(std::make_unique<VariantDependentEditorFactory>()) -{ -} - -//! Creates editor for given model index basing either on editorType() or specific variant name. - -std::unique_ptr<CustomEditor> DefaultEditorFactory::createEditor(const QModelIndex& index) const -{ - // trying to created an editor basing on possibly defined EDITOR role - auto editor = m_roleDependentFactory->createEditor(index); - // if we do not succeed, then creating editor from variant type - return editor ? std::move(editor) : m_variantDependentFactory->createEditor(index); -} diff --git a/mvvm/viewmodel/mvvm/editors/defaulteditorfactory.h b/mvvm/viewmodel/mvvm/editors/defaulteditorfactory.h deleted file mode 100644 index 8e1cc94f5ea5cb09c9adb7b62cddd1089bdf21a6..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/editors/defaulteditorfactory.h +++ /dev/null @@ -1,79 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/editors/defaulteditorfactory.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEWMODEL_MVVM_EDITORS_DEFAULTEDITORFACTORY_H -#define BORNAGAIN_MVVM_VIEWMODEL_MVVM_EDITORS_DEFAULTEDITORFACTORY_H - -//! @file mvvm/viewmodel/mvvm/editors/defaulteditorfactory.h -//! Defines DefaultEditorFactory and auxiliary classes for custom view model delegates. - -#include "mvvm/editors/editorbuilders.h" -#include "mvvm/interfaces/editorfactoryinterface.h" -#include <map> -#include <memory> - -namespace ModelView { - -//! Abstract editor factory for ViewModelDelegate. -//! Creates cell editors for Qt trees and tables from model index. Cell editor is -//! Qt widget intended for editing DATA role of some SessionItem. - -class MVVM_VIEWMODEL_EXPORT AbstractEditorFactory : public EditorFactoryInterface { -protected: - void registerBuilder(const std::string& name, EditorBuilders::builder_t builder); - EditorBuilders::builder_t findBuilder(const std::string& name) const; - - std::map<std::string, EditorBuilders::builder_t> m_nameToBuilderMap; -}; - -//! Editor factory for cell editors in Qt trees and tables, relies on EDITORTYPE role stored -//! on board of SessionItem. - -class MVVM_VIEWMODEL_EXPORT RoleDependentEditorFactory : public AbstractEditorFactory { -public: - RoleDependentEditorFactory(); - - std::unique_ptr<CustomEditor> createEditor(const QModelIndex& index) const override; - -protected: - std::unique_ptr<CustomEditor> createItemEditor(const SessionItem* item) const; -}; - -//! Editor factory for cell editors in Qt trees and tables, relies on variant type stored as -//! DATA role on board of SessionItem. - -class MVVM_VIEWMODEL_EXPORT VariantDependentEditorFactory : public AbstractEditorFactory { -public: - VariantDependentEditorFactory(); - - std::unique_ptr<CustomEditor> createEditor(const QModelIndex& index) const override; -}; - -//! Default editor factory for cell editors in Qt trees and tables. -//! Internaly it uses two factories - -class MVVM_VIEWMODEL_EXPORT DefaultEditorFactory : public EditorFactoryInterface { -public: - DefaultEditorFactory(); - - std::unique_ptr<CustomEditor> createEditor(const QModelIndex& index) const override; - -private: - std::unique_ptr<RoleDependentEditorFactory> m_roleDependentFactory; - std::unique_ptr<VariantDependentEditorFactory> m_variantDependentFactory; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEWMODEL_MVVM_EDITORS_DEFAULTEDITORFACTORY_H diff --git a/mvvm/viewmodel/mvvm/editors/doubleeditor.cpp b/mvvm/viewmodel/mvvm/editors/doubleeditor.cpp deleted file mode 100644 index 35289f98969fb83af29aca0ac8af2f493be72a52..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/editors/doubleeditor.cpp +++ /dev/null @@ -1,74 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/editors/doubleeditor.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/editors/doubleeditor.h" -#include "mvvm/utils/numericutils.h" -#include <QDoubleSpinBox> -#include <QVBoxLayout> -#include <stdexcept> - -using namespace ModelView; - -DoubleEditor::DoubleEditor(QWidget* parent) - : CustomEditor(parent), m_doubleEditor(new QDoubleSpinBox) -{ - setFocusPolicy(Qt::StrongFocus); - m_doubleEditor->setFocusPolicy(Qt::StrongFocus); - m_doubleEditor->setKeyboardTracking(false); - - auto layout = new QVBoxLayout; - layout->setMargin(0); - layout->setSpacing(0); - - layout->addWidget(m_doubleEditor); - - connect(m_doubleEditor, - static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), - [=] { this->onEditingFinished(); }); - - setLayout(layout); - - setFocusProxy(m_doubleEditor); -} - -void DoubleEditor::setRange(double minimum, double maximum) -{ - m_doubleEditor->setRange(minimum, maximum); -} - -void DoubleEditor::setDecimals(int decimals) -{ - m_doubleEditor->setDecimals(decimals); -} - -void DoubleEditor::setSingleStep(double value) -{ - m_doubleEditor->setSingleStep(value); -} - -void DoubleEditor::onEditingFinished() -{ - double new_value = m_doubleEditor->value(); - - if (!Utils::AreAlmostEqual(new_value, m_data.value<double>())) - setDataIntern(QVariant::fromValue(new_value)); -} - -void DoubleEditor::update_components() -{ - if (m_data.type() != QVariant::Double) - throw std::runtime_error("DoubleEditor::update_components() -> Error. Wrong variant type"); - - m_doubleEditor->setValue(m_data.value<double>()); -} diff --git a/mvvm/viewmodel/mvvm/editors/doubleeditor.h b/mvvm/viewmodel/mvvm/editors/doubleeditor.h deleted file mode 100644 index 9b6ec57dc779d99e543403c532e145111b68b084..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/editors/doubleeditor.h +++ /dev/null @@ -1,48 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/editors/doubleeditor.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEWMODEL_MVVM_EDITORS_DOUBLEEDITOR_H -#define BORNAGAIN_MVVM_VIEWMODEL_MVVM_EDITORS_DOUBLEEDITOR_H - -#include "mvvm/editors/customeditor.h" - -class QDoubleSpinBox; - -namespace ModelView { - -//! Custom editor for QVariant based on double with possibility to set limits. - -class MVVM_VIEWMODEL_EXPORT DoubleEditor : public CustomEditor { - Q_OBJECT - -public: - explicit DoubleEditor(QWidget* parent = nullptr); - - void setRange(double minimum, double maximum); - - void setDecimals(int decimals); - - void setSingleStep(double value); - -private slots: - void onEditingFinished(); - -private: - void update_components() override; - QDoubleSpinBox* m_doubleEditor; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEWMODEL_MVVM_EDITORS_DOUBLEEDITOR_H diff --git a/mvvm/viewmodel/mvvm/editors/editor_constants.h b/mvvm/viewmodel/mvvm/editors/editor_constants.h deleted file mode 100644 index 9465f4fa3b52b86d14499e58f6c4221e76824964..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/editors/editor_constants.h +++ /dev/null @@ -1,39 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/editors/editor_constants.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEWMODEL_MVVM_EDITORS_EDITOR_CONSTANTS_H -#define BORNAGAIN_MVVM_VIEWMODEL_MVVM_EDITORS_EDITOR_CONSTANTS_H - -//! @file mvvm/viewmodel/mvvm/editors/editor_constants.h -//! Collection of constants specific for cell editing. - -#include <string> - -namespace ModelView::Constants { - -const std::string BoolEditorType = "BoolEditor"; -const std::string ColorEditorType = "ColorEditor"; -const std::string ComboPropertyEditorType = "ComboPropertyEditor"; -const std::string DoubleEditorType = "DoubleEditor"; -const std::string ExternalPropertyEditorType = "ExternalPropertyEditor"; -const std::string IntegerEditorType = "IntegerEditor"; -const std::string ScientficDoubleEditorType = "ScientficDoubleEditor"; -const std::string ScientficSpinBoxEditorType = "ScientficSpinBoxEditor"; -const std::string SelectableComboPropertyEditorType = "SelectableComboPropertyEditor"; - -const int default_double_decimals = 4; //! number of digits after decimal points - -} // namespace ModelView::Constants - -#endif // BORNAGAIN_MVVM_VIEWMODEL_MVVM_EDITORS_EDITOR_CONSTANTS_H diff --git a/mvvm/viewmodel/mvvm/editors/editorbuilders.cpp b/mvvm/viewmodel/mvvm/editors/editorbuilders.cpp deleted file mode 100644 index bea9b9640ce634ad496ab137440bd5a3bac4ff21..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/editors/editorbuilders.cpp +++ /dev/null @@ -1,141 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/editors/editorbuilders.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/editors/editorbuilders.h" -#include "mvvm/editors/booleditor.h" -#include "mvvm/editors/coloreditor.h" -#include "mvvm/editors/combopropertyeditor.h" -#include "mvvm/editors/doubleeditor.h" -#include "mvvm/editors/editor_constants.h" -#include "mvvm/editors/externalpropertyeditor.h" -#include "mvvm/editors/integereditor.h" -#include "mvvm/editors/scientificdoubleeditor.h" -#include "mvvm/editors/scientificspinboxeditor.h" -#include "mvvm/editors/selectablecomboboxeditor.h" -#include "mvvm/model/customvariants.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/utils/reallimits.h" -#include <cmath> - -namespace { -double singleStep(int decimals) -{ - // For item with decimals=3 (i.e. 0.001) single step will be 0.1 - return 1. / std::pow(10., decimals - 1); -} - -double getStep(double val) -{ - return val == 0.0 ? 1.0 : val / 100.; -} - -} // namespace - -namespace ModelView ::EditorBuilders { - -builder_t BoolEditorBuilder() -{ - auto builder = [](const SessionItem*) -> editor_t { return std::make_unique<BoolEditor>(); }; - return builder; -} - -builder_t IntegerEditorBuilder() -{ - auto builder = [](const SessionItem* item) -> editor_t { - auto editor = std::make_unique<IntegerEditor>(); - if (item && item->hasData(ItemDataRole::LIMITS)) { - auto limits = item->data<RealLimits>(ItemDataRole::LIMITS); - editor->setRange(limits.lowerLimit(), limits.upperLimit()); - } - return editor; - }; - return builder; -} - -builder_t DoubleEditorBuilder() -{ - auto builder = [](const SessionItem* item) -> editor_t { - auto editor = std::make_unique<DoubleEditor>(); - if (item && item->hasData(ItemDataRole::LIMITS)) { - auto limits = item->data<RealLimits>(ItemDataRole::LIMITS); - editor->setRange(limits.lowerLimit(), limits.upperLimit()); - editor->setSingleStep(singleStep(GUI::Constants::default_double_decimals)); - editor->setDecimals(GUI::Constants::default_double_decimals); - } - return editor; - }; - return builder; -} - -builder_t ScientificDoubleEditorBuilder() -{ - auto builder = [](const SessionItem* item) -> editor_t { - auto editor = std::make_unique<ScientificDoubleEditor>(); - if (item && item->hasData(ItemDataRole::LIMITS)) { - auto limits = item->data<RealLimits>(ItemDataRole::LIMITS); - editor->setRange(limits.lowerLimit(), limits.upperLimit()); - } - return editor; - }; - return builder; -} - -builder_t ScientificSpinBoxEditorBuilder() -{ - auto builder = [](const SessionItem* item) -> editor_t { - auto editor = std::make_unique<ScientificSpinBoxEditor>(); - if (item) { - if (item->hasData(ItemDataRole::LIMITS)) { - auto limits = item->data<RealLimits>(ItemDataRole::LIMITS); - editor->setRange(limits.lowerLimit(), limits.upperLimit()); - } - editor->setSingleStep(getStep(item->data<double>())); - } - editor->setDecimals(GUI::Constants::default_double_decimals); - return editor; - }; - return builder; -} - -builder_t ColorEditorBuilder() -{ - auto builder = [](const SessionItem*) -> editor_t { return std::make_unique<ColorEditor>(); }; - return builder; -} - -builder_t ComboPropertyEditorBuilder() -{ - auto builder = [](const SessionItem*) -> editor_t { - return std::make_unique<ComboPropertyEditor>(); - }; - return builder; -} - -builder_t ExternalPropertyEditorBuilder() -{ - auto builder = [](const SessionItem*) -> editor_t { - return std::make_unique<ExternalPropertyEditor>(); - }; - return builder; -} - -builder_t SelectableComboPropertyEditorBuilder() -{ - auto builder = [](const SessionItem*) -> editor_t { - return std::make_unique<SelectableComboBoxEditor>(); - }; - return builder; -} - -} // namespace ModelView::EditorBuilders diff --git a/mvvm/viewmodel/mvvm/editors/editorbuilders.h b/mvvm/viewmodel/mvvm/editors/editorbuilders.h deleted file mode 100644 index a6a41dcf350f11bcfd61335ff4bbb46c42b07322..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/editors/editorbuilders.h +++ /dev/null @@ -1,66 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/editors/editorbuilders.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEWMODEL_MVVM_EDITORS_EDITORBUILDERS_H -#define BORNAGAIN_MVVM_VIEWMODEL_MVVM_EDITORS_EDITORBUILDERS_H - -#include "mvvm/viewmodel_export.h" -#include <functional> -#include <memory> - -namespace ModelView { - -class CustomEditor; -class SessionItem; - -//! Collection of methods to build custom editors for trees/tables cells. -//! Used to edit SessionItem data in the context of DefaultEditorFactory. - -namespace EditorBuilders { - -using editor_t = std::unique_ptr<CustomEditor>; -using builder_t = std::function<editor_t(const SessionItem*)>; - -//! Builder for boolean property editor. -MVVM_VIEWMODEL_EXPORT builder_t BoolEditorBuilder(); - -//! Builder for integer property editor. -MVVM_VIEWMODEL_EXPORT builder_t IntegerEditorBuilder(); - -//! Builder for double editor with limits support. -MVVM_VIEWMODEL_EXPORT builder_t DoubleEditorBuilder(); - -//! Builder for double editor with scientific notation based on simple text field. -MVVM_VIEWMODEL_EXPORT builder_t ScientificDoubleEditorBuilder(); - -//! Builder for double editor with scientific notation and spinbox functionality. -MVVM_VIEWMODEL_EXPORT builder_t ScientificSpinBoxEditorBuilder(); - -//! Builder for color property editor. -MVVM_VIEWMODEL_EXPORT builder_t ColorEditorBuilder(); - -//! Builder for ComboProperty editor. -MVVM_VIEWMODEL_EXPORT builder_t ComboPropertyEditorBuilder(); - -//! Builder for external property editor. -MVVM_VIEWMODEL_EXPORT builder_t ExternalPropertyEditorBuilder(); - -//! Builder for ComboProperty editor with multi-selection functionality. -MVVM_VIEWMODEL_EXPORT builder_t SelectableComboPropertyEditorBuilder(); - -} // namespace EditorBuilders - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEWMODEL_MVVM_EDITORS_EDITORBUILDERS_H diff --git a/mvvm/viewmodel/mvvm/editors/externalpropertycomboeditor.cpp b/mvvm/viewmodel/mvvm/editors/externalpropertycomboeditor.cpp deleted file mode 100644 index c845bba78003763020e80f22cb65effc654994a1..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/editors/externalpropertycomboeditor.cpp +++ /dev/null @@ -1,109 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/editors/externalpropertycomboeditor.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/editors/externalpropertycomboeditor.h" -#include "mvvm/model/externalproperty.h" -#include <QColor> -#include <QComboBox> -#include <QStandardItemModel> -#include <QVBoxLayout> - -using namespace ModelView; - -ExternalPropertyComboEditor::ExternalPropertyComboEditor(callback_t callback, QWidget* parent) - : CustomEditor(parent) - , m_getPropertiesCallback(std::move(callback)) - , m_box(new QComboBox) - , m_comboModel(new QStandardItemModel(this)) -{ - setAutoFillBackground(true); - setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); - - auto layout = new QVBoxLayout; - layout->setMargin(0); - layout->setSpacing(0); - layout->addWidget(m_box); - setLayout(layout); - - m_box->setModel(m_comboModel); - - setConnected(true); -} - -QSize ExternalPropertyComboEditor::sizeHint() const -{ - return m_box->sizeHint(); -} - -QSize ExternalPropertyComboEditor::minimumSizeHint() const -{ - return m_box->minimumSizeHint(); -} - -void ExternalPropertyComboEditor::onIndexChanged(int index) -{ - auto property = m_data.value<ModelView::ExternalProperty>(); - auto mdata = m_getPropertiesCallback(); - - if (index >= 0 && index < static_cast<int>(mdata.size())) { - if (property != mdata[static_cast<size_t>(index)]) - setDataIntern(QVariant::fromValue(mdata[static_cast<size_t>(index)])); - } -} - -void ExternalPropertyComboEditor::update_components() -{ - setConnected(false); - - m_comboModel->clear(); - - QStandardItem* parentItem = m_comboModel->invisibleRootItem(); - for (auto prop : m_getPropertiesCallback()) { - auto item = new QStandardItem(QString::fromStdString(prop.text())); - parentItem->appendRow(item); - item->setData(prop.color(), Qt::DecorationRole); - } - - m_box->setCurrentIndex(internIndex()); - - setConnected(true); -} - -//! Returns index for QComboBox. - -int ExternalPropertyComboEditor::internIndex() -{ - if (!m_data.canConvert<ModelView::ExternalProperty>()) - return 0; - - auto property = m_data.value<ModelView::ExternalProperty>(); - int result(-1); - for (auto prop : m_getPropertiesCallback()) { - ++result; - if (property.identifier() == prop.identifier()) - return result; - } - - return result; -} - -void ExternalPropertyComboEditor::setConnected(bool isConnected) -{ - if (isConnected) - connect(m_box, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, - &ExternalPropertyComboEditor::onIndexChanged, Qt::UniqueConnection); - else - disconnect(m_box, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), - this, &ExternalPropertyComboEditor::onIndexChanged); -} diff --git a/mvvm/viewmodel/mvvm/editors/externalpropertycomboeditor.h b/mvvm/viewmodel/mvvm/editors/externalpropertycomboeditor.h deleted file mode 100644 index a5f573ace7ee927e5f867a32760eca6f6ad3d97e..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/editors/externalpropertycomboeditor.h +++ /dev/null @@ -1,58 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/editors/externalpropertycomboeditor.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEWMODEL_MVVM_EDITORS_EXTERNALPROPERTYCOMBOEDITOR_H -#define BORNAGAIN_MVVM_VIEWMODEL_MVVM_EDITORS_EXTERNALPROPERTYCOMBOEDITOR_H - -#include "mvvm/editors/customeditor.h" -#include <functional> -#include <vector> - -class QComboBox; -class QStandardItemModel; - -namespace ModelView { - -class ExternalProperty; - -//! Custom editor for table/tree cells to select ExternalProperty from the list of -//! external properties. Uses callbacks to retrieve vector of possible properties. - -class MVVM_VIEWMODEL_EXPORT ExternalPropertyComboEditor : public CustomEditor { - Q_OBJECT - -public: - using callback_t = std::function<std::vector<ModelView::ExternalProperty>()>; - - ExternalPropertyComboEditor(callback_t callback, QWidget* parent = nullptr); - - QSize sizeHint() const override; - QSize minimumSizeHint() const override; - -protected slots: - virtual void onIndexChanged(int index); - -private: - int internIndex(); - void setConnected(bool isConnected); - void update_components() override; - - callback_t m_getPropertiesCallback; - QComboBox* m_box{nullptr}; - QStandardItemModel* m_comboModel{nullptr}; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEWMODEL_MVVM_EDITORS_EXTERNALPROPERTYCOMBOEDITOR_H diff --git a/mvvm/viewmodel/mvvm/editors/externalpropertyeditor.cpp b/mvvm/viewmodel/mvvm/editors/externalpropertyeditor.cpp deleted file mode 100644 index 3a6ca4ac4a0aebb53effe5f1f462a8c5b4e8c53d..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/editors/externalpropertyeditor.cpp +++ /dev/null @@ -1,79 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/editors/externalpropertyeditor.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/editors/externalpropertyeditor.h" -#include "mvvm/editors/customeventfilters.h" -#include "mvvm/editors/styleutils.h" -#include "mvvm/model/customvariants.h" -#include "mvvm/model/externalproperty.h" -#include <QHBoxLayout> -#include <QLabel> -#include <QMessageBox> -#include <QToolButton> -#include <stdexcept> - -using namespace ModelView; - -ExternalPropertyEditor::ExternalPropertyEditor(QWidget* parent) - : CustomEditor(parent) - , m_textLabel(new QLabel) - , m_pixmapLabel(new QLabel) - , m_focusFilter(new LostFocusFilter(this)) - -{ - setMouseTracking(true); - setAutoFillBackground(true); - - auto layout = new QHBoxLayout; - layout->setContentsMargins(4, 0, 0, 0); - - auto button = new QToolButton; - button->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred)); - button->setText(QLatin1String(" . . . ")); - button->setToolTip("Open selector"); - layout->addWidget(m_pixmapLabel); - layout->addWidget(m_textLabel); - layout->addStretch(1); - layout->addWidget(button); - setFocusPolicy(Qt::StrongFocus); - setAttribute(Qt::WA_InputMethodEnabled); - connect(button, &QToolButton::clicked, this, &ExternalPropertyEditor::buttonClicked); - - setLayout(layout); -} - -void ExternalPropertyEditor::setCallback(std::function<void(const QVariant&)> callback) -{ - m_callback = std::move(callback); -} - -void ExternalPropertyEditor::buttonClicked() -{ - if (m_callback) - m_callback(m_data); - else - QMessageBox::warning(nullptr, "Not configured", "No external dialog configured."); -} - -void ExternalPropertyEditor::update_components() -{ - if (!Utils::IsExtPropertyVariant(m_data)) - throw std::runtime_error("Error. Wrong variant type (ExternalProperty is required)."); - - auto prop = m_data.value<ExternalProperty>(); - QPixmap pixmap(Style::DefaultPixmapSize(), Style::DefaultPixmapSize()); - pixmap.fill(prop.color()); - m_textLabel->setText(QString::fromStdString(prop.text())); - m_pixmapLabel->setPixmap(pixmap); -} diff --git a/mvvm/viewmodel/mvvm/editors/externalpropertyeditor.h b/mvvm/viewmodel/mvvm/editors/externalpropertyeditor.h deleted file mode 100644 index a42d21ea61aeb93996e59d207d66582919866915..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/editors/externalpropertyeditor.h +++ /dev/null @@ -1,51 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/editors/externalpropertyeditor.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEWMODEL_MVVM_EDITORS_EXTERNALPROPERTYEDITOR_H -#define BORNAGAIN_MVVM_VIEWMODEL_MVVM_EDITORS_EXTERNALPROPERTYEDITOR_H - -#include "mvvm/editors/customeditor.h" -#include <functional> - -class QLabel; - -namespace ModelView { - -class LostFocusFilter; - -//! Custom editor for QVariant based on ExternalProperty. -//! Contains icon, label and button to call external dialog via callback mechanism. - -class MVVM_VIEWMODEL_EXPORT ExternalPropertyEditor : public CustomEditor { - Q_OBJECT - -public: - explicit ExternalPropertyEditor(QWidget* parent = nullptr); - - void setCallback(std::function<void(const QVariant&)> callback); - -private slots: - void buttonClicked(); - -private: - void update_components() override; - QLabel* m_textLabel; - QLabel* m_pixmapLabel; - LostFocusFilter* m_focusFilter; - std::function<void(const QVariant&)> m_callback; //! actions to take on clicked button -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEWMODEL_MVVM_EDITORS_EXTERNALPROPERTYEDITOR_H diff --git a/mvvm/viewmodel/mvvm/editors/integereditor.cpp b/mvvm/viewmodel/mvvm/editors/integereditor.cpp deleted file mode 100644 index 3fa68a4de564fc8e1718cb0740af347bebd7b7df..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/editors/integereditor.cpp +++ /dev/null @@ -1,67 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/editors/integereditor.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/editors/integereditor.h" -#include <QSpinBox> -#include <QVBoxLayout> -#include <cmath> -#include <stdexcept> - -namespace { -const int max_val = 65536; -const int min_val = -max_val; -} // namespace - -using namespace ModelView; - -IntegerEditor::IntegerEditor(QWidget* parent) : CustomEditor(parent), m_intEditor(new QSpinBox) -{ - setAutoFillBackground(true); - m_intEditor->setFocusPolicy(Qt::StrongFocus); - m_intEditor->setKeyboardTracking(false); - m_intEditor->setRange(min_val, max_val); - - auto layout = new QVBoxLayout; - layout->setMargin(0); - layout->setSpacing(0); - - layout->addWidget(m_intEditor); - - connect(m_intEditor, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), - [=] { this->onEditingFinished(); }); - - setLayout(layout); - - setFocusProxy(m_intEditor); -} - -void IntegerEditor::setRange(int minimum, int maximum) -{ - m_intEditor->setRange(minimum, maximum); -} - -void IntegerEditor::onEditingFinished() -{ - int new_value = m_intEditor->value(); - if (new_value != m_data.value<int>()) - setDataIntern(QVariant::fromValue(new_value)); -} - -void IntegerEditor::update_components() -{ - if (m_data.type() != QVariant::Int) - throw std::runtime_error("IntegerEditor::update_components() -> Error. Wrong variant type"); - - m_intEditor->setValue(m_data.value<int>()); -} diff --git a/mvvm/viewmodel/mvvm/editors/integereditor.h b/mvvm/viewmodel/mvvm/editors/integereditor.h deleted file mode 100644 index 71f51dc2221cb4f412785339c5e33ac6d729fa54..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/editors/integereditor.h +++ /dev/null @@ -1,44 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/editors/integereditor.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEWMODEL_MVVM_EDITORS_INTEGEREDITOR_H -#define BORNAGAIN_MVVM_VIEWMODEL_MVVM_EDITORS_INTEGEREDITOR_H - -#include "mvvm/editors/customeditor.h" - -class QSpinBox; - -namespace ModelView { - -//! Custom editor for QVariant based on integer with possibility to set limits. - -class MVVM_VIEWMODEL_EXPORT IntegerEditor : public CustomEditor { - Q_OBJECT - -public: - explicit IntegerEditor(QWidget* parent = nullptr); - - void setRange(int minimum, int maximum); - -private slots: - void onEditingFinished(); - -private: - void update_components() override; - QSpinBox* m_intEditor; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEWMODEL_MVVM_EDITORS_INTEGEREDITOR_H diff --git a/mvvm/viewmodel/mvvm/editors/scientificdoubleeditor.cpp b/mvvm/viewmodel/mvvm/editors/scientificdoubleeditor.cpp deleted file mode 100644 index 3543e372547a08801458e245f099d6054d022a7f..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/editors/scientificdoubleeditor.cpp +++ /dev/null @@ -1,70 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/editors/scientificdoubleeditor.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/editors/scientificdoubleeditor.h" -#include "mvvm/utils/numericutils.h" -#include <QDoubleValidator> -#include <QLineEdit> -#include <QVBoxLayout> -#include <stdexcept> - -namespace { -const int max_digits = 1000; -} - -using namespace ModelView; - -ScientificDoubleEditor::ScientificDoubleEditor(QWidget* parent) - : CustomEditor(parent), m_lineEdit(new QLineEdit) - -{ - setAutoFillBackground(true); - - auto layout = new QVBoxLayout; - layout->setMargin(0); - layout->setSpacing(0); - - layout->addWidget(m_lineEdit); - - m_validator = new QDoubleValidator(0.0, std::numeric_limits<double>::max(), max_digits, this); - m_validator->setNotation(QDoubleValidator::ScientificNotation); - m_lineEdit->setValidator(m_validator); - - connect(m_lineEdit, &QLineEdit::editingFinished, this, - &ScientificDoubleEditor::onEditingFinished); - - setLayout(layout); -} - -void ScientificDoubleEditor::setRange(double minimum, double maximum) -{ - m_validator->setRange(minimum, maximum, max_digits); -} - -void ScientificDoubleEditor::onEditingFinished() -{ - double new_value = m_lineEdit->text().toDouble(); - - if (!Utils::AreAlmostEqual(new_value, m_data.value<double>())) - setDataIntern(QVariant::fromValue(new_value)); -} - -void ScientificDoubleEditor::update_components() -{ - if (m_data.type() != QVariant::Double) - throw std::runtime_error( - "ScientificDoubleEditor::update_components() -> Error. Wrong variant type"); - - m_lineEdit->setText(QString::number(m_data.value<double>(), 'g')); -} diff --git a/mvvm/viewmodel/mvvm/editors/scientificdoubleeditor.h b/mvvm/viewmodel/mvvm/editors/scientificdoubleeditor.h deleted file mode 100644 index 0330a009ef6ba9620442d73a0c924fbbbe2510c3..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/editors/scientificdoubleeditor.h +++ /dev/null @@ -1,46 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/editors/scientificdoubleeditor.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEWMODEL_MVVM_EDITORS_SCIENTIFICDOUBLEEDITOR_H -#define BORNAGAIN_MVVM_VIEWMODEL_MVVM_EDITORS_SCIENTIFICDOUBLEEDITOR_H - -#include "mvvm/editors/customeditor.h" - -class QLineEdit; -class QDoubleValidator; - -namespace ModelView { - -//! Custom editor for QVariant based on double with scientific notation support. - -class MVVM_VIEWMODEL_EXPORT ScientificDoubleEditor : public CustomEditor { - Q_OBJECT - -public: - explicit ScientificDoubleEditor(QWidget* parent = nullptr); - - void setRange(double minimum, double maximum); - -private slots: - void onEditingFinished(); - -private: - void update_components() override; - QLineEdit* m_lineEdit; - QDoubleValidator* m_validator{nullptr}; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEWMODEL_MVVM_EDITORS_SCIENTIFICDOUBLEEDITOR_H diff --git a/mvvm/viewmodel/mvvm/editors/scientificspinbox.cpp b/mvvm/viewmodel/mvvm/editors/scientificspinbox.cpp deleted file mode 100644 index f5ba485c23f9a5b263fd63c431eded5a728ca077..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/editors/scientificspinbox.cpp +++ /dev/null @@ -1,180 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/editors/scientificspinbox.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/editors/scientificspinbox.h" -#include "mvvm/editors/editor_constants.h" -#include <QLineEdit> -#include <cmath> -#include <limits> - -namespace { -const double upper_switch = 1000; -const double lower_switch = 0.1; -const double min_val = std::numeric_limits<double>::min(); -const double max_val = std::numeric_limits<double>::max(); - -bool useExponentialNotation(double val); -} // namespace - -using namespace ModelView; - -ScientificSpinBox::ScientificSpinBox(QWidget* parent) - : QAbstractSpinBox(parent) - , m_value(0.0) - , m_min(-max_val) - , m_max(max_val) - , m_step(1.0) - , m_decimals(GUI::Constants::default_double_decimals) -{ - QLocale locale; - locale.setNumberOptions(QLocale::RejectGroupSeparator); - m_validator.setLocale(locale); - m_validator.setNotation(QDoubleValidator::ScientificNotation); - - connect(this, &QAbstractSpinBox::editingFinished, this, &ScientificSpinBox::updateValue); -} - -ScientificSpinBox::~ScientificSpinBox() = default; - -double ScientificSpinBox::value() const -{ - // return last acceptable input (required for the proper focus-out behaviour) - double val = toDouble(text(), m_validator, m_min, m_max, m_value); - return round(val, m_decimals); -} - -void ScientificSpinBox::setValue(double val) -{ - double old_val = m_value; - m_value = round(val, m_decimals); - updateText(); - if (std::abs(old_val - m_value) > min_val) - emit valueChanged(m_value); -} - -void ScientificSpinBox::updateValue() -{ - double new_val = toDouble(text(), m_validator, m_min, m_max, m_value); - setValue(new_val); -} - -double ScientificSpinBox::singleStep() const -{ - return m_step; -} - -void ScientificSpinBox::setSingleStep(double step) -{ - m_step = step; -} - -double ScientificSpinBox::minimum() const -{ - return m_min; -} - -void ScientificSpinBox::setMinimum(double min) -{ - m_min = min; - if (m_value < m_min) - setValue(m_min); -} - -double ScientificSpinBox::maximum() const -{ - return m_max; -} - -void ScientificSpinBox::setMaximum(double max) -{ - m_max = max; - if (m_value > m_max) - setValue(m_max); -} - -void ScientificSpinBox::setDecimals(int val) -{ - if (val <= 0) - return; - m_decimals = val; - setValue(m_value); -} - -int ScientificSpinBox::decimals() const -{ - return m_decimals; -} - -void ScientificSpinBox::stepBy(int steps) -{ - double new_val = round(m_value + m_step * steps, m_decimals); - if (inRange(new_val)) - setValue(new_val); -} - -QString ScientificSpinBox::toString(double val, int decimal_points) -{ - QString result = useExponentialNotation(val) ? QString::number(val, 'e', decimal_points) - : QString::number(val, 'f', decimal_points); - - return result.replace(QRegExp("(\\.?0+)?((e{1}[\\+|-]{1})(0+)?([1-9]{1}.*))?$"), "\\3\\5"); -} - -double ScientificSpinBox::toDouble(QString text, const QDoubleValidator& validator, double min, - double max, double default_value) -{ - int pos = 0; - if (validator.validate(text, pos) == QValidator::Acceptable) { - double new_val = validator.locale().toDouble(text); - if (std::abs(new_val) < min_val) - new_val = 0.0; - return new_val >= min && new_val <= max ? new_val : default_value; - } - return default_value; -} - -double ScientificSpinBox::round(double val, int decimals) -{ - char notation = useExponentialNotation(val) ? 'e' : 'f'; - return QString::number(val, notation, decimals).toDouble(); -} - -QAbstractSpinBox::StepEnabled ScientificSpinBox::stepEnabled() const -{ - return isReadOnly() ? StepNone : StepUpEnabled | StepDownEnabled; -} - -void ScientificSpinBox::updateText() -{ - QString new_text = toString(m_value, m_decimals); - if (new_text != text()) - lineEdit()->setText(new_text); -} - -bool ScientificSpinBox::inRange(double val) const -{ - return val >= m_min && val <= m_max; -} - -namespace { -bool useExponentialNotation(double val) -{ - const double abs_val = std::abs(val); - - if (abs_val <= min_val) - return false; - - return abs_val >= upper_switch || abs_val < lower_switch; -} -} // namespace diff --git a/mvvm/viewmodel/mvvm/editors/scientificspinbox.h b/mvvm/viewmodel/mvvm/editors/scientificspinbox.h deleted file mode 100644 index 6f99184b1887bc95af7ac66d4918001a006adc6d..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/editors/scientificspinbox.h +++ /dev/null @@ -1,74 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/editors/scientificspinbox.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEWMODEL_MVVM_EDITORS_SCIENTIFICSPINBOX_H -#define BORNAGAIN_MVVM_VIEWMODEL_MVVM_EDITORS_SCIENTIFICSPINBOX_H - -#include "mvvm/viewmodel_export.h" -#include <QAbstractSpinBox> - -namespace ModelView { - -class MVVM_VIEWMODEL_EXPORT ScientificSpinBox : public QAbstractSpinBox { - Q_OBJECT - Q_PROPERTY(double value MEMBER m_value READ value WRITE setValue NOTIFY valueChanged USER true) - -public: - ScientificSpinBox(QWidget* parent = nullptr); - ~ScientificSpinBox() override; - - double value() const; - void setValue(double val); - - double singleStep() const; - void setSingleStep(double step); - - double minimum() const; - void setMinimum(double min); - - double maximum() const; - void setMaximum(double max); - - void setDecimals(int); - int decimals() const; - - void stepBy(int steps) override; - QValidator::State validate(QString&, int&) const override { return QValidator::Acceptable; } - void fixup(QString&) const override {} - - static QString toString(double val, int decimal_points); - static double toDouble(QString text, const QDoubleValidator& validator, double min, double max, - double default_value); - static double round(double val, int decimals); - -signals: - void valueChanged(double value); - -protected: - QAbstractSpinBox::StepEnabled stepEnabled() const override; - -private: - void updateValue(); - void updateText(); - bool inRange(double val) const; - - double m_value, m_min, m_max; - double m_step; - int m_decimals; - QDoubleValidator m_validator; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEWMODEL_MVVM_EDITORS_SCIENTIFICSPINBOX_H diff --git a/mvvm/viewmodel/mvvm/editors/scientificspinboxeditor.cpp b/mvvm/viewmodel/mvvm/editors/scientificspinboxeditor.cpp deleted file mode 100644 index 27b25cedf9ef152ef175abe8376f0f1235705b5f..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/editors/scientificspinboxeditor.cpp +++ /dev/null @@ -1,80 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/editors/scientificspinboxeditor.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/editors/scientificspinboxeditor.h" -#include "mvvm/editors/scientificspinbox.h" -#include "mvvm/utils/numericutils.h" -#include <QVBoxLayout> -#include <stdexcept> - -using namespace ModelView; - -ScientificSpinBoxEditor::ScientificSpinBoxEditor(QWidget* parent) - : CustomEditor(parent), m_doubleEditor(new ScientificSpinBox) -{ - setAutoFillBackground(true); - setFocusPolicy(Qt::StrongFocus); - m_doubleEditor->setFocusPolicy(Qt::StrongFocus); - m_doubleEditor->setKeyboardTracking(false); - - auto layout = new QVBoxLayout; - layout->setMargin(0); - layout->setSpacing(0); - - layout->addWidget(m_doubleEditor); - - connect(m_doubleEditor, &ScientificSpinBox::valueChanged, [=] { this->onEditingFinished(); }); - - setLayout(layout); - - setFocusProxy(m_doubleEditor); -} - -void ScientificSpinBoxEditor::setRange(double minimum, double maximum) -{ - m_doubleEditor->setMinimum(minimum); - m_doubleEditor->setMaximum(maximum); -} - -void ScientificSpinBoxEditor::setDecimals(int decimals) -{ - m_doubleEditor->setDecimals(decimals); -} - -void ScientificSpinBoxEditor::setSingleStep(double step) -{ - m_doubleEditor->setSingleStep(step); -} - -bool ScientificSpinBoxEditor::is_persistent() const -{ - return true; -} - -void ScientificSpinBoxEditor::onEditingFinished() -{ - double new_value = m_doubleEditor->value(); - - if (!Utils::AreAlmostEqual(new_value, m_data.value<double>())) - setDataIntern(QVariant::fromValue(new_value)); -} - -void ScientificSpinBoxEditor::update_components() -{ - if (m_data.type() != QVariant::Double) - throw std::runtime_error( - "ScientificSpinBoxEditor::update_components() -> Error. Wrong variant type"); - - m_doubleEditor->setValue(m_data.value<double>()); -} diff --git a/mvvm/viewmodel/mvvm/editors/scientificspinboxeditor.h b/mvvm/viewmodel/mvvm/editors/scientificspinboxeditor.h deleted file mode 100644 index cacf9b4d37ac7540a4dcef74ca6dcf60c32b5a81..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/editors/scientificspinboxeditor.h +++ /dev/null @@ -1,48 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/editors/scientificspinboxeditor.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEWMODEL_MVVM_EDITORS_SCIENTIFICSPINBOXEDITOR_H -#define BORNAGAIN_MVVM_VIEWMODEL_MVVM_EDITORS_SCIENTIFICSPINBOXEDITOR_H - -#include "mvvm/editors/customeditor.h" - -namespace ModelView { - -class ScientificSpinBox; - -//! Custom editor for QVariant based on double with scientific notation support. - -class MVVM_VIEWMODEL_EXPORT ScientificSpinBoxEditor : public CustomEditor { - Q_OBJECT - -public: - explicit ScientificSpinBoxEditor(QWidget* parent = nullptr); - - void setRange(double minimum, double maximum); - void setDecimals(int decimals); - void setSingleStep(double step); - - bool is_persistent() const override; - -private slots: - void onEditingFinished(); - -private: - void update_components() override; - ScientificSpinBox* m_doubleEditor; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEWMODEL_MVVM_EDITORS_SCIENTIFICSPINBOXEDITOR_H diff --git a/mvvm/viewmodel/mvvm/editors/selectablecomboboxeditor.cpp b/mvvm/viewmodel/mvvm/editors/selectablecomboboxeditor.cpp deleted file mode 100644 index 70b9139ade8aca175d0fddcf1dc863b5b2f5a335..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/editors/selectablecomboboxeditor.cpp +++ /dev/null @@ -1,211 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/editors/selectablecomboboxeditor.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -// ---------------------------------------------------------------------------- -// https://stackoverflow.com/questions/8422760/combobox-of-checkboxes -// https://stackoverflow.com/questions/21186779/catch-mouse-button-pressed-signal-from-qcombobox-popup-menu -// https://gist.github.com/mistic100/c3b7f3eabc65309687153fe3e0a9a720 -// ---------------------------------------------------------------------------- - -#include "mvvm/editors/selectablecomboboxeditor.h" -#include "mvvm/editors/customeventfilters.h" -#include "mvvm/model/comboproperty.h" -#include "mvvm/utils/containerutils.h" -#include <QAbstractItemView> -#include <QComboBox> -#include <QLineEdit> -#include <QMouseEvent> -#include <QStandardItem> -#include <QStandardItemModel> -#include <QStyledItemDelegate> -#include <QVBoxLayout> - -using namespace ModelView; - -//! Provides custom style delegate for QComboBox to allow checkboxes. - -class QCheckListStyledItemDelegate : public QStyledItemDelegate { -public: - QCheckListStyledItemDelegate(QObject* parent = nullptr) : QStyledItemDelegate(parent) {} - - void paint(QPainter* painter, const QStyleOptionViewItem& option, - const QModelIndex& index) const override - { - auto styleOption = const_cast<QStyleOptionViewItem&>(option); - styleOption.showDecorationSelected = false; - QStyledItemDelegate::paint(painter, styleOption, index); - } -}; - -// ---------------------------------------------------------------------------- - -SelectableComboBoxEditor::SelectableComboBoxEditor(QWidget* parent) - : CustomEditor(parent) - , m_box(new QComboBox) - , m_wheelEventFilter(new WheelEventFilter(this)) - , m_model(new QStandardItemModel(this)) -{ - setAutoFillBackground(true); - setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); - - m_box->installEventFilter(m_wheelEventFilter); - m_box->view()->viewport()->installEventFilter(this); - - // Editable mode will be used to have None/Multiple labels on top - m_box->setEditable(true); - m_box->lineEdit()->setReadOnly(true); - m_box->lineEdit()->installEventFilter(this); - connect(m_box->lineEdit(), &QLineEdit::selectionChanged, m_box->lineEdit(), - &QLineEdit::deselect); - - // transforms ordinary combo box into check list - m_box->setItemDelegate(new QCheckListStyledItemDelegate(this)); - m_box->setModel(m_model); - - auto layout = new QVBoxLayout; - layout->setMargin(0); - layout->setSpacing(0); - layout->addWidget(m_box); - setLayout(layout); - setConnected(true); -} - -QSize SelectableComboBoxEditor::sizeHint() const -{ - return m_box->sizeHint(); -} - -QSize SelectableComboBoxEditor::minimumSizeHint() const -{ - return m_box->minimumSizeHint(); -} - -bool SelectableComboBoxEditor::is_persistent() const -{ - return true; -} - -//! Propagate check state from the model to ComboProperty. - -void SelectableComboBoxEditor::onModelDataChanged(const QModelIndex& topLeft, const QModelIndex&, - const QVector<int>& roles) -{ -#if QT_VERSION > QT_VERSION_CHECK(5, 9, 0) - // for older versions this role is always empty - if (!roles.contains(Qt::CheckStateRole)) - return; -#endif - - auto item = m_model->itemFromIndex(topLeft); - if (!item) - return; - - ComboProperty comboProperty = m_data.value<ComboProperty>(); - auto state = item->checkState() == Qt::Checked ? true : false; - comboProperty.setSelected(topLeft.row(), state); - - updateBoxLabel(); - setDataIntern(QVariant::fromValue<ComboProperty>(comboProperty)); -} - -//! Processes press event in QComboBox's underlying list view. - -void SelectableComboBoxEditor::onClickedList(const QModelIndex& index) -{ - if (auto item = m_model->itemFromIndex(index)) { - auto state = item->checkState() == Qt::Checked ? Qt::Unchecked : Qt::Checked; - item->setCheckState(state); - } -} - -//! Handles mouse clicks on QComboBox elements. - -bool SelectableComboBoxEditor::eventFilter(QObject* obj, QEvent* event) -{ - if (isClickToSelect(obj, event)) { - // Handles mouse clicks on QListView when it is expanded from QComboBox - // 1) Prevents list from closing while selecting items. - // 2) Correctly calculates underlying model index when mouse is over check box style - // element. - const auto mouseEvent = static_cast<const QMouseEvent*>(event); - auto index = m_box->view()->indexAt(mouseEvent->pos()); - onClickedList(index); - return true; - - } else if (isClickToExpand(obj, event)) { - // Expands box when clicking on None/Multiple label - m_box->showPopup(); - return true; - - } else { - // Propagate to the parent class. - return QObject::eventFilter(obj, event); - } -} - -void SelectableComboBoxEditor::update_components() -{ - if (!m_data.canConvert<ComboProperty>()) - return; - - ComboProperty property = m_data.value<ComboProperty>(); - - setConnected(false); - m_model->clear(); - - auto labels = property.values(); - auto selectedIndices = property.selectedIndices(); - - for (size_t i = 0; i < labels.size(); ++i) { - auto item = new QStandardItem(QString::fromStdString(labels[i])); - m_model->invisibleRootItem()->appendRow(item); - item->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable); - item->setCheckable(true); - - auto state = Utils::Contains(selectedIndices, i) ? Qt::Checked : Qt::Unchecked; - item->setData(state, Qt::CheckStateRole); - } - - setConnected(true); - updateBoxLabel(); -} - -void SelectableComboBoxEditor::setConnected(bool isConnected) -{ - if (isConnected) { - connect(m_model, &QStandardItemModel::dataChanged, this, - &SelectableComboBoxEditor::onModelDataChanged); - } else { - disconnect(m_model, &QStandardItemModel::dataChanged, this, - &SelectableComboBoxEditor::onModelDataChanged); - } -} - -//! Update text on QComboBox with the label provided by combo property. - -void SelectableComboBoxEditor::updateBoxLabel() -{ - ComboProperty combo = m_data.value<ComboProperty>(); - m_box->setCurrentText(QString::fromStdString(combo.label())); -} - -bool SelectableComboBoxEditor::isClickToSelect(QObject* obj, QEvent* event) const -{ - return obj == m_box->view()->viewport() && event->type() == QEvent::MouseButtonRelease; -} - -bool SelectableComboBoxEditor::isClickToExpand(QObject* obj, QEvent* event) const -{ - return obj == m_box->lineEdit() && event->type() == QEvent::MouseButtonRelease; -} diff --git a/mvvm/viewmodel/mvvm/editors/selectablecomboboxeditor.h b/mvvm/viewmodel/mvvm/editors/selectablecomboboxeditor.h deleted file mode 100644 index 2c3bc636a00cb0f03a59b289e42affa2b2a6cabb..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/editors/selectablecomboboxeditor.h +++ /dev/null @@ -1,63 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/editors/selectablecomboboxeditor.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEWMODEL_MVVM_EDITORS_SELECTABLECOMBOBOXEDITOR_H -#define BORNAGAIN_MVVM_VIEWMODEL_MVVM_EDITORS_SELECTABLECOMBOBOXEDITOR_H - -#include "mvvm/editors/customeditor.h" - -class QComboBox; -class QStandardItemModel; - -namespace ModelView { - -class WheelEventFilter; - -//! Adds multi-selection capabilities to QComboBox. - -class MVVM_VIEWMODEL_EXPORT SelectableComboBoxEditor : public CustomEditor { - Q_OBJECT - -public: - explicit SelectableComboBoxEditor(QWidget* parent = nullptr); - - QSize sizeHint() const override; - QSize minimumSizeHint() const override; - - bool is_persistent() const override; - -protected slots: - void onModelDataChanged(const QModelIndex&, const QModelIndex&, const QVector<int>&); - - void onClickedList(const QModelIndex& index); - -protected: - void update_components() override; - -private: - bool eventFilter(QObject* obj, QEvent* event) override; - void setConnected(bool isConnected); - void updateBoxLabel(); - - bool isClickToSelect(QObject* obj, QEvent* event) const; - bool isClickToExpand(QObject* obj, QEvent* event) const; - - QComboBox* m_box{nullptr}; - WheelEventFilter* m_wheelEventFilter{nullptr}; - QStandardItemModel* m_model{nullptr}; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEWMODEL_MVVM_EDITORS_SELECTABLECOMBOBOXEDITOR_H diff --git a/mvvm/viewmodel/mvvm/editors/styleutils.cpp b/mvvm/viewmodel/mvvm/editors/styleutils.cpp deleted file mode 100644 index 4aff4cba07394d53f5bff872c1e6b71e24f46226..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/editors/styleutils.cpp +++ /dev/null @@ -1,33 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/editors/styleutils.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/editors/styleutils.h" - -int ModelView::Style::DefaultPixmapSize() -{ - const int default_pixmap_size = 16; - return default_pixmap_size; -} - -int ModelView::Style::DefaultInfoBarHeight() -{ - const int default_info_bar_height = 24; - return default_info_bar_height; -} - -int ModelView::Style::DefaultInfoBarTextSize() -{ - const int default_info_bar_text_saize = 8; - return default_info_bar_text_saize; -} diff --git a/mvvm/viewmodel/mvvm/editors/styleutils.h b/mvvm/viewmodel/mvvm/editors/styleutils.h deleted file mode 100644 index 3c536d46748b57d77d66150d176c5fb8592fa54e..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/editors/styleutils.h +++ /dev/null @@ -1,33 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/editors/styleutils.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEWMODEL_MVVM_EDITORS_STYLEUTILS_H -#define BORNAGAIN_MVVM_VIEWMODEL_MVVM_EDITORS_STYLEUTILS_H - -#include "mvvm/viewmodel_export.h" - -namespace ModelView::Style { - -//! Returns int value corresponding to pixmap in standard Qt table/tree decorations. -MVVM_VIEWMODEL_EXPORT int DefaultPixmapSize(); - -//! Returns default height of info bar -MVVM_VIEWMODEL_EXPORT int DefaultInfoBarHeight(); - -//! Returns default size of text on info bar. -MVVM_VIEWMODEL_EXPORT int DefaultInfoBarTextSize(); - -} // namespace ModelView::Style - -#endif // BORNAGAIN_MVVM_VIEWMODEL_MVVM_EDITORS_STYLEUTILS_H diff --git a/mvvm/viewmodel/mvvm/factories/CMakeLists.txt b/mvvm/viewmodel/mvvm/factories/CMakeLists.txt deleted file mode 100644 index 71dbc879c933ed9653703f01c6995ecdc431b092..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/factories/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -target_sources(${library_name} PRIVATE - viewmodelcontrollerbuilder.cpp - viewmodelcontrollerbuilder.h - viewmodelcontrollerfactory.h - viewmodelfactory.cpp - viewmodelfactory.h -) diff --git a/mvvm/viewmodel/mvvm/factories/viewmodelcontrollerbuilder.cpp b/mvvm/viewmodel/mvvm/factories/viewmodelcontrollerbuilder.cpp deleted file mode 100644 index 93fd87afcfc6a456a0eb8445df7631c0938b143f..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/factories/viewmodelcontrollerbuilder.cpp +++ /dev/null @@ -1,72 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/factories/viewmodelcontrollerbuilder.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/factories/viewmodelcontrollerbuilder.h" -#include "mvvm/interfaces/childrenstrategyinterface.h" -#include "mvvm/interfaces/rowstrategyinterface.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/viewmodel/viewmodelcontroller.h" -#include <stdexcept> - -namespace ModelView { - -ViewModelControllerBuilder::ViewModelControllerBuilder() = default; - -ViewModelControllerBuilder::~ViewModelControllerBuilder() = default; - -ViewModelControllerBuilder::operator std::unique_ptr<ViewModelController>() -{ - if (!context.model) - throw std::runtime_error("Error in ViewModelController: undefined model"); - - if (!context.children_strategy) - throw std::runtime_error("Error in ViewModelController: no children strategy defined."); - - if (!context.row_strategy) - throw std::runtime_error("Error in ViewModelController: no row strategy defined."); - - auto result = std::make_unique<ViewModelController>(context.model, context.view_model); - result->setChildrenStrategy(std::move(context.children_strategy)); - result->setRowStrategy(std::move(context.row_strategy)); - - return result; -} - -ViewModelControllerBuilder::self& ViewModelControllerBuilder::model(SessionModel* model) -{ - context.model = model; - return *this; -} - -ViewModelControllerBuilder::self& ViewModelControllerBuilder::viewModel(ViewModelBase* view_model) -{ - context.view_model = view_model; - return *this; -} - -ViewModelControllerBuilder::self& ViewModelControllerBuilder::childrenStrategy( - std::unique_ptr<ChildrenStrategyInterface> children_strategy) -{ - context.children_strategy = std::move(children_strategy); - return *this; -} - -ViewModelControllerBuilder::self& -ViewModelControllerBuilder::rowStrategy(std::unique_ptr<RowStrategyInterface> row_strategy) -{ - context.row_strategy = std::move(row_strategy); - return *this; -} - -} // namespace ModelView diff --git a/mvvm/viewmodel/mvvm/factories/viewmodelcontrollerbuilder.h b/mvvm/viewmodel/mvvm/factories/viewmodelcontrollerbuilder.h deleted file mode 100644 index 7189a5139962fa1e3c2a7528954e1ee10c59da2e..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/factories/viewmodelcontrollerbuilder.h +++ /dev/null @@ -1,62 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/factories/viewmodelcontrollerbuilder.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEWMODEL_MVVM_FACTORIES_VIEWMODELCONTROLLERBUILDER_H -#define BORNAGAIN_MVVM_VIEWMODEL_MVVM_FACTORIES_VIEWMODELCONTROLLERBUILDER_H - -#include "mvvm/viewmodel/viewmodelcontroller.h" -#include "mvvm/viewmodel_export.h" -#include <memory> - -namespace ModelView { - -class SessionModel; -class ViewModelBase; -class ChildrenStrategyInterface; -class RowStrategyInterface; - -//! Builder class for ViewModelController. - -class MVVM_VIEWMODEL_EXPORT ViewModelControllerBuilder { -public: - using self = ViewModelControllerBuilder; - - ViewModelControllerBuilder(); - ~ViewModelControllerBuilder(); - - ViewModelControllerBuilder(const ViewModelControllerBuilder& other) = delete; - ViewModelControllerBuilder& operator=(const ViewModelControllerBuilder& other) = delete; - - self& model(SessionModel* model); - self& viewModel(ViewModelBase* view_model); - self& childrenStrategy(std::unique_ptr<ChildrenStrategyInterface> children_strategy); - self& rowStrategy(std::unique_ptr<RowStrategyInterface> row_strategy); - - operator std::unique_ptr<ViewModelController>(); - -private: - //! Components necessary to build ViewModelController - struct Context { - SessionModel* model{nullptr}; - ViewModelBase* view_model{nullptr}; - std::unique_ptr<ChildrenStrategyInterface> children_strategy; - std::unique_ptr<RowStrategyInterface> row_strategy; - }; - - Context context; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEWMODEL_MVVM_FACTORIES_VIEWMODELCONTROLLERBUILDER_H diff --git a/mvvm/viewmodel/mvvm/factories/viewmodelcontrollerfactory.h b/mvvm/viewmodel/mvvm/factories/viewmodelcontrollerfactory.h deleted file mode 100644 index debcaf31a8baa937a461b32fbd705cf2e14fa0d6..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/factories/viewmodelcontrollerfactory.h +++ /dev/null @@ -1,47 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/factories/viewmodelcontrollerfactory.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEWMODEL_MVVM_FACTORIES_VIEWMODELCONTROLLERFACTORY_H -#define BORNAGAIN_MVVM_VIEWMODEL_MVVM_FACTORIES_VIEWMODELCONTROLLERFACTORY_H - -#include "mvvm/factories/viewmodelcontrollerbuilder.h" -#include "mvvm/viewmodel_export.h" -#include <memory> - -namespace ModelView { - -class SessionModel; -class ViewModelBase; -class ViewModelController; - -namespace Factory { - -//! Create universal controller. - -template <typename ChildrenStrategy, typename RowStrategy> -std::unique_ptr<ViewModelController> CreateController(SessionModel* session_model, - ViewModelBase* view_model) -{ - return ViewModelControllerBuilder() - .model(session_model) - .viewModel(view_model) - .childrenStrategy(std::make_unique<ChildrenStrategy>()) - .rowStrategy(std::make_unique<RowStrategy>()); -} - -} // namespace Factory - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEWMODEL_MVVM_FACTORIES_VIEWMODELCONTROLLERFACTORY_H diff --git a/mvvm/viewmodel/mvvm/factories/viewmodelfactory.cpp b/mvvm/viewmodel/mvvm/factories/viewmodelfactory.cpp deleted file mode 100644 index 8ec0a4a92870c9eef6c75a29f19be2640cbadca4..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/factories/viewmodelfactory.cpp +++ /dev/null @@ -1,47 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/factories/viewmodelfactory.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/factories/viewmodelfactory.h" -#include "mvvm/viewmodel/defaultviewmodel.h" -#include "mvvm/viewmodel/propertyflatviewmodel.h" -#include "mvvm/viewmodel/propertytableviewmodel.h" -#include "mvvm/viewmodel/propertyviewmodel.h" -#include "mvvm/viewmodel/topitemsviewmodel.h" - -using namespace ModelView; - -std::unique_ptr<ViewModel> Factory::CreateDefaultViewModel(ModelView::SessionModel* model) -{ - return std::make_unique<DefaultViewModel>(model); -} - -std::unique_ptr<ViewModel> Factory::CreatePropertyViewModel(SessionModel* model) -{ - return std::make_unique<PropertyViewModel>(model); -} - -std::unique_ptr<ViewModel> Factory::CreatePropertyTableViewModel(SessionModel* model) -{ - return std::make_unique<PropertyTableViewModel>(model); -} - -std::unique_ptr<ViewModel> Factory::CreateTopItemsViewModel(SessionModel* model) -{ - return std::make_unique<TopItemsViewModel>(model); -} - -std::unique_ptr<ViewModel> Factory::CreatePropertyFlatViewModel(SessionModel* model) -{ - return std::make_unique<PropertyFlatViewModel>(model); -} diff --git a/mvvm/viewmodel/mvvm/factories/viewmodelfactory.h b/mvvm/viewmodel/mvvm/factories/viewmodelfactory.h deleted file mode 100644 index 2b481d63d4a4359d286540ec3520508e0aa30f0c..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/factories/viewmodelfactory.h +++ /dev/null @@ -1,74 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/factories/viewmodelfactory.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEWMODEL_MVVM_FACTORIES_VIEWMODELFACTORY_H -#define BORNAGAIN_MVVM_VIEWMODEL_MVVM_FACTORIES_VIEWMODELFACTORY_H - -#include "mvvm/factories/viewmodelcontrollerfactory.h" -#include "mvvm/viewmodel/viewmodel.h" -#include "mvvm/viewmodel_export.h" -#include <memory> - -namespace ModelView { - -class SessionModel; -class ViewModel; - -namespace Factory { - -//! Creates view model to represent SessionModel for Qt views. -//! The model has two columns, all items are shown. -MVVM_VIEWMODEL_EXPORT std::unique_ptr<ViewModel> CreateDefaultViewModel(SessionModel* model); - -//! Creates view model to represent SessionModel for Qt views. -//! The model has two columns, shows only property items and simplified group items. -MVVM_VIEWMODEL_EXPORT std::unique_ptr<ViewModel> CreatePropertyViewModel(SessionModel* model); - -//! Creates view model to represent SessionModel for Qt views. -//! Shows all properties of CompoundItem in columns of the table, rows of the table represent -//! different CompoundItems. Items of same type and table like structure of the model are expected. -MVVM_VIEWMODEL_EXPORT std::unique_ptr<ViewModel> CreatePropertyTableViewModel(SessionModel* model); - -//! Creates view model to represent SessionModel for Qt views. -//! Shows only top items. -MVVM_VIEWMODEL_EXPORT std::unique_ptr<ViewModel> CreateTopItemsViewModel(SessionModel* model); - -//! Creates view model to represent SessionModel for Qt views. -//! The model has two columns, shows only property items and simplified group items. -//! Subproperties of group item moved one level up. -MVVM_VIEWMODEL_EXPORT std::unique_ptr<ViewModel> CreatePropertyFlatViewModel(SessionModel* model); - -//! Creates view model to represent SessionModel for Qt views. -//! Use user provided types for ChildrenStrategy and RowStrategy. -template <typename ChildrenStrategy, typename RowStrategy> -std::unique_ptr<ViewModel> CreateViewModel(SessionModel* session_model) -{ - auto controller = CreateController<ChildrenStrategy, RowStrategy>(session_model, nullptr); - return std::make_unique<ViewModel>(std::move(controller)); -} - -//! Creates view model to represent SessionModel for Qt views. -//! Use user provided controller type. -template <typename ViewModelController> -std::unique_ptr<ViewModel> CreateViewModel(SessionModel* session_model) -{ - auto controller = std::make_unique<ViewModelController>(session_model); - return std::make_unique<ViewModel>(std::move(controller)); -} - -} // namespace Factory - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEWMODEL_MVVM_FACTORIES_VIEWMODELFACTORY_H diff --git a/mvvm/viewmodel/mvvm/interfaces/CMakeLists.txt b/mvvm/viewmodel/mvvm/interfaces/CMakeLists.txt deleted file mode 100644 index 6080cc1b5e818400ece40a74e3d4c2a306fe270c..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/interfaces/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -target_sources(${library_name} PRIVATE - celldecoratorinterface.h - childrenstrategyinterface.h - editorfactoryinterface.h - rowstrategyinterface.h -) diff --git a/mvvm/viewmodel/mvvm/interfaces/celldecoratorinterface.h b/mvvm/viewmodel/mvvm/interfaces/celldecoratorinterface.h deleted file mode 100644 index 938b18683b9889de760401f26152413fc4e6e54d..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/interfaces/celldecoratorinterface.h +++ /dev/null @@ -1,38 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/interfaces/celldecoratorinterface.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEWMODEL_MVVM_INTERFACES_CELLDECORATORINTERFACE_H -#define BORNAGAIN_MVVM_VIEWMODEL_MVVM_INTERFACES_CELLDECORATORINTERFACE_H - -#include "mvvm/viewmodel_export.h" -#include <string> - -class QModelIndex; -class QStyleOptionViewItem; - -namespace ModelView { - -//! Interface class to generate cell decorations (i.e. text) in Qt trees and tables. - -class MVVM_VIEWMODEL_EXPORT CellDecoratorInterface { -public: - virtual ~CellDecoratorInterface() = default; - - virtual bool hasCustomDecoration(const QModelIndex& index) const = 0; - virtual void initStyleOption(QStyleOptionViewItem* option, const QModelIndex& index) = 0; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEWMODEL_MVVM_INTERFACES_CELLDECORATORINTERFACE_H diff --git a/mvvm/viewmodel/mvvm/interfaces/childrenstrategyinterface.h b/mvvm/viewmodel/mvvm/interfaces/childrenstrategyinterface.h deleted file mode 100644 index 4174b76b972dbc75bb5008d3d20b641e038c5b0d..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/interfaces/childrenstrategyinterface.h +++ /dev/null @@ -1,41 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/interfaces/childrenstrategyinterface.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEWMODEL_MVVM_INTERFACES_CHILDRENSTRATEGYINTERFACE_H -#define BORNAGAIN_MVVM_VIEWMODEL_MVVM_INTERFACES_CHILDRENSTRATEGYINTERFACE_H - -#include "mvvm/viewmodel_export.h" -#include <vector> - -namespace ModelView { - -class SessionItem; - -//! Base class for strategies to find children, actual of fictional, of given item. - -//! Reported vector of children might be different from actual children of given item. -//! The strategy is used in context of AbstractViewModel while exposing SessionModel to Qt. -//! Thanks to this strategy ViewModel decides which items to visit. - -class MVVM_VIEWMODEL_EXPORT ChildrenStrategyInterface { -public: - virtual ~ChildrenStrategyInterface() = default; - - //! Returns vector of children of given item. - virtual std::vector<SessionItem*> children(const SessionItem* item) const = 0; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEWMODEL_MVVM_INTERFACES_CHILDRENSTRATEGYINTERFACE_H diff --git a/mvvm/viewmodel/mvvm/interfaces/editorfactoryinterface.h b/mvvm/viewmodel/mvvm/interfaces/editorfactoryinterface.h deleted file mode 100644 index 6e474dd50541bcb068a4062202440bad73b1b9ad..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/interfaces/editorfactoryinterface.h +++ /dev/null @@ -1,41 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/interfaces/editorfactoryinterface.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEWMODEL_MVVM_INTERFACES_EDITORFACTORYINTERFACE_H -#define BORNAGAIN_MVVM_VIEWMODEL_MVVM_INTERFACES_EDITORFACTORYINTERFACE_H - -#include "mvvm/viewmodel_export.h" -#include <memory> -#include <string> - -class QModelIndex; -class QWidget; - -namespace ModelView { - -class CustomEditor; - -//! Interface for custom editor factory. -//! Intended for editor construction in cells of tables and trees in the context of delegate. - -class MVVM_VIEWMODEL_EXPORT EditorFactoryInterface { -public: - virtual ~EditorFactoryInterface() = default; - - virtual std::unique_ptr<CustomEditor> createEditor(const QModelIndex& index) const = 0; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEWMODEL_MVVM_INTERFACES_EDITORFACTORYINTERFACE_H diff --git a/mvvm/viewmodel/mvvm/interfaces/rowstrategyinterface.h b/mvvm/viewmodel/mvvm/interfaces/rowstrategyinterface.h deleted file mode 100644 index f919423c4f136fa3e0de56a2e967e8a1e7729bfe..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/interfaces/rowstrategyinterface.h +++ /dev/null @@ -1,42 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/interfaces/rowstrategyinterface.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEWMODEL_MVVM_INTERFACES_ROWSTRATEGYINTERFACE_H -#define BORNAGAIN_MVVM_VIEWMODEL_MVVM_INTERFACES_ROWSTRATEGYINTERFACE_H - -#include "mvvm/viewmodel_export.h" -#include <QStringList> -#include <memory> -#include <vector> - -namespace ModelView { - -class SessionItem; -class ViewItem; - -//! Base class to construct row of ViewItem's from given SessionItem. -//! Used in context of AbstractViewModel while exposing SessionModel to Qt. - -class MVVM_VIEWMODEL_EXPORT RowStrategyInterface { -public: - virtual ~RowStrategyInterface() = default; - - virtual QStringList horizontalHeaderLabels() const = 0; - - virtual std::vector<std::unique_ptr<ViewItem>> constructRow(SessionItem*) = 0; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEWMODEL_MVVM_INTERFACES_ROWSTRATEGYINTERFACE_H diff --git a/mvvm/viewmodel/mvvm/viewmodel/CMakeLists.txt b/mvvm/viewmodel/mvvm/viewmodel/CMakeLists.txt deleted file mode 100644 index 0d93f441bc62225ef2000e74d7f430616234dc24..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/viewmodel/CMakeLists.txt +++ /dev/null @@ -1,36 +0,0 @@ -target_sources(${library_name} PRIVATE - defaultcelldecorator.cpp - defaultcelldecorator.h - defaultviewmodel.cpp - defaultviewmodel.h - labeldatarowstrategy.cpp - labeldatarowstrategy.h - propertiesrowstrategy.cpp - propertiesrowstrategy.h - propertyflatviewmodel.cpp - propertyflatviewmodel.h - propertytableviewmodel.cpp - propertytableviewmodel.h - propertyviewmodel.cpp - propertyviewmodel.h - standardchildrenstrategies.cpp - standardchildrenstrategies.h - standardviewitems.cpp - standardviewitems.h - standardviewmodelcontrollers.cpp - standardviewmodelcontrollers.h - topitemsviewmodel.cpp - topitemsviewmodel.h - viewitem.cpp - viewitem.h - viewmodel.cpp - viewmodel.h - viewmodelbase.cpp - viewmodelbase.h - viewmodelcontroller.cpp - viewmodelcontroller.h - viewmodeldelegate.cpp - viewmodeldelegate.h - viewmodelutils.cpp - viewmodelutils.h -) diff --git a/mvvm/viewmodel/mvvm/viewmodel/defaultcelldecorator.cpp b/mvvm/viewmodel/mvvm/viewmodel/defaultcelldecorator.cpp deleted file mode 100644 index e6f5d327357965929a021756a07546d4fa975eb6..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/viewmodel/defaultcelldecorator.cpp +++ /dev/null @@ -1,66 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/viewmodel/defaultcelldecorator.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/viewmodel/defaultcelldecorator.h" -#include "mvvm/editors/editor_constants.h" -#include "mvvm/editors/scientificspinbox.h" -#include "mvvm/model/comboproperty.h" -#include "mvvm/model/customvariants.h" -#include "mvvm/model/externalproperty.h" -#include <QModelIndex> -#include <QStyleOptionViewItem> - -using namespace ModelView; - -bool DefaultCellDecorator::hasCustomDecoration(const QModelIndex& index) const -{ - return cellText(index).has_value(); -} - -std::optional<std::string> DefaultCellDecorator::cellText(const QModelIndex& index) const -{ - auto variant = index.data(); - - if (Utils::IsComboVariant(variant)) - return std::optional<std::string>{variant.value<ComboProperty>().label()}; - - else if (Utils::IsBoolVariant(variant)) - return variant.value<bool>() ? std::optional<std::string>{"True"} - : std::optional<std::string>{"False"}; - - else if (Utils::IsExtPropertyVariant(variant)) - return std::optional<std::string>{variant.value<ExternalProperty>().text()}; - - else if (Utils::IsColorVariant(variant)) - return std::optional<std::string>{""}; - - else if (Utils::IsDoubleVariant(variant)) - return std::optional<std::string>{ - ScientificSpinBox::toString(index.data(Qt::EditRole).value<double>(), - GUI::Constants::default_double_decimals) - .toStdString()}; - - return {}; -} - -void DefaultCellDecorator::initStyleOption(QStyleOptionViewItem* option, const QModelIndex& index) -{ - if (!hasCustomDecoration(index)) - return; - - auto value = cellText(index).value(); - option->text = QString::fromStdString(value); - if (value.empty()) - option->features &= ~QStyleOptionViewItem::HasDisplay; -} diff --git a/mvvm/viewmodel/mvvm/viewmodel/defaultcelldecorator.h b/mvvm/viewmodel/mvvm/viewmodel/defaultcelldecorator.h deleted file mode 100644 index d6ba584cdce93a647bf1a987f4d9edee45830be8..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/viewmodel/defaultcelldecorator.h +++ /dev/null @@ -1,36 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/viewmodel/defaultcelldecorator.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEWMODEL_MVVM_VIEWMODEL_DEFAULTCELLDECORATOR_H -#define BORNAGAIN_MVVM_VIEWMODEL_MVVM_VIEWMODEL_DEFAULTCELLDECORATOR_H - -#include "mvvm/interfaces/celldecoratorinterface.h" -#include <optional> - -namespace ModelView { - -//! Generates default cell decorations for Qt trees and tables. - -class MVVM_VIEWMODEL_EXPORT DefaultCellDecorator : public CellDecoratorInterface { -public: - bool hasCustomDecoration(const QModelIndex& index) const override; - void initStyleOption(QStyleOptionViewItem* option, const QModelIndex& index) override; - -protected: - virtual std::optional<std::string> cellText(const QModelIndex& index) const; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEWMODEL_MVVM_VIEWMODEL_DEFAULTCELLDECORATOR_H diff --git a/mvvm/viewmodel/mvvm/viewmodel/defaultviewmodel.cpp b/mvvm/viewmodel/mvvm/viewmodel/defaultviewmodel.cpp deleted file mode 100644 index b0e082d80b6efec3f4e87ca5d91293ffca132a80..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/viewmodel/defaultviewmodel.cpp +++ /dev/null @@ -1,23 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/viewmodel/defaultviewmodel.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/viewmodel/defaultviewmodel.h" -#include "mvvm/viewmodel/standardviewmodelcontrollers.h" - -using namespace ModelView; - -DefaultViewModel::DefaultViewModel(SessionModel* model, QObject* parent) - : ViewModel(std::make_unique<DefaultViewModelController>(model, this), parent) -{ -} diff --git a/mvvm/viewmodel/mvvm/viewmodel/defaultviewmodel.h b/mvvm/viewmodel/mvvm/viewmodel/defaultviewmodel.h deleted file mode 100644 index d96b977dc7026a4173e6bb814e8c7fe0c060a8c7..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/viewmodel/defaultviewmodel.h +++ /dev/null @@ -1,35 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/viewmodel/defaultviewmodel.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEWMODEL_MVVM_VIEWMODEL_DEFAULTVIEWMODEL_H -#define BORNAGAIN_MVVM_VIEWMODEL_MVVM_VIEWMODEL_DEFAULTVIEWMODEL_H - -#include "mvvm/viewmodel/viewmodel.h" - -namespace ModelView { - -//! View model to show content of SessionModel in Qt widgets: two column tree with label/data. - -//! Provides two column tree with label/data, with one-to-one child/parent -//! correspondence as in the original SessionModel. - -class MVVM_VIEWMODEL_EXPORT DefaultViewModel : public ViewModel { - Q_OBJECT -public: - DefaultViewModel(SessionModel* model, QObject* parent = nullptr); -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEWMODEL_MVVM_VIEWMODEL_DEFAULTVIEWMODEL_H diff --git a/mvvm/viewmodel/mvvm/viewmodel/labeldatarowstrategy.cpp b/mvvm/viewmodel/mvvm/viewmodel/labeldatarowstrategy.cpp deleted file mode 100644 index b7db7e4521c2bf74c183d96ee29c1ca04b94a6cb..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/viewmodel/labeldatarowstrategy.cpp +++ /dev/null @@ -1,41 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/viewmodel/labeldatarowstrategy.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/viewmodel/labeldatarowstrategy.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/viewmodel/standardviewitems.h" - -using namespace ModelView; - -//! Example: -//! For LayerItem two items will be generated: ViewLabelItem and ViewEmptyItem, both uneditable. -//! For LayerItem's thickness property, two items will be generated: ViewLabelItem and ViewDataItem. - -QStringList LabelDataRowStrategy::horizontalHeaderLabels() const -{ - return QStringList() << "Name" - << "Value"; -} - -std::vector<std::unique_ptr<ViewItem>> LabelDataRowStrategy::constructRow(SessionItem* item) -{ - std::vector<std::unique_ptr<ViewItem>> result; - - if (!item) - return result; - - result.emplace_back(std::make_unique<ViewLabelItem>(item)); - result.emplace_back(std::make_unique<ViewDataItem>(item)); - return result; -} diff --git a/mvvm/viewmodel/mvvm/viewmodel/labeldatarowstrategy.h b/mvvm/viewmodel/mvvm/viewmodel/labeldatarowstrategy.h deleted file mode 100644 index a04f2493d28b63dca9c3b2a66e31435583c66c00..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/viewmodel/labeldatarowstrategy.h +++ /dev/null @@ -1,39 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/viewmodel/labeldatarowstrategy.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEWMODEL_MVVM_VIEWMODEL_LABELDATAROWSTRATEGY_H -#define BORNAGAIN_MVVM_VIEWMODEL_MVVM_VIEWMODEL_LABELDATAROWSTRATEGY_H - -#include "mvvm/interfaces/rowstrategyinterface.h" - -class QStandardItem; - -namespace ModelView { - -class SessionItem; - -//! Constructs row of QStandardItem's for given SessionItem. -//! Row consists of two columns, ViewLabelItem for SessionItem's display role and -//! ViewDataItem for Session's item data role. - -class MVVM_VIEWMODEL_EXPORT LabelDataRowStrategy : public RowStrategyInterface { -public: - QStringList horizontalHeaderLabels() const override; - - std::vector<std::unique_ptr<ViewItem>> constructRow(SessionItem*) override; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEWMODEL_MVVM_VIEWMODEL_LABELDATAROWSTRATEGY_H diff --git a/mvvm/viewmodel/mvvm/viewmodel/propertiesrowstrategy.cpp b/mvvm/viewmodel/mvvm/viewmodel/propertiesrowstrategy.cpp deleted file mode 100644 index 42908cffd515a0cd1e95a58395447600a95b791b..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/viewmodel/propertiesrowstrategy.cpp +++ /dev/null @@ -1,65 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/viewmodel/propertiesrowstrategy.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/viewmodel/propertiesrowstrategy.h" -#include "mvvm/model/itemutils.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/viewmodel/standardviewitems.h" - -using namespace ModelView; - -PropertiesRowStrategy::PropertiesRowStrategy(std::vector<std::string> labels) - : user_defined_column_labels(std::move(labels)) -{ -} - -QStringList PropertiesRowStrategy::horizontalHeaderLabels() const -{ - QStringList result; - auto labels = - user_defined_column_labels.empty() ? current_column_labels : user_defined_column_labels; - std::transform(labels.begin(), labels.end(), std::back_inserter(result), - [](const std::string& str) { return QString::fromStdString(str); }); - return result; -} - -std::vector<std::unique_ptr<ViewItem>> PropertiesRowStrategy::constructRow(SessionItem* item) -{ - std::vector<std::unique_ptr<ViewItem>> result; - - if (!item) - return result; - - auto items_in_row = Utils::SinglePropertyItems(*item); - if (user_defined_column_labels.empty()) - update_column_labels(items_in_row); - - for (auto child : items_in_row) { - if (child->hasData()) - result.emplace_back(std::make_unique<ViewDataItem>(child)); - else - result.emplace_back(std::make_unique<ViewLabelItem>(child)); - } - - return result; -} - -//! Updates current column labels. - -void PropertiesRowStrategy::update_column_labels(std::vector<SessionItem*> items) -{ - current_column_labels.clear(); - std::transform(items.begin(), items.end(), std::back_inserter(current_column_labels), - [](const SessionItem* item) { return item->displayName(); }); -} diff --git a/mvvm/viewmodel/mvvm/viewmodel/propertiesrowstrategy.h b/mvvm/viewmodel/mvvm/viewmodel/propertiesrowstrategy.h deleted file mode 100644 index 047ca906e36f1240ec63f8aa9322ea5f35445a3f..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/viewmodel/propertiesrowstrategy.h +++ /dev/null @@ -1,45 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/viewmodel/propertiesrowstrategy.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEWMODEL_MVVM_VIEWMODEL_PROPERTIESROWSTRATEGY_H -#define BORNAGAIN_MVVM_VIEWMODEL_MVVM_VIEWMODEL_PROPERTIESROWSTRATEGY_H - -#include "mvvm/interfaces/rowstrategyinterface.h" - -class QStandardItem; - -namespace ModelView { - -class SessionItem; - -//! Constructs row of QStandardItem's for given SessionItem. -//! Row consists of columns with all PropertyItem's of given SessionItem. - -class MVVM_VIEWMODEL_EXPORT PropertiesRowStrategy : public RowStrategyInterface { -public: - PropertiesRowStrategy(std::vector<std::string> labels = {}); - - QStringList horizontalHeaderLabels() const override; - - std::vector<std::unique_ptr<ViewItem>> constructRow(SessionItem* item) override; - -private: - void update_column_labels(std::vector<ModelView::SessionItem*> items); - std::vector<std::string> current_column_labels; - std::vector<std::string> user_defined_column_labels; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEWMODEL_MVVM_VIEWMODEL_PROPERTIESROWSTRATEGY_H diff --git a/mvvm/viewmodel/mvvm/viewmodel/propertyflatviewmodel.cpp b/mvvm/viewmodel/mvvm/viewmodel/propertyflatviewmodel.cpp deleted file mode 100644 index 4054f47ab31a7de92923a069fc1c924f3ec13de3..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/viewmodel/propertyflatviewmodel.cpp +++ /dev/null @@ -1,23 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/viewmodel/propertyflatviewmodel.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/viewmodel/propertyflatviewmodel.h" -#include "mvvm/viewmodel/standardviewmodelcontrollers.h" - -using namespace ModelView; - -PropertyFlatViewModel::PropertyFlatViewModel(SessionModel* model, QObject* parent) - : ViewModel(std::make_unique<PropertyFlatViewModelController>(model, this), parent) -{ -} diff --git a/mvvm/viewmodel/mvvm/viewmodel/propertyflatviewmodel.h b/mvvm/viewmodel/mvvm/viewmodel/propertyflatviewmodel.h deleted file mode 100644 index 1bcd27827d6252201119444ce15fadd1d8755eca..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/viewmodel/propertyflatviewmodel.h +++ /dev/null @@ -1,33 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/viewmodel/propertyflatviewmodel.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEWMODEL_MVVM_VIEWMODEL_PROPERTYFLATVIEWMODEL_H -#define BORNAGAIN_MVVM_VIEWMODEL_MVVM_VIEWMODEL_PROPERTYFLATVIEWMODEL_H - -#include "mvvm/viewmodel/viewmodel.h" - -namespace ModelView { - -//! View model to show content of SessionModel in Qt widgets. -//! Only property items are shown, also hides inactive items of GroupProperty. - -class MVVM_VIEWMODEL_EXPORT PropertyFlatViewModel : public ViewModel { - Q_OBJECT -public: - PropertyFlatViewModel(SessionModel* model, QObject* parent = nullptr); -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEWMODEL_MVVM_VIEWMODEL_PROPERTYFLATVIEWMODEL_H diff --git a/mvvm/viewmodel/mvvm/viewmodel/propertytableviewmodel.cpp b/mvvm/viewmodel/mvvm/viewmodel/propertytableviewmodel.cpp deleted file mode 100644 index dedbb8a0ee581ca0ffeaf161892d5989eacd2796..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/viewmodel/propertytableviewmodel.cpp +++ /dev/null @@ -1,23 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/viewmodel/propertytableviewmodel.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/viewmodel/propertytableviewmodel.h" -#include "mvvm/viewmodel/standardviewmodelcontrollers.h" - -using namespace ModelView; - -PropertyTableViewModel::PropertyTableViewModel(SessionModel* model, QObject* parent) - : ViewModel(std::make_unique<PropertyTableViewModelController>(model, this), parent) -{ -} diff --git a/mvvm/viewmodel/mvvm/viewmodel/propertytableviewmodel.h b/mvvm/viewmodel/mvvm/viewmodel/propertytableviewmodel.h deleted file mode 100644 index 8bcd5af6a189a083eaf71b9c28669a1ff80b17bf..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/viewmodel/propertytableviewmodel.h +++ /dev/null @@ -1,35 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/viewmodel/propertytableviewmodel.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEWMODEL_MVVM_VIEWMODEL_PROPERTYTABLEVIEWMODEL_H -#define BORNAGAIN_MVVM_VIEWMODEL_MVVM_VIEWMODEL_PROPERTYTABLEVIEWMODEL_H - -#include "mvvm/viewmodel/viewmodel.h" - -namespace ModelView { - -//! View model to show content of SessionModel in Qt widgets: all item properties as a table row. - -//! Intended to show registered properties of items in table-like view. -//! Registered properties will form columns of the table, top level items will form table rows. - -class MVVM_VIEWMODEL_EXPORT PropertyTableViewModel : public ViewModel { - Q_OBJECT -public: - PropertyTableViewModel(SessionModel* model, QObject* parent = nullptr); -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEWMODEL_MVVM_VIEWMODEL_PROPERTYTABLEVIEWMODEL_H diff --git a/mvvm/viewmodel/mvvm/viewmodel/propertyviewmodel.cpp b/mvvm/viewmodel/mvvm/viewmodel/propertyviewmodel.cpp deleted file mode 100644 index 5125ac678b5f48222d02e210eb6007f2bb235d56..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/viewmodel/propertyviewmodel.cpp +++ /dev/null @@ -1,23 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/viewmodel/propertyviewmodel.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/viewmodel/propertyviewmodel.h" -#include "mvvm/viewmodel/standardviewmodelcontrollers.h" - -using namespace ModelView; - -PropertyViewModel::PropertyViewModel(SessionModel* model, QObject* parent) - : ViewModel(std::make_unique<PropertyViewModelController>(model, this), parent) -{ -} diff --git a/mvvm/viewmodel/mvvm/viewmodel/propertyviewmodel.h b/mvvm/viewmodel/mvvm/viewmodel/propertyviewmodel.h deleted file mode 100644 index 8282f3886c5ec9b0f18860267de81f66cbb1fe67..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/viewmodel/propertyviewmodel.h +++ /dev/null @@ -1,33 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/viewmodel/propertyviewmodel.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEWMODEL_MVVM_VIEWMODEL_PROPERTYVIEWMODEL_H -#define BORNAGAIN_MVVM_VIEWMODEL_MVVM_VIEWMODEL_PROPERTYVIEWMODEL_H - -#include "mvvm/viewmodel/viewmodel.h" - -namespace ModelView { - -//! View model to show content of SessionModel in Qt widgets. -//! Only property items are shown, also hides inactive items of GroupProperty. - -class MVVM_VIEWMODEL_EXPORT PropertyViewModel : public ViewModel { - Q_OBJECT -public: - PropertyViewModel(SessionModel* model, QObject* parent = nullptr); -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEWMODEL_MVVM_VIEWMODEL_PROPERTYVIEWMODEL_H diff --git a/mvvm/viewmodel/mvvm/viewmodel/standardchildrenstrategies.cpp b/mvvm/viewmodel/mvvm/viewmodel/standardchildrenstrategies.cpp deleted file mode 100644 index eadbbf17ded6801e78068029a0ee7e63a6b971c0..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/viewmodel/standardchildrenstrategies.cpp +++ /dev/null @@ -1,103 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/viewmodel/standardchildrenstrategies.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/viewmodel/standardchildrenstrategies.h" -#include "mvvm/model/groupitem.h" -#include "mvvm/model/itemutils.h" - -using namespace ModelView; - -// ---------------------------------------------------------------------------- - -std::vector<SessionItem*> AllChildrenStrategy::children(const SessionItem* item) const -{ - return item ? item->children() : std::vector<SessionItem*>(); -} - -std::vector<SessionItem*> TopItemsStrategy::children(const SessionItem* item) const -{ - return item ? Utils::TopLevelItems(*item) : std::vector<SessionItem*>(); -} - -// ---------------------------------------------------------------------------- - -/* -PropertyItemsStrategy example: if group property has Cylinder active: - -Particle - ShapeGroup - Sphere - Radius - Cylinder - Height - Radius - -will become: -Particle - ShapeGroup -> Cylinder - Height - Radius -*/ - -std::vector<SessionItem*> PropertyItemsStrategy::children(const SessionItem* item) const -{ - if (!item) - return std::vector<SessionItem*>(); - - auto group = dynamic_cast<const GroupItem*>(item); - auto next_item = group ? group->currentItem() : item; - return Utils::SinglePropertyItems(*next_item); -} - -// ---------------------------------------------------------------------------- - -/* -PropertyItemsFlatStrategy example: if group property has Cylinder active: - -Particle - ShapeGroup - Sphere - Radius - Cylinder - Height - Radius - -will become: -Particle - ShapeGroup -> Cylinder - Height - Radius -*/ - -std::vector<SessionItem*> PropertyItemsFlatStrategy::children(const SessionItem* item) const -{ - if (!item) - return std::vector<SessionItem*>(); - - if (auto group = dynamic_cast<const GroupItem*>(item); group) - return Utils::SinglePropertyItems(*group->currentItem()); - - std::vector<SessionItem*> result; - for (auto child : Utils::SinglePropertyItems(*item)) { - if (auto group_item = dynamic_cast<GroupItem*>(child); group_item) { - result.push_back(group_item); - for (auto sub_property : Utils::SinglePropertyItems(*group_item->currentItem())) - result.push_back(sub_property); - } else { - result.push_back(child); - } - } - - return result; -} diff --git a/mvvm/viewmodel/mvvm/viewmodel/standardchildrenstrategies.h b/mvvm/viewmodel/mvvm/viewmodel/standardchildrenstrategies.h deleted file mode 100644 index 74cdeb7e4d07662403740f05f62910d52d6cc1ae..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/viewmodel/standardchildrenstrategies.h +++ /dev/null @@ -1,63 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/viewmodel/standardchildrenstrategies.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEWMODEL_MVVM_VIEWMODEL_STANDARDCHILDRENSTRATEGIES_H -#define BORNAGAIN_MVVM_VIEWMODEL_MVVM_VIEWMODEL_STANDARDCHILDRENSTRATEGIES_H - -//! @file mvvm/viewmodel/mvvm/viewmodel/standardchildrenstrategies.h -//! @brief Collection of strategies to find children, actual of fictional, of given SessionItem. -//! Used for ViewModel generation when underlying SessionModel changes its layout. - -#include "mvvm/interfaces/childrenstrategyinterface.h" - -namespace ModelView { - -class SessionItem; - -//! Strategy to find children of given item: gives all actual children back. - -class MVVM_VIEWMODEL_EXPORT AllChildrenStrategy : public ChildrenStrategyInterface { -public: - std::vector<SessionItem*> children(const SessionItem* item) const override; -}; - -//! Strategy to find children of given item: only top level items will be given, all -//! property items will be filtered out. - -class MVVM_VIEWMODEL_EXPORT TopItemsStrategy : public ChildrenStrategyInterface { -public: - std::vector<SessionItem*> children(const SessionItem* item) const override; -}; - -//! Strategy to find children of given item: only property item will be given, all top level items -//! will be filtered out, all inactive children of GroupItem will be filtered out. See example -//! in code. - -class MVVM_VIEWMODEL_EXPORT PropertyItemsStrategy : public ChildrenStrategyInterface { -public: - std::vector<SessionItem*> children(const SessionItem* item) const override; -}; - -//! Strategy to find children of given item: flat alignment. -//! Acts as PropertyItemStrategy, with the difference that active subproperties of -//! GroupItem are moved to the same parent, as GroupItem itself. See example in code. - -class MVVM_VIEWMODEL_EXPORT PropertyItemsFlatStrategy : public ChildrenStrategyInterface { -public: - std::vector<SessionItem*> children(const SessionItem* item) const override; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEWMODEL_MVVM_VIEWMODEL_STANDARDCHILDRENSTRATEGIES_H diff --git a/mvvm/viewmodel/mvvm/viewmodel/standardviewitems.cpp b/mvvm/viewmodel/mvvm/viewmodel/standardviewitems.cpp deleted file mode 100644 index 9d022a7f622d4a3279a466e8fd371cbab7dcad40..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/viewmodel/standardviewitems.cpp +++ /dev/null @@ -1,67 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/viewmodel/standardviewitems.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/viewmodel/standardviewitems.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/viewmodel/viewmodelutils.h" - -using namespace ModelView; - -RootViewItem::RootViewItem(SessionItem* item) : ViewItem(item, ItemDataRole::DATA) {} - -//! --------------------------------------------------------------------------- - -ViewLabelItem::ViewLabelItem(SessionItem* item) : ViewItem(item, ItemDataRole::DISPLAY) {} - -QVariant ViewLabelItem::data(int role) const -{ - if (!item()) - return QVariant(); - - // use item's display role - if (role == Qt::DisplayRole || role == Qt::EditRole) - return QString::fromStdString(item()->displayName()); - - return ViewItem::data(role); -} - -//! --------------------------------------------------------------------------- - -ViewDataItem::ViewDataItem(SessionItem* item) : ViewItem(item, ItemDataRole::DATA) {} - -Qt::ItemFlags ViewDataItem::flags() const -{ - Qt::ItemFlags result = ViewItem::flags(); - if (item() && item()->isEditable() && item()->isEnabled() && item()->data<QVariant>().isValid()) - result |= Qt::ItemIsEditable; - - return result; -} - -QVariant ViewDataItem::data(int role) const -{ - if (role == Qt::DecorationRole) - return Utils::DecorationRole(*item()); - else if (role == Qt::CheckStateRole) - return Utils::CheckStateRole(*item()); - - return ViewItem::data(role); -} - -ViewEmptyItem::ViewEmptyItem() : ViewItem(nullptr, 0) {} - -QVariant ViewEmptyItem::data(int) const -{ - return QVariant(); -} diff --git a/mvvm/viewmodel/mvvm/viewmodel/standardviewitems.h b/mvvm/viewmodel/mvvm/viewmodel/standardviewitems.h deleted file mode 100644 index 79a4688ca32f978ad93fe3415e15c57e4f265745..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/viewmodel/standardviewitems.h +++ /dev/null @@ -1,61 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/viewmodel/standardviewitems.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEWMODEL_MVVM_VIEWMODEL_STANDARDVIEWITEMS_H -#define BORNAGAIN_MVVM_VIEWMODEL_MVVM_VIEWMODEL_STANDARDVIEWITEMS_H - -#include "mvvm/viewmodel/viewitem.h" - -namespace ModelView { - -class SessionItem; - -//! Represents root item. - -class MVVM_VIEWMODEL_EXPORT RootViewItem : public ViewItem { -public: - explicit RootViewItem(SessionItem* item); -}; - -//! Represents empty cell of tree or table. - -class MVVM_VIEWMODEL_EXPORT ViewEmptyItem : public ViewItem { -public: - ViewEmptyItem(); - QVariant data(int role) const override; -}; - -//! Represents display name of SessionItem in any cell of Qt's trees and tables. - -class MVVM_VIEWMODEL_EXPORT ViewLabelItem : public ViewItem { -public: - explicit ViewLabelItem(SessionItem* item); - - QVariant data(int role) const override; -}; - -//! Represents data role of SessionItem in any cell of Qt's trees and tables. - -class MVVM_VIEWMODEL_EXPORT ViewDataItem : public ViewItem { -public: - explicit ViewDataItem(SessionItem* item); - - Qt::ItemFlags flags() const override; - - QVariant data(int role) const override; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEWMODEL_MVVM_VIEWMODEL_STANDARDVIEWITEMS_H diff --git a/mvvm/viewmodel/mvvm/viewmodel/standardviewmodelcontrollers.cpp b/mvvm/viewmodel/mvvm/viewmodel/standardviewmodelcontrollers.cpp deleted file mode 100644 index a6a8d57cb7eab2b87370f67763cd47cd2487ece8..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/viewmodel/standardviewmodelcontrollers.cpp +++ /dev/null @@ -1,92 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/viewmodel/standardviewmodelcontrollers.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/viewmodel/standardviewmodelcontrollers.h" -#include "mvvm/model/groupitem.h" -#include "mvvm/viewmodel/labeldatarowstrategy.h" -#include "mvvm/viewmodel/propertiesrowstrategy.h" -#include "mvvm/viewmodel/standardchildrenstrategies.h" -#include "mvvm/viewmodel/standardviewitems.h" - -using namespace ModelView; - -// ---------------------------------------------------------------------------- - -DefaultViewModelController::DefaultViewModelController(SessionModel* session_model, - ViewModelBase* view_model) - : ViewModelController(session_model, view_model) -{ - setChildrenStrategy(std::make_unique<AllChildrenStrategy>()); - setRowStrategy(std::make_unique<LabelDataRowStrategy>()); -} - -// ---------------------------------------------------------------------------- - -TopItemsViewModelController::TopItemsViewModelController(SessionModel* session_model, - ViewModelBase* view_model) - : ViewModelController(session_model, view_model) -{ - setChildrenStrategy(std::make_unique<TopItemsStrategy>()); - setRowStrategy(std::make_unique<LabelDataRowStrategy>()); -} - -// ---------------------------------------------------------------------------- - -PropertyViewModelController::PropertyViewModelController(SessionModel* session_model, - ViewModelBase* view_model) - : ViewModelController(session_model, view_model) -{ - setChildrenStrategy(std::make_unique<PropertyItemsStrategy>()); - setRowStrategy(std::make_unique<LabelDataRowStrategy>()); -} - -void PropertyViewModelController::onDataChange(SessionItem* item, int role) -{ - ViewModelController::onDataChange(item, role); - // If data change occured with GroupItem, performs cleanup and regeneration of - // ViewItems, corresponding to groupItem's current index. - if (auto group = dynamic_cast<GroupItem*>(item)) - update_branch(group); -} - -// ---------------------------------------------------------------------------- - -// FIXME What to do with group property? - -PropertyTableViewModelController::PropertyTableViewModelController( - SessionModel* session_model, ViewModelBase* view_model, const std::vector<std::string>& labels) - : ViewModelController(session_model, view_model) -{ - setChildrenStrategy(std::make_unique<TopItemsStrategy>()); - setRowStrategy(std::make_unique<PropertiesRowStrategy>(labels)); -} - -// ---------------------------------------------------------------------------- - -PropertyFlatViewModelController::PropertyFlatViewModelController(SessionModel* session_model, - ViewModelBase* view_model) - : ViewModelController(session_model, view_model) -{ - setChildrenStrategy(std::make_unique<PropertyItemsFlatStrategy>()); - setRowStrategy(std::make_unique<LabelDataRowStrategy>()); -} - -void PropertyFlatViewModelController::onDataChange(SessionItem* item, int role) -{ - ViewModelController::onDataChange(item, role); - // If data change occured with GroupItem, performs cleanup and regeneration of - // ViewItems, corresponding to groupItem's current index. - if (auto group = dynamic_cast<GroupItem*>(item)) - update_branch(group->parent()); -} diff --git a/mvvm/viewmodel/mvvm/viewmodel/standardviewmodelcontrollers.h b/mvvm/viewmodel/mvvm/viewmodel/standardviewmodelcontrollers.h deleted file mode 100644 index eb3ed4b5dead552e10de02f49bd847cc9d4c6ada..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/viewmodel/standardviewmodelcontrollers.h +++ /dev/null @@ -1,79 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/viewmodel/standardviewmodelcontrollers.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEWMODEL_MVVM_VIEWMODEL_STANDARDVIEWMODELCONTROLLERS_H -#define BORNAGAIN_MVVM_VIEWMODEL_MVVM_VIEWMODEL_STANDARDVIEWMODELCONTROLLERS_H - -#include "mvvm/viewmodel/viewmodel.h" -#include "mvvm/viewmodel/viewmodelcontroller.h" -#include <string> -#include <vector> - -//! @file mvvm/viewmodel/mvvm/viewmodel/standardviewmodelcontrollers.h -//! Collection of standard controllers for AbstractViewModel. - -namespace ModelView { - -//! Controller for AbstractViewModel to show all items of SessionModel. -//! The layout corresponds to original SessionModel, generates standard label/value tree. - -class MVVM_VIEWMODEL_EXPORT DefaultViewModelController : public ViewModelController { -public: - explicit DefaultViewModelController(SessionModel* session_model, ViewModelBase* view_model); -}; - -//! Controller for AbstractViewModel to show top level items. -//! Shows only top level items, property items, group items are hidden. - -class MVVM_VIEWMODEL_EXPORT TopItemsViewModelController : public ViewModelController { -public: - explicit TopItemsViewModelController(SessionModel* session_model, ViewModelBase* view_model); -}; - -//! Controller for AbstractViewModel to show item properties. -//! Shows property items, hides top level items, hides inactive items of GroupProperty. - -class MVVM_VIEWMODEL_EXPORT PropertyViewModelController : public ViewModelController { -public: - explicit PropertyViewModelController(SessionModel* session_model, ViewModelBase* view_model); - -protected: - void onDataChange(SessionItem* item, int role) override; -}; - -//! Controller for AbstractViewModel to show item properties in table layout. -//! Shows all property items and place them in table columns. - -class MVVM_VIEWMODEL_EXPORT PropertyTableViewModelController : public ViewModelController { -public: - PropertyTableViewModelController(SessionModel* session_model, ViewModelBase* view_model, - const std::vector<std::string>& labels = {}); -}; - -//! Controller for AbstractViewModel to show item properties. -//! Shows property items, hides top level items, hides inactive items of GroupProperty, -//! moves subproperties of group item under parent of group item. - -class MVVM_VIEWMODEL_EXPORT PropertyFlatViewModelController : public ViewModelController { -public: - explicit PropertyFlatViewModelController(SessionModel* session_model, - ViewModelBase* view_model); - -protected: - void onDataChange(SessionItem* item, int role) override; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEWMODEL_MVVM_VIEWMODEL_STANDARDVIEWMODELCONTROLLERS_H diff --git a/mvvm/viewmodel/mvvm/viewmodel/topitemsviewmodel.cpp b/mvvm/viewmodel/mvvm/viewmodel/topitemsviewmodel.cpp deleted file mode 100644 index ff664764adb3331d8e6be2acf1c359f06649917d..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/viewmodel/topitemsviewmodel.cpp +++ /dev/null @@ -1,23 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/viewmodel/topitemsviewmodel.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/viewmodel/topitemsviewmodel.h" -#include "mvvm/viewmodel/standardviewmodelcontrollers.h" - -using namespace ModelView; - -TopItemsViewModel::TopItemsViewModel(SessionModel* model, QObject* parent) - : ViewModel(std::make_unique<TopItemsViewModelController>(model, this), parent) -{ -} diff --git a/mvvm/viewmodel/mvvm/viewmodel/topitemsviewmodel.h b/mvvm/viewmodel/mvvm/viewmodel/topitemsviewmodel.h deleted file mode 100644 index c86035b606454ece1326ec66a6f1de0f84f5e4f7..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/viewmodel/topitemsviewmodel.h +++ /dev/null @@ -1,34 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/viewmodel/topitemsviewmodel.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEWMODEL_MVVM_VIEWMODEL_TOPITEMSVIEWMODEL_H -#define BORNAGAIN_MVVM_VIEWMODEL_MVVM_VIEWMODEL_TOPITEMSVIEWMODEL_H - -#include "mvvm/viewmodel/viewmodel.h" - -namespace ModelView { - -//! View model to show top level items of SessionModel in Qt trees and tables. -//! All property items (i.e. "thickness", "color" etc) will be filtered out, top level items -//! (i.e. Layer, MultiLayer, ...) will be presented as simple parent/child tree. - -class MVVM_VIEWMODEL_EXPORT TopItemsViewModel : public ViewModel { - Q_OBJECT -public: - TopItemsViewModel(SessionModel* model, QObject* parent = nullptr); -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEWMODEL_MVVM_VIEWMODEL_TOPITEMSVIEWMODEL_H diff --git a/mvvm/viewmodel/mvvm/viewmodel/viewitem.cpp b/mvvm/viewmodel/mvvm/viewmodel/viewitem.cpp deleted file mode 100644 index 16f30edac2d0503142cdd35da2fbbeec0e933ac0..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/viewmodel/viewitem.cpp +++ /dev/null @@ -1,245 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/viewmodel/viewitem.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/viewmodel/viewitem.h" -#include "mvvm/model/customvariants.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/utils/containerutils.h" -#include "mvvm/viewmodel/viewmodelutils.h" -#include <algorithm> -#include <stdexcept> -#include <vector> - -using namespace ModelView; - -struct ViewItem::ViewItemImpl { - std::vector<std::unique_ptr<ViewItem>> children; //! buffer to hold rows x columns - int rows{0}; - int columns{0}; - SessionItem* item{nullptr}; - int role{0}; - ViewItem* parent_view_item{nullptr}; - ViewItemImpl(SessionItem* item, int role) : item(item), role(role) {} - - void appendRow(std::vector<std::unique_ptr<ViewItem>> items) - { - insertRow(rows, std::move(items)); - } - - void insertRow(int row, std::vector<std::unique_ptr<ViewItem>> items) - { - if (items.empty()) - throw std::runtime_error("Error in ViewItemImpl: attempt to insert empty row"); - - if (columns > 0 && items.size() != static_cast<size_t>(columns)) - throw std::runtime_error("Error in ViewItemImpl: wrong number of columns."); - - if (row < 0 || row > rows) - throw std::runtime_error("Error in ViewItemImpl: invalid row index."); - - children.insert(std::next(children.begin(), row * columns), - std::make_move_iterator(items.begin()), - std::make_move_iterator(items.end())); - - columns = static_cast<int>(items.size()); - ++rows; - } - - void removeRow(int row) - { - if (row < 0 || row >= rows) - throw std::runtime_error("Error in RefViewItem: invalid row index."); - - auto begin = std::next(children.begin(), row * columns); - auto end = std::next(begin, columns); - children.erase(begin, end); - --rows; - if (rows == 0) - columns = 0; - } - - ViewItem* child(int row, int column) const - { - if (row < 0 || row >= rows) - throw std::runtime_error("Error in RefViewItem: wrong row)"); - - if (column < 0 || column >= columns) - throw std::runtime_error("Error in RefViewItem: wrong column)"); - - return children.at(static_cast<size_t>(column + row * columns)).get(); - } - - ViewItem* parent() { return parent_view_item; } - - int index_of_child(const ViewItem* child) - { - return Utils::IndexOfItem(children.begin(), children.end(), child); - } - - //! Returns item data associated with this RefViewItem. - - QVariant data() const { return item ? item->data<QVariant>(role) : QVariant(); } - - //! Returns vector of children. - - std::vector<ViewItem*> get_children() const - { - std::vector<ViewItem*> result; - std::transform(children.begin(), children.end(), std::back_inserter(result), - [](const auto& x) { return x.get(); }); - return result; - } -}; - -ViewItem::ViewItem(SessionItem* item, int role) : p_impl(std::make_unique<ViewItemImpl>(item, role)) -{ -} - -ViewItem::~ViewItem() = default; - -//! Returns the number of child item rows that the item has. - -int ViewItem::rowCount() const -{ - return p_impl->rows; -} - -//! Returns the number of child item columns that the item has. - -int ViewItem::columnCount() const -{ - return p_impl->columns; -} - -//! Appends a row containing items. Number of items should be the same as columnCount() -//! (if there are already some rows). If it is a first row, then items can be of any size. - -void ViewItem::appendRow(std::vector<std::unique_ptr<ViewItem>> items) -{ - for (auto& x : items) - x->setParent(this); - p_impl->appendRow(std::move(items)); -} - -//! Insert a row of items at index 'row'. - -void ViewItem::insertRow(int row, std::vector<std::unique_ptr<ViewItem>> items) -{ - for (auto& x : items) - x->setParent(this); - p_impl->insertRow(row, std::move(items)); -} - -//! Removes row of items at given 'row'. Items will be deleted. - -void ViewItem::removeRow(int row) -{ - p_impl->removeRow(row); -} - -void ViewItem::clear() -{ - p_impl->children.clear(); - p_impl->rows = 0; - p_impl->columns = 0; -} - -ViewItem* ViewItem::parent() const -{ - return p_impl->parent(); -} - -ViewItem* ViewItem::child(int row, int column) const -{ - return p_impl->child(row, column); -} - -SessionItem* ViewItem::item() const -{ - return p_impl->item; -} - -int ViewItem::item_role() const -{ - return p_impl->role; -} - -//! Returns the row where the item is located in its parent's child table, or -1 if the item has no -//! parent. - -int ViewItem::row() const -{ - auto index = parent() ? parent()->p_impl->index_of_child(this) : -1; - return index >= 0 ? index / parent()->p_impl->columns : -1; -} - -//! Returns the column where the item is located in its parent's child table, or -1 if the item has -//! no parent. - -int ViewItem::column() const -{ - auto index = parent() ? parent()->p_impl->index_of_child(this) : -1; - return index >= 0 ? index % parent()->p_impl->columns : -1; -} - -//! Returns the data for given role according to Qt::ItemDataRole namespace definitions. -//! Converts data and roles from underlying SessionItem to what Qt expects. - -QVariant ViewItem::data(int qt_role) const -{ - if (!p_impl->item) - return QVariant(); - - if (qt_role == Qt::DisplayRole || qt_role == Qt::EditRole) - return Utils::toQtVariant(p_impl->data()); -#if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0) - else if (qt_role == Qt::ForegroundRole) -#else - else if (qt_role == Qt::TextColorRole) -#endif - return Utils::TextColorRole(*p_impl->item); - else if (qt_role == Qt::ToolTipRole) - return Utils::ToolTipRole(*p_impl->item); - else - return QVariant(); -} - -//! Sets the data to underlying SessionItem. -//! Converts data and roles from Qt definitions to what SessionItem expects. - -bool ViewItem::setData(const QVariant& value, int qt_role) -{ - if (p_impl->item && qt_role == Qt::EditRole) - return p_impl->item->setData(Utils::toCustomVariant(value), p_impl->role); - return false; -} - -//! Returns Qt's item flags. -//! Converts internal SessionItem's status enable/disabled/readonly to what Qt expects. - -Qt::ItemFlags ViewItem::flags() const -{ - Qt::ItemFlags result = Qt::ItemIsSelectable | Qt::ItemIsEnabled; - return result; -} - -std::vector<ViewItem*> ViewItem::children() const -{ - return p_impl->get_children(); -} - -void ViewItem::setParent(ViewItem* parent) -{ - p_impl->parent_view_item = parent; -} diff --git a/mvvm/viewmodel/mvvm/viewmodel/viewitem.h b/mvvm/viewmodel/mvvm/viewmodel/viewitem.h deleted file mode 100644 index ddfbf935a9d2f2e913dbcd542fbdba1512b2bf2c..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/viewmodel/viewitem.h +++ /dev/null @@ -1,76 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/viewmodel/viewitem.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEWMODEL_MVVM_VIEWMODEL_VIEWITEM_H -#define BORNAGAIN_MVVM_VIEWMODEL_MVVM_VIEWMODEL_VIEWITEM_H - -#include "mvvm/core/variant.h" -#include "mvvm/viewmodel_export.h" -#include <memory> -#include <vector> - -namespace ModelView { - -class SessionItem; - -//! Represents the view of SessionItem's data in a single cell of ViewModel. - -class MVVM_VIEWMODEL_EXPORT ViewItem { -public: - virtual ~ViewItem(); - - int rowCount() const; - - int columnCount() const; - - void appendRow(std::vector<std::unique_ptr<ViewItem>> items); - - void insertRow(int row, std::vector<std::unique_ptr<ViewItem>> items); - - void removeRow(int row); - - void clear(); - - ViewItem* parent() const; - - ViewItem* child(int row, int column) const; - - SessionItem* item() const; - - int item_role() const; - - int row() const; - - int column() const; - - virtual QVariant data(int qt_role) const; - - virtual bool setData(const QVariant& value, int qt_role); - - virtual Qt::ItemFlags flags() const; - - std::vector<ViewItem*> children() const; - -protected: - ViewItem(SessionItem* item, int role); - void setParent(ViewItem* parent); - -private: - struct ViewItemImpl; - std::unique_ptr<ViewItemImpl> p_impl; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEWMODEL_MVVM_VIEWMODEL_VIEWITEM_H diff --git a/mvvm/viewmodel/mvvm/viewmodel/viewmodel.cpp b/mvvm/viewmodel/mvvm/viewmodel/viewmodel.cpp deleted file mode 100644 index 9a0d907ec40995a049998e876812d9bde71b57c3..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/viewmodel/viewmodel.cpp +++ /dev/null @@ -1,84 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/viewmodel/viewmodel.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/viewmodel/viewmodel.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/viewmodel/standardviewitems.h" -#include "mvvm/viewmodel/viewmodelcontroller.h" - -using namespace ModelView; - -ViewModel::ViewModel(std::unique_ptr<ViewModelController> controller, QObject* parent) - : ViewModelBase(parent), m_controller(std::move(controller)) -{ - m_controller->setViewModel(this); - m_controller->setRootSessionItem(sessionModel()->rootItem()); -} - -QVariant ViewModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if (orientation == Qt::Horizontal && role == Qt::DisplayRole) { - auto data = m_controller->horizontalHeaderLabels(); - if (section < data.size()) - return data.at(section); - } - return QVariant(); -} - -SessionModel* ViewModel::sessionModel() const -{ - return m_controller->sessionModel(); -} - -SessionItem* ViewModel::rootSessionItem() -{ - return m_controller->rootSessionItem(); -} - -ViewModel::~ViewModel() = default; - -void ViewModel::setRootSessionItem(SessionItem* item) -{ - if (!item) - throw std::runtime_error("Error in ViewModel: atttemp to set nulptr as root item"); - m_controller->setRootSessionItem(item); -} - -SessionItem* ViewModel::sessionItemFromIndex(const QModelIndex& index) const -{ - return index.isValid() ? itemFromIndex(index)->item() : m_controller->rootSessionItem(); -} - -ViewItem* ViewModel::viewItemFromIndex(const QModelIndex& index) const -{ - return itemFromIndex(index); -} - -//! Returns list of model indices representing given SessionItem. - -QModelIndexList ViewModel::indexOfSessionItem(const SessionItem* item) const -{ - QModelIndexList result; - for (auto view : m_controller->findViews(item)) - result.push_back(indexFromItem(view)); - return result; -} - -//! Returns vector of all ViewItem's representing given SessionItem. - -std::vector<ViewItem*> ViewModel::findViews(const SessionItem* item) const -{ - return m_controller->findViews(item); -} diff --git a/mvvm/viewmodel/mvvm/viewmodel/viewmodel.h b/mvvm/viewmodel/mvvm/viewmodel/viewmodel.h deleted file mode 100644 index d9e7b3bac1dd18b8eb5d9662a794262359a8233a..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/viewmodel/viewmodel.h +++ /dev/null @@ -1,59 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/viewmodel/viewmodel.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEWMODEL_MVVM_VIEWMODEL_VIEWMODEL_H -#define BORNAGAIN_MVVM_VIEWMODEL_MVVM_VIEWMODEL_VIEWMODEL_H - -#include "mvvm/viewmodel/viewmodelbase.h" - -namespace ModelView { - -class SessionModel; -class SessionItem; -class ViewItem; -class ViewModelController; - -//! Main class to represent content of SessionModel in Qt's trees and tables. - -class MVVM_VIEWMODEL_EXPORT ViewModel : public ViewModelBase { - Q_OBJECT - -public: - ViewModel(std::unique_ptr<ViewModelController> controller, QObject* parent = nullptr); - ~ViewModel() override; - - QVariant headerData(int section, Qt::Orientation orientation, - int role = Qt::DisplayRole) const override; - - SessionModel* sessionModel() const; - - SessionItem* rootSessionItem(); - - void setRootSessionItem(SessionItem* item); - - SessionItem* sessionItemFromIndex(const QModelIndex& index) const; - - ViewItem* viewItemFromIndex(const QModelIndex& index) const; - - QModelIndexList indexOfSessionItem(const SessionItem* item) const; - - std::vector<ViewItem*> findViews(const ModelView::SessionItem* item) const; - -private: - std::unique_ptr<ViewModelController> m_controller; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEWMODEL_MVVM_VIEWMODEL_VIEWMODEL_H diff --git a/mvvm/viewmodel/mvvm/viewmodel/viewmodelbase.cpp b/mvvm/viewmodel/mvvm/viewmodel/viewmodelbase.cpp deleted file mode 100644 index 2a0e3c4840cc93569747adc0a7ec878f6e894d4f..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/viewmodel/viewmodelbase.cpp +++ /dev/null @@ -1,185 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/viewmodel/viewmodelbase.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/viewmodel/viewmodelbase.h" -#include "mvvm/viewmodel/standardviewitems.h" -#include <stdexcept> - -using namespace ModelView; - -struct ViewModelBase::ViewModelBaseImpl { - ViewModelBase* model{nullptr}; - std::unique_ptr<ViewItem> root; - ViewModelBaseImpl(ViewModelBase* model) : model(model) {} - - bool item_belongs_to_model(ViewItem* item) - { - return model->indexFromItem(item).isValid() || item == model->rootItem(); - } -}; - -ViewModelBase::ViewModelBase(QObject* parent) - : QAbstractItemModel(parent), p_impl(std::make_unique<ViewModelBaseImpl>(this)) -{ - beginResetModel(); - setRootViewItem(std::make_unique<RootViewItem>(nullptr)); - endResetModel(); -} - -ViewModelBase::~ViewModelBase() = default; - -QModelIndex ViewModelBase::index(int row, int column, const QModelIndex& parent) const -{ - auto parent_item = itemFromIndex(parent) ? itemFromIndex(parent) : rootItem(); - const bool is_valid_row = row >= 0 && row < rowCount(parent); - const bool is_valid_column = column >= 0 && column < columnCount(parent); - return is_valid_row && is_valid_column - ? createIndex(row, column, parent_item->child(row, column)) - : QModelIndex(); -} - -QModelIndex ViewModelBase::parent(const QModelIndex& child) const -{ - if (auto child_item = itemFromIndex(child); child_item) { - auto parent_item = child_item->parent(); - return parent_item == rootItem() - ? QModelIndex() - : createIndex(parent_item->row(), parent_item->column(), parent_item); - } - - return QModelIndex(); -} - -int ViewModelBase::rowCount(const QModelIndex& parent) const -{ - auto parent_item = itemFromIndex(parent); - return parent_item ? parent_item->rowCount() : rootItem()->rowCount(); -} - -int ViewModelBase::columnCount(const QModelIndex& parent) const -{ - auto parent_item = itemFromIndex(parent); - return parent_item ? parent_item->columnCount() : rootItem()->columnCount(); -} - -QVariant ViewModelBase::data(const QModelIndex& index, int role) const -{ - if (!rootItem()) - return QVariant(); - - auto item = itemFromIndex(index); - return item ? item->data(role) : QVariant(); -} - -bool ViewModelBase::setData(const QModelIndex& index, const QVariant& value, int role) -{ - if (!index.isValid()) - return false; - - if (auto item = itemFromIndex(index); item) { - bool result = item->setData(value, role); - if (result) - dataChanged(index, index, QVector<int>() << role); - return result; - } - - return false; -} - -//! Returns a pointer to invisible root item. - -ViewItem* ViewModelBase::rootItem() const -{ - return p_impl->root.get(); -} - -//! Returns a pointer to the RefViewItem associated with the given index. -//! If index is invalid, returns nullptr. - -ViewItem* ViewModelBase::itemFromIndex(const QModelIndex& index) const -{ - return index.isValid() ? static_cast<ViewItem*>(index.internalPointer()) : nullptr; -} - -//! Returns the QModelIndex associated with the given item. - -QModelIndex ViewModelBase::indexFromItem(const ViewItem* item) const -{ - return item && item->parent() - ? createIndex(item->row(), item->column(), const_cast<ViewItem*>(item)) - : QModelIndex(); -} - -void ViewModelBase::removeRow(ViewItem* parent, int row) -{ - if (!p_impl->item_belongs_to_model(parent)) - throw std::runtime_error( - "Error in ViewModelBase: attempt to use parent from another model"); - - beginRemoveRows(indexFromItem(parent), row, row); - parent->removeRow(row); - endRemoveRows(); -} - -void ViewModelBase::clearRows(ViewItem* parent) -{ - if (!p_impl->item_belongs_to_model(parent)) - throw std::runtime_error( - "Error in ViewModelBase: attempt to use parent from another model"); - - if (!parent->rowCount()) - return; - - beginRemoveRows(indexFromItem(parent), 0, parent->rowCount() - 1); - parent->clear(); - endRemoveRows(); -} - -//! Insert a row of items at index 'row' to given parent. - -void ViewModelBase::insertRow(ViewItem* parent, int row, - std::vector<std::unique_ptr<ViewItem>> items) -{ - if (!p_impl->item_belongs_to_model(parent)) - throw std::runtime_error( - "Error in ViewModelBase: attempt to use parent from another model"); - - beginInsertRows(indexFromItem(parent), row, row); - parent->insertRow(row, std::move(items)); - endInsertRows(); -} - -//! Appends row of items to given parent. - -void ViewModelBase::appendRow(ViewItem* parent, std::vector<std::unique_ptr<ViewItem>> items) -{ - insertRow(parent, parent->rowCount(), std::move(items)); -} - -//! Returns the item flags for the given index. - -Qt::ItemFlags ViewModelBase::flags(const QModelIndex& index) const -{ - Qt::ItemFlags result = QAbstractItemModel::flags(index); - if (auto item = itemFromIndex(index); item) - result |= item->flags(); - return result; -} - -//! Sets new root item. Previous item will be deleted, model will be reset. - -void ViewModelBase::setRootViewItem(std::unique_ptr<ViewItem> root_item) -{ - p_impl->root = std::move(root_item); -} diff --git a/mvvm/viewmodel/mvvm/viewmodel/viewmodelbase.h b/mvvm/viewmodel/mvvm/viewmodel/viewmodelbase.h deleted file mode 100644 index ef1ba1b60bfdd30c5c87013fc74998fe2bd2422b..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/viewmodel/viewmodelbase.h +++ /dev/null @@ -1,75 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/viewmodel/viewmodelbase.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEWMODEL_MVVM_VIEWMODEL_VIEWMODELBASE_H -#define BORNAGAIN_MVVM_VIEWMODEL_MVVM_VIEWMODEL_VIEWMODELBASE_H - -#include "mvvm/viewmodel_export.h" -#include <QAbstractItemModel> -#include <memory> - -namespace ModelView { - -class ViewItem; - -//! Base class for all view models to show content of SessionModel in Qt views. -//! ViewModelBase is made of ViewItems, where each ViewItem represents some concrete data role -//! of SessionItem. ViewModelBase doesn't have own logic and needs ViewModelController to listen -//! for SessionModel changes. - -class MVVM_VIEWMODEL_EXPORT ViewModelBase : public QAbstractItemModel { - Q_OBJECT -public: - explicit ViewModelBase(QObject* parent = nullptr); - ~ViewModelBase() override; - - QModelIndex index(int row, int column, - const QModelIndex& parent = QModelIndex()) const override; - - QModelIndex parent(const QModelIndex& child) const override; - - int rowCount(const QModelIndex& parent = QModelIndex()) const override; - - int columnCount(const QModelIndex& parent = QModelIndex()) const override; - - QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; - - bool setData(const QModelIndex& index, const QVariant& value, int role) override; - - ViewItem* rootItem() const; - - ViewItem* itemFromIndex(const QModelIndex& index) const; - - QModelIndex indexFromItem(const ViewItem* item) const; - - void removeRow(ViewItem* parent, int row); - - void clearRows(ViewItem* parent); - - void insertRow(ViewItem* parent, int row, std::vector<std::unique_ptr<ViewItem>> items); - - void appendRow(ViewItem* parent, std::vector<std::unique_ptr<ViewItem>> items); - - Qt::ItemFlags flags(const QModelIndex& index) const override; - -private: - void setRootViewItem(std::unique_ptr<ViewItem> root_item); - friend class ViewModelController; - struct ViewModelBaseImpl; - std::unique_ptr<ViewModelBaseImpl> p_impl; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEWMODEL_MVVM_VIEWMODEL_VIEWMODELBASE_H diff --git a/mvvm/viewmodel/mvvm/viewmodel/viewmodelcontroller.cpp b/mvvm/viewmodel/mvvm/viewmodel/viewmodelcontroller.cpp deleted file mode 100644 index 34406baa28464c2ca7d1550260df163fa29218f1..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/viewmodel/viewmodelcontroller.cpp +++ /dev/null @@ -1,308 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/viewmodel/viewmodelcontroller.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/viewmodel/viewmodelcontroller.h" -#include "mvvm/interfaces/childrenstrategyinterface.h" -#include "mvvm/interfaces/rowstrategyinterface.h" -#include "mvvm/model/itemutils.h" -#include "mvvm/model/modelutils.h" -#include "mvvm/model/path.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/model/sessionmodel.h" -#include "mvvm/utils/containerutils.h" -#include "mvvm/viewmodel/standardviewitems.h" -#include "mvvm/viewmodel/viewmodelbase.h" -#include "mvvm/viewmodel/viewmodelutils.h" -#include <map> -#include <stdexcept> - -using namespace ModelView; - -namespace { - -//! Returns true if given SessionItem role is valid for view -bool isValidItemRole(const ViewItem* view, int item_role) -{ - if (view->item_role() == item_role) - return true; - - if (item_role == ItemDataRole::APPEARANCE || item_role == ItemDataRole::TOOLTIP) - return true; - return false; -} - -} // namespace - -struct ViewModelController::ViewModelControllerImpl { - ViewModelController* m_self; - ViewModelBase* m_viewModel{nullptr}; - std::unique_ptr<ChildrenStrategyInterface> m_childrenStrategy; - std::unique_ptr<RowStrategyInterface> m_rowStrategy; - std::map<SessionItem*, ViewItem*> m_itemToVview; //! correspondence of item and its view - Path m_rootItemPath; - - ViewModelControllerImpl(ViewModelController* controller, ViewModelBase* view_model) - : m_self(controller), m_viewModel(view_model) - { - } - - void check_initialization() - { - const std::string msg("Error in ViewModelController: "); - if (!m_viewModel) - throw std::runtime_error(msg + "ViewModel is not defined"); - - if (!m_rowStrategy) - throw std::runtime_error(msg + "RowStrategy is not defined"); - - if (!m_childrenStrategy) - throw std::runtime_error(msg + "Children is not defined"); - } - - void init_view_model() - { - check_initialization(); - m_itemToVview.clear(); - m_itemToVview[m_self->rootSessionItem()] = m_viewModel->rootItem(); - iterate(m_self->rootSessionItem(), m_viewModel->rootItem()); - } - - void iterate(const SessionItem* item, ViewItem* parent) - { - ViewItem* origParent(parent); - for (auto child : m_childrenStrategy->children(item)) { - auto row = m_rowStrategy->constructRow(child); - if (!row.empty()) { - auto next_parent = row.at(0).get(); - m_viewModel->appendRow(parent, std::move(row)); - m_itemToVview[child] = next_parent; - parent = next_parent; // labelItem - iterate(child, parent); - } - parent = origParent; - } - } - - //! Remove row of ViewItem's corresponding to given item. - - void remove_row_of_views(SessionItem* item) - { - auto pos = m_itemToVview.find(item); - if (pos != m_itemToVview.end()) { - auto view = pos->second; - m_viewModel->removeRow(view->parent(), view->row()); - m_itemToVview.erase(pos); - } - } - - void remove_children_of_view(ViewItem* view) - { - for (auto child : view->children()) { - auto pos = std::find_if(m_itemToVview.begin(), m_itemToVview.end(), - [child](const auto& it) { return it.second == child; }); - if (pos != m_itemToVview.end()) - m_itemToVview.erase(pos); - } - - m_viewModel->clearRows(view); - } - - void insert_view(SessionItem* parent, const TagRow& tagrow) - { - auto child = parent->getItem(tagrow.tag, tagrow.row); - auto children = m_childrenStrategy->children(parent); - auto index = Utils::IndexOfItem(children, child); - if (index == -1) - return; - - auto pos = m_itemToVview.find(parent); - if (pos == m_itemToVview.end()) - return; - - auto parent_view = pos->second; - - auto row = m_rowStrategy->constructRow(child); - if (!row.empty()) { - auto next_parent = row.at(0).get(); - m_viewModel->insertRow(parent_view, index, std::move(row)); - m_itemToVview[child] = next_parent; - parent_view = next_parent; // labelItem - iterate(child, parent_view); - } - } - - std::vector<ViewItem*> findViews(const SessionItem* item) const - { - if (item == m_viewModel->rootItem()->item()) - return {m_viewModel->rootItem()}; - - std::vector<ViewItem*> result; - auto on_index = [&](const QModelIndex& index) { - auto view_item = m_viewModel->itemFromIndex(index); - if (view_item->item() == item) - result.push_back(view_item); - }; - Utils::iterate_model(m_viewModel, QModelIndex(), on_index); - return result; - } - - void setRootSessionItemIntern(SessionItem* item) - { - m_rootItemPath = Utils::PathFromItem(item); - m_viewModel->setRootViewItem(std::make_unique<RootViewItem>(item)); - init_view_model(); - } -}; - -ViewModelController::ViewModelController(SessionModel* session_model, ViewModelBase* view_model) - : ModelListener(session_model) - , p_impl(std::make_unique<ViewModelControllerImpl>(this, view_model)) -{ - auto on_data_change = [this](SessionItem* item, int role) { onDataChange(item, role); }; - setOnDataChange(on_data_change); - - auto on_item_inserted = [this](SessionItem* item, TagRow tagrow) { - onItemInserted(item, std::move(tagrow)); - }; - setOnItemInserted(on_item_inserted); - - auto on_item_removed = [this](SessionItem* item, TagRow tagrow) { - onItemRemoved(item, std::move(tagrow)); - }; - setOnItemRemoved(on_item_removed); - - auto on_about_to_remove = [this](SessionItem* item, TagRow tagrow) { - onAboutToRemoveItem(item, std::move(tagrow)); - }; - setOnAboutToRemoveItem(on_about_to_remove); - - auto on_model_destroyed = [this](auto) { - p_impl->m_viewModel->setRootViewItem(std::make_unique<RootViewItem>(nullptr)); - }; - setOnModelDestroyed(on_model_destroyed); - - auto on_model_reset = [this](auto) { - auto root_item = Utils::ItemFromPath(*model(), p_impl->m_rootItemPath); - p_impl->setRootSessionItemIntern(root_item ? root_item : model()->rootItem()); - p_impl->m_viewModel->endResetModel(); - }; - setOnModelReset(on_model_reset); - - auto on_model_about_to_be_reset = [this](auto) { p_impl->m_viewModel->beginResetModel(); }; - setOnModelAboutToBeReset(on_model_about_to_be_reset); -} - -void ViewModelController::setViewModel(ViewModelBase* view_model) -{ - p_impl->m_viewModel = view_model; -} - -ViewModelController::~ViewModelController() = default; - -void ViewModelController::setChildrenStrategy( - std::unique_ptr<ChildrenStrategyInterface> children_strategy) -{ - p_impl->m_childrenStrategy = std::move(children_strategy); -} - -void ViewModelController::setRowStrategy(std::unique_ptr<RowStrategyInterface> row_strategy) -{ - p_impl->m_rowStrategy = std::move(row_strategy); -} - -//! Returns SessionModel handled by this controller. - -SessionModel* ViewModelController::sessionModel() const -{ - return model(); -} - -void ViewModelController::setRootSessionItem(SessionItem* item) -{ - if (!item) - throw std::runtime_error( - "Error in ViewModelController: atttemp to set nulptr as root item"); - - if (item->model() != model()) - throw std::runtime_error( - "Error in ViewModelController: atttemp to use item from alien model as new root."); - - p_impl->m_viewModel->beginResetModel(); - p_impl->setRootSessionItemIntern(item); - p_impl->m_viewModel->endResetModel(); -} - -SessionItem* ViewModelController::rootSessionItem() const -{ - return p_impl->m_viewModel->rootItem()->item(); -} - -//! Returns all ViewItem's displaying given SessionItem. - -std::vector<ViewItem*> ViewModelController::findViews(const SessionItem* item) const -{ - return p_impl->findViews(item); -} - -QStringList ViewModelController::horizontalHeaderLabels() const -{ - return p_impl->m_rowStrategy->horizontalHeaderLabels(); -} - -void ViewModelController::onDataChange(SessionItem* item, int role) -{ - for (auto view : findViews(item)) { - // inform corresponding LabelView and DataView - if (isValidItemRole(view, role)) { - auto index = p_impl->m_viewModel->indexFromItem(view); - p_impl->m_viewModel->dataChanged(index, index, Utils::ItemRoleToQtRole(role)); - } - } -} - -void ViewModelController::onItemInserted(SessionItem* parent, TagRow tagrow) -{ - p_impl->insert_view(parent, tagrow); -} - -void ViewModelController::onItemRemoved(SessionItem*, TagRow) {} - -void ViewModelController::onAboutToRemoveItem(SessionItem* parent, TagRow tagrow) -{ - auto item_to_remove = parent->getItem(tagrow.tag, tagrow.row); - if (item_to_remove == rootSessionItem() - || Utils::IsItemAncestor(rootSessionItem(), item_to_remove)) { - // special case when user removes SessionItem which is one of ancestors of our root item - // or root item iteslf - p_impl->m_viewModel->beginResetModel(); - p_impl->m_viewModel->setRootViewItem(std::make_unique<RootViewItem>(nullptr)); - p_impl->m_itemToVview.clear(); - p_impl->m_rootItemPath = {}; - p_impl->m_viewModel->endResetModel(); - } else { - p_impl->remove_row_of_views(item_to_remove); - } -} - -void ViewModelController::update_branch(const SessionItem* item) -{ - auto views = findViews(item); - if (views.empty()) - return; - - for (auto view : views) - p_impl->remove_children_of_view(view); - - p_impl->iterate(item, views.at(0)); -} diff --git a/mvvm/viewmodel/mvvm/viewmodel/viewmodelcontroller.h b/mvvm/viewmodel/mvvm/viewmodel/viewmodelcontroller.h deleted file mode 100644 index 723870aa0c75e4d29bbce335d9a43a6422023897..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/viewmodel/viewmodelcontroller.h +++ /dev/null @@ -1,74 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/viewmodel/viewmodelcontroller.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEWMODEL_MVVM_VIEWMODEL_VIEWMODELCONTROLLER_H -#define BORNAGAIN_MVVM_VIEWMODEL_MVVM_VIEWMODEL_VIEWMODELCONTROLLER_H - -#include "mvvm/model/tagrow.h" -#include "mvvm/signals/modellistener.h" -#include "mvvm/viewmodel_export.h" -#include <QStringList> -#include <memory> -#include <vector> - -class QStandardItem; - -namespace ModelView { - -class SessionModel; -class SessionItem; -class ViewModelBase; -class ViewItem; -class ChildrenStrategyInterface; -class RowStrategyInterface; - -//! Propagates changes from SessionModel to its ViewModelBase. - -class MVVM_VIEWMODEL_EXPORT ViewModelController : public ModelListener<SessionModel> { -public: - ViewModelController(SessionModel* session_model, ViewModelBase* view_model = nullptr); - ~ViewModelController(); - - void setViewModel(ViewModelBase* view_model); - - void setChildrenStrategy(std::unique_ptr<ChildrenStrategyInterface> children_strategy); - - void setRowStrategy(std::unique_ptr<RowStrategyInterface> row_strategy); - - SessionModel* sessionModel() const; - - void setRootSessionItem(SessionItem* item); - - SessionItem* rootSessionItem() const; - - std::vector<ViewItem*> findViews(const ModelView::SessionItem* item) const; - - QStringList horizontalHeaderLabels() const; - -protected: - virtual void onDataChange(SessionItem* item, int role); - virtual void onItemInserted(SessionItem* parent, TagRow tagrow); - virtual void onItemRemoved(SessionItem* parent, TagRow tagrow); - virtual void onAboutToRemoveItem(SessionItem* parent, TagRow tagrow); - - void update_branch(const SessionItem* item); - -private: - struct ViewModelControllerImpl; - std::unique_ptr<ViewModelControllerImpl> p_impl; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEWMODEL_MVVM_VIEWMODEL_VIEWMODELCONTROLLER_H diff --git a/mvvm/viewmodel/mvvm/viewmodel/viewmodeldelegate.cpp b/mvvm/viewmodel/mvvm/viewmodel/viewmodeldelegate.cpp deleted file mode 100644 index 11da8b9a352d1e7ce679f9d1cc8d68a29de3447a..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/viewmodel/viewmodeldelegate.cpp +++ /dev/null @@ -1,119 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/viewmodel/viewmodeldelegate.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/viewmodel/viewmodeldelegate.h" -#include "mvvm/editors/customeditor.h" -#include "mvvm/editors/defaulteditorfactory.h" -#include "mvvm/model/comboproperty.h" -#include "mvvm/viewmodel/defaultcelldecorator.h" -#include <QApplication> - -namespace { -const double scale_default_height_factor{1.2}; -} - -using namespace ModelView; - -ViewModelDelegate::ViewModelDelegate(QObject* parent) - : QStyledItemDelegate(parent) - , m_editor_factory(std::make_unique<DefaultEditorFactory>()) - , m_cell_decoration(std::make_unique<DefaultCellDecorator>()) -{ -} - -ViewModelDelegate::~ViewModelDelegate() = default; - -void ViewModelDelegate::setEditorFactory(std::unique_ptr<EditorFactoryInterface> editor_factory) -{ - m_editor_factory = std::move(editor_factory); -} - -void ViewModelDelegate::setCellDecoration(std::unique_ptr<CellDecoratorInterface> cell_decoration) -{ - m_cell_decoration = std::move(cell_decoration); -} - -QWidget* ViewModelDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, - const QModelIndex& index) const -{ - if (auto editor = m_editor_factory->createEditor(index)) { - editor->setParent(parent); - connect(editor.get(), &CustomEditor::dataChanged, this, - &ViewModelDelegate::onCustomEditorDataChanged); - return editor.release(); - } - return QStyledItemDelegate::createEditor(parent, option, index); -} - -void ViewModelDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const -{ - if (!index.isValid()) - return; - - if (auto customEditor = dynamic_cast<CustomEditor*>(editor)) - customEditor->setData(index.data()); - else - QStyledItemDelegate::setEditorData(editor, index); -} - -void ViewModelDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, - const QModelIndex& index) const -{ - if (!index.isValid()) - return; - - if (auto customEditor = dynamic_cast<CustomEditor*>(editor)) { - model->setData(index, customEditor->data()); - } else { - QStyledItemDelegate::setModelData(editor, model, index); - } -} - -//! Increases height of the row by 20% wrt the default. - -QSize ViewModelDelegate::sizeHint(const QStyleOptionViewItem& option, - const QModelIndex& index) const -{ - QSize result = QStyledItemDelegate::sizeHint(option, index); - result.setHeight(static_cast<int>(result.height() * scale_default_height_factor)); - return result; -} - -//! Makes an editor occupying whole available space in a cell. If cell contains an icon -//! as a decoration (i.e. icon of material property), it will be hidden as soon as editor -//! up and running. - -void ViewModelDelegate::updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, - const QModelIndex& index) const -{ - QStyledItemDelegate::updateEditorGeometry(editor, option, index); - editor->setGeometry(option.rect); -} - -void ViewModelDelegate::onCustomEditorDataChanged() -{ - auto editor = qobject_cast<CustomEditor*>(sender()); - emit commitData(editor); - if (!editor->is_persistent()) - emit closeEditor(editor); -} - -void ViewModelDelegate::initStyleOption(QStyleOptionViewItem* option, - const QModelIndex& index) const -{ - QStyledItemDelegate::initStyleOption(option, index); - - if (m_cell_decoration && m_cell_decoration->hasCustomDecoration(index)) - m_cell_decoration->initStyleOption(option, index); -} diff --git a/mvvm/viewmodel/mvvm/viewmodel/viewmodeldelegate.h b/mvvm/viewmodel/mvvm/viewmodel/viewmodeldelegate.h deleted file mode 100644 index 5c6863cfc8dd863e4e5e8ba9770c656d4c81f68e..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/viewmodel/viewmodeldelegate.h +++ /dev/null @@ -1,63 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/viewmodel/viewmodeldelegate.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEWMODEL_MVVM_VIEWMODEL_VIEWMODELDELEGATE_H -#define BORNAGAIN_MVVM_VIEWMODEL_MVVM_VIEWMODEL_VIEWMODELDELEGATE_H - -#include "mvvm/viewmodel_export.h" -#include <QStyledItemDelegate> -#include <memory> - -namespace ModelView { - -class EditorFactoryInterface; -class CellDecoratorInterface; - -//! Model delegate to provide editing/painting for custom variants. - -class MVVM_VIEWMODEL_EXPORT ViewModelDelegate : public QStyledItemDelegate { - Q_OBJECT - -public: - explicit ViewModelDelegate(QObject* parent = nullptr); - ~ViewModelDelegate() override; - - void setEditorFactory(std::unique_ptr<EditorFactoryInterface> editor_factory); - void setCellDecoration(std::unique_ptr<CellDecoratorInterface> cell_decoration); - - QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, - const QModelIndex& index) const override; - - void setEditorData(QWidget* editor, const QModelIndex& index) const override; - void setModelData(QWidget* editor, QAbstractItemModel* model, - const QModelIndex& index) const override; - - QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const override; - - void updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, - const QModelIndex& index) const override; - -public slots: - void onCustomEditorDataChanged(); - -protected: - void initStyleOption(QStyleOptionViewItem* option, const QModelIndex& index) const override; - - std::unique_ptr<EditorFactoryInterface> m_editor_factory; - std::unique_ptr<CellDecoratorInterface> m_cell_decoration; -}; - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEWMODEL_MVVM_VIEWMODEL_VIEWMODELDELEGATE_H diff --git a/mvvm/viewmodel/mvvm/viewmodel/viewmodelutils.cpp b/mvvm/viewmodel/mvvm/viewmodel/viewmodelutils.cpp deleted file mode 100644 index 4a6665aac4fab7ccc9ccde7e44fc484f4533840d..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/viewmodel/viewmodelutils.cpp +++ /dev/null @@ -1,126 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/viewmodel/viewmodelutils.cpp -//! @brief Implements class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "mvvm/viewmodel/viewmodelutils.h" -#include "mvvm/model/customvariants.h" -#include "mvvm/model/externalproperty.h" -#include "mvvm/model/itemutils.h" -#include "mvvm/model/mvvm_types.h" -#include "mvvm/model/sessionitem.h" -#include "mvvm/viewmodel/viewitem.h" -#include "mvvm/viewmodel/viewmodel.h" -#include <QStandardItemModel> -#include <iterator> -#include <set> - -using namespace ModelView; - -void Utils::iterate_model(const QAbstractItemModel* model, const QModelIndex& parent, - const std::function<void(const QModelIndex& child)>& fun) -{ - if (!model) - return; - - for (int row = 0; row < model->rowCount(parent); ++row) { - for (int col = 0; col < model->columnCount(parent); ++col) { - auto index = model->index(row, col, parent); - if (index.isValid()) - fun(index); - } - for (int col = 0; col < model->columnCount(parent); ++col) { - auto index = model->index(row, col, parent); - iterate_model(model, index, fun); - } - } -} - -//! Translates SessionItem's data role to vector of Qt roles. - -QVector<int> Utils::ItemRoleToQtRole(int role) -{ - QVector<int> result; - // In Qt when we are editing the data in a view two roles are emmited. - if (role == ItemDataRole::DISPLAY || role == ItemDataRole::DATA) - result = {Qt::DisplayRole, Qt::EditRole}; - else if (role == ItemDataRole::APPEARANCE) -#if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0) - result = {Qt::ForegroundRole}; -#else - result = {Qt::TextColorRole}; -#endif - else if (role == ItemDataRole::TOOLTIP) - result = {Qt::ToolTipRole}; - - return result; -} - -QVariant Utils::TextColorRole(const SessionItem& item) -{ - return item.isEnabled() ? QVariant() : QColor(Qt::gray); -} - -QVariant Utils::CheckStateRole(const SessionItem& item) -{ - auto value = item.data<QVariant>(); - if (Utils::IsBoolVariant(value)) - return value.value<bool>() ? Qt::Checked : Qt::Unchecked; - return QVariant(); -} - -QVariant Utils::DecorationRole(const SessionItem& item) -{ - auto value = item.data<QVariant>(); - if (Utils::IsColorVariant(value)) - return value; - else if (Utils::IsExtPropertyVariant(value)) - return value.value<ExternalProperty>().color(); - return QVariant(); -} - -QVariant Utils::ToolTipRole(const SessionItem& item) -{ - return item.hasData(ItemDataRole::TOOLTIP) ? Variant(QString::fromStdString(item.toolTip())) - : QVariant(); -} - -std::vector<SessionItem*> Utils::ItemsFromIndex(const QModelIndexList& index_list) -{ - if (index_list.empty()) - return {}; - - std::vector<SessionItem*> result; - - if (auto model = dynamic_cast<const ViewModelBase*>(index_list.front().model())) - std::transform(index_list.begin(), index_list.end(), std::back_inserter(result), - [model](auto index) { return model->itemFromIndex(index)->item(); }); - - return result; -} - -std::vector<SessionItem*> Utils::UniqueItemsFromIndex(const QModelIndexList& index_list) -{ - return Utils::UniqueItems(Utils::ItemsFromIndex(index_list)); -} - -std::vector<SessionItem*> Utils::ParentItemsFromIndex(const QModelIndexList& index_list) -{ - std::set<SessionItem*> unique_parents; - for (auto item : ItemsFromIndex(index_list)) - if (item) - unique_parents.insert(item->parent()); - - std::vector<SessionItem*> result; - std::copy(unique_parents.begin(), unique_parents.end(), std::back_inserter(result)); - return result; -} diff --git a/mvvm/viewmodel/mvvm/viewmodel/viewmodelutils.h b/mvvm/viewmodel/mvvm/viewmodel/viewmodelutils.h deleted file mode 100644 index 217853c1fea8dd0a1a4e8dec3e23ac4de989ff93..0000000000000000000000000000000000000000 --- a/mvvm/viewmodel/mvvm/viewmodel/viewmodelutils.h +++ /dev/null @@ -1,73 +0,0 @@ -// ************************************************************************************************ -// -// qt-mvvm: Model-view-view-model framework for large GUI applications -// -//! @file mvvm/viewmodel/mvvm/viewmodel/viewmodelutils.h -//! @brief Defines class CLASS? -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2020 -//! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_MVVM_VIEWMODEL_MVVM_VIEWMODEL_VIEWMODELUTILS_H -#define BORNAGAIN_MVVM_VIEWMODEL_MVVM_VIEWMODEL_VIEWMODELUTILS_H - -#include "mvvm/viewmodel_export.h" -#include <QModelIndex> -#include <QModelIndexList> -#include <QVector> -#include <functional> -#include <vector> - -class QStandardItemModel; -class QStandardItem; -class QVariant; - -namespace ModelView { - -class ViewItem; -class SessionItem; - -namespace Utils { - -//! Iterates through QAbstractItem model -MVVM_VIEWMODEL_EXPORT void iterate_model(const QAbstractItemModel* model, const QModelIndex& parent, - const std::function<void(const QModelIndex& child)>& fun); - -//! Returns vector of Qt roles corresponding to given ItemDataRole. -MVVM_VIEWMODEL_EXPORT QVector<int> ItemRoleToQtRole(int role); - -//! Returns text color for given item. -MVVM_VIEWMODEL_EXPORT QVariant TextColorRole(const SessionItem& item); - -//! Returns check state role of given item. -MVVM_VIEWMODEL_EXPORT QVariant CheckStateRole(const SessionItem& item); - -//! Returns decoration role for given item. -MVVM_VIEWMODEL_EXPORT QVariant DecorationRole(const SessionItem& item); - -//! Returns tooltip role for given item. -MVVM_VIEWMODEL_EXPORT QVariant ToolTipRole(const SessionItem& item); - -//! Returns vector of underlying SessionItem's for given index list. -MVVM_VIEWMODEL_EXPORT std::vector<SessionItem*> ItemsFromIndex(const QModelIndexList& index_list); - -//! Returns vector of underlying SessionItem's for given index list. Removes repetitions -MVVM_VIEWMODEL_EXPORT std::vector<SessionItem*> -UniqueItemsFromIndex(const QModelIndexList& index_list); - -//! Returns vector of parent items from given index list. -//! Finds all SessionItems corresponding to given index list and collect their parents. -//! Function is usefull in the context of table-like views when we want to find compound items -//! (i.e. Layers) from table cells containing LayerItem's properties (i.e. thickness). -MVVM_VIEWMODEL_EXPORT std::vector<SessionItem*> -ParentItemsFromIndex(const QModelIndexList& index_list); - -} // namespace Utils - -} // namespace ModelView - -#endif // BORNAGAIN_MVVM_VIEWMODEL_MVVM_VIEWMODEL_VIEWMODELUTILS_H