Project

General

Profile

eq-preset-qt.cc

(libaudqt) - Jim Turner, December 03, 2019 05:29

 
1
/*
2
 * eq-preset-qt.cc
3
 * Copyright 2018 John Lindgren
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions are met:
7
 *
8
 * 1. Redistributions of source code must retain the above copyright notice,
9
 *    this list of conditions, and the following disclaimer.
10
 *
11
 * 2. Redistributions in binary form must reproduce the above copyright notice,
12
 *    this list of conditions, and the following disclaimer in the documentation
13
 *    provided with the distribution.
14
 *
15
 * This software is provided "as is" and without any warranty, express or
16
 * implied. In no event shall the authors be liable for any damages arising from
17
 * the use of this software.
18
 */
19

    
20
#include "libfauxdqt.h"
21
#include "treeview.h"
22

    
23
#include <QBoxLayout>
24
#include <QDialog>
25
#include <QLineEdit>
26
#include <QPointer>
27
#include <QPushButton>
28
#include <QCheckBox>
29
#include <QStandardItemModel>
30

    
31
#include "libaudcore/audstrings.h"
32
#include "libaudcore/equalizer.h"
33
#include "libaudcore/i18n.h"
34
#include "libaudcore/interface.h"
35
#include "libfauxdcore/playlist.h"
36
#include "libaudcore/runtime.h"
37
#include "libaudcore/vfs.h"
38

    
39
namespace audqt {
40

    
41
class PresetItem : public QStandardItem
42
{
43
public:
44
    explicit PresetItem (const EqualizerPreset & preset) :
45
        QStandardItem ((const char *) preset.name),
46
        preset (preset) {}
47

    
48
    const EqualizerPreset preset;
49
};
50

    
51
class PresetModel : public QStandardItemModel
52
{
53
public:
54
    explicit PresetModel (QObject * parent) :
55
        QStandardItemModel (0, 1, parent) {}
56

    
57
    void load_all ();
58
    void save_all ();
59

    
60
    QModelIndex add_preset (const EqualizerPreset & preset);
61
    QModelIndex add_preset (const char * name);
62
    void apply_preset (int row);
63

    
64
    const EqualizerPreset * preset_at (int row) const
65
    {
66
        auto pitem = static_cast<PresetItem *> (item (row));
67
        return pitem ? & pitem->preset : nullptr;
68
    }
69

    
70
    bool removeRows (int row, int count, const QModelIndex & parent = QModelIndex ()) override
71
    {
72
        bool removed = QStandardItemModel::removeRows (row, count, parent);
73
        m_changed = m_changed || removed;
74
        return removed;
75
    }
76

    
77
private:
78
    bool m_changed = false;
79
};
80

    
81
void PresetModel::load_all ()
82
{
83
    clear ();
84

    
85
    auto presets = aud_eq_read_presets ("eq.preset");
86
    for (const EqualizerPreset & preset : presets)
87
        appendRow (new PresetItem (preset));
88

    
89
    m_changed = false;
90
}
91

    
92
void PresetModel::save_all ()
93
{
94
    if (! m_changed)
95
        return;
96

    
97
    Index<EqualizerPreset> presets;
98
    for (int row = 0; row < rowCount (); row ++)
99
        presets.append (* preset_at (row));
100

    
101
    presets.sort ([] (const EqualizerPreset & a, const EqualizerPreset & b)
102
        { return strcmp (a.name, b.name); });
103

    
104
    aud_eq_write_presets (presets, "eq.preset");
105
    m_changed = false;
106
}
107

    
108
QModelIndex PresetModel::add_preset (const EqualizerPreset & preset)
109
{
110
    int insert_idx = rowCount ();
111
    for (int row = 0; row < rowCount (); row ++)
112
    {
113
        if (preset_at (row)->name == preset.name)
114
        {
115
            insert_idx = row;
116
            break;
117
        }
118
    }
119

    
120
    setItem (insert_idx, new PresetItem (preset));
121
    m_changed = true;
122

    
123
    return index (insert_idx, 0);
124
}
125

    
126
QModelIndex PresetModel::add_preset (const char * name)
127
{
128
    EqualizerPreset preset {String (name)};
129
    aud_eq_update_preset (preset);
130
    return add_preset (preset);
131
}
132

    
133
void PresetModel::apply_preset (int row)
134
{
135
    auto preset = preset_at (row);
136
    if (! preset)
137
        return;
138

    
139
    aud_eq_apply_preset (* preset);
140
    aud_set_bool (nullptr, "equalizer_active", true);
141
}
142

    
143
class PresetView : public TreeView
144
{
145
public:
146
    PresetView (QPushButton * export_btn) :
147
        m_export_btn (export_btn)
148
    {
149
        setEditTriggers (QTreeView::NoEditTriggers);
150
        setHeaderHidden (true);
151
        setIndentation (0);
152
        setSelectionMode (QTreeView::ExtendedSelection);
153
        setUniformRowHeights (true);
154

    
155
        auto pmodel = new PresetModel (this);
156
        pmodel->load_all ();
157
        setModel (pmodel);
158
    }
159

    
160
    PresetModel * pmodel () const
161
        { return static_cast<PresetModel *> (model ()); }
162

    
163
    void add_imported (const Index<EqualizerPreset> & presets);
164

    
165
    const EqualizerPreset * preset_for_export () const
166
    {
167
        auto idxs = selectionModel ()->selectedIndexes ();
168
        if (idxs.size () != 1)
169
            return nullptr;
170

    
171
        return pmodel ()->preset_at (idxs[0].row ());
172
    }
173

    
174
    void removeSelRows ()
175
    {
176
        while (1)
177
        {
178
            auto idxs = selectionModel ()->selectedIndexes ();
179
            if (idxs.size () <= 0)
180
                break;
181

    
182
            pmodel ()->removeRows (idxs[0].row (), 1);
183
        }
184
    }
185

    
186
protected:
187
    void activate (const QModelIndex & index) override
188
        { pmodel ()->apply_preset (index.row ()); }
189

    
190
    void selectionChanged (const QItemSelection & selected,
191
                           const QItemSelection & deselected) override
192
    {
193
        TreeView::selectionChanged (selected, deselected);
194

    
195
        auto idxs = selectionModel ()->selectedIndexes ();
196
        // JWT:THEY DON'T HAVE TO SELECT ONE IN FAUXDACIOUS!:  m_export_btn->setEnabled (idxs.size () == 1);
197
    }
198

    
199
private:
200
    QPushButton * m_export_btn;
201
};
202

    
203
void PresetView::add_imported (const Index<EqualizerPreset> & presets)
204
{
205
    QItemSelection sel;
206
    for (auto & preset : presets)
207
    {
208
        auto idx = pmodel ()->add_preset (preset);
209
        sel.select (idx, idx);
210
    }
211

    
212
    selectionModel ()->select (sel, QItemSelectionModel::Clear |
213
                                    QItemSelectionModel::SelectCurrent);
214

    
215
    if (presets.len () == 1)
216
    {
217
        aud_eq_apply_preset (presets[0]);
218
        aud_set_bool ("equalizer_active", true);
219
    }
220
}
221

    
222
static Index<EqualizerPreset> import_file (const char * filename)
223
{
224
    VFSFile file (filename, "r");
225
    if (! file)
226
        return Index<EqualizerPreset> ();
227

    
228
    if (str_has_suffix_nocase (filename, ".eqf") ||
229
        str_has_suffix_nocase (filename, ".q1"))
230
    {
231
        return aud_import_winamp_presets (file);
232
    }
233

    
234
    /* assume everything else is a native preset file */
235
    Index<EqualizerPreset> presets;
236
    presets.append ();
237

    
238
    if (! aud_load_preset_file (presets[0], file))
239
        presets.clear ();
240

    
241
    return presets;
242
}
243

    
244
static bool export_file (const char * filename, const EqualizerPreset & preset)
245
{
246
    VFSFile file (filename, "w");
247
    if (! file)
248
        return false;
249

    
250
    if (str_has_suffix_nocase (filename, ".eqf") ||
251
        str_has_suffix_nocase (filename, ".q1"))
252
    {
253
        return aud_export_winamp_preset (preset, file);
254
    }
255

    
256
    /* assume everything else is a native preset file */
257
    bool filesave_result = aud_save_preset_file (preset, file);
258

    
259
    // JWT:IF [Auto] IS ON && FILENAME SAVED == SONG AUTO (DEFAULT) PATH/SONGNAME.preset, LIGHT UP THE 
260
    // [PRESET] BUTTON INDICATING SONG-SPECIFIC EQUALIZATION IS IN EFFECT!
261

    
262
    if (filesave_result && aud_get_bool (nullptr, "equalizer_autoload") 
263
            && ! strcmp((const char *) str_decode_percent (aud_get_str(nullptr, "_eq_last_preset_filename"),-1), 
264
            (const char *) str_decode_percent (filename)))
265
    {
266
        aud_set_bool(nullptr, "equalizer_songauto", true);
267
        aud_set_str(nullptr, "_eq_last_preset_filename", "");
268
    }
269
    return filesave_result;
270
}
271

    
272
static const char * name_filter = N_("Preset files (*.preset *.eqf *.q1)");
273

    
274
static void set_default_preset_dir ()
275
{
276
    aud_set_str (nullptr, "_preset_dir", aud_get_path (AudPath::UserDir));
277
    if (aud_get_bool (nullptr, "try_local_preset_files"))
278
    {
279
        int current_playlist = aud_playlist_get_playing ();
280
        if (current_playlist >= 0)
281
        {
282
            int current_song = aud_playlist_get_position (current_playlist);
283
            if (current_song >= 0)
284
            {
285
                String filename = aud_playlist_entry_get_filename (current_playlist, current_song);
286

    
287
                StringBuf scheme = uri_get_scheme (filename);
288
                if (aud_get_bool (nullptr, "try_local_preset_files") && ! strcmp (scheme, "file"))
289
                {
290
                    StringBuf path = filename_get_parent ((const char *) uri_to_filename (filename));
291
                    aud_set_str (nullptr, "_preset_dir", (const char *) path);
292
                }
293
            }
294
        }
295
    }
296
}
297

    
298
static void show_import_dialog (QDialog * parent, PresetView * view)
299
{
300
    auto dialog = new QFileDialog (parent, _("Load Preset File - Fauxdacious"));
301

    
302
    dialog->setAttribute (Qt::WA_DeleteOnClose);
303
    dialog->setFileMode (QFileDialog::ExistingFile);
304
    dialog->setLabelText (QFileDialog::Accept, _("Load"));
305
    dialog->setNameFilter (_(name_filter));
306
    set_default_preset_dir ();
307
    dialog->setDirectory (QString (aud_get_str (nullptr, "_preset_dir")));
308

    
309
    QObject::connect (dialog, & QFileDialog::accepted, [dialog, view] () {
310
        auto urls = dialog->selectedUrls ();
311
        if (urls.size () != 1)
312
            return;
313

    
314
        auto filename = urls[0].toEncoded ();
315
        auto presets = import_file (filename);
316

    
317
        if (presets.len ())
318
        {
319
            view->add_imported (presets);
320
            dialog->deleteLater ();
321
        }
322
        else
323
        {
324
            aud_ui_show_error (str_printf (_("Error loading %s."), filename.constData ()));
325
        }
326
    });
327

    
328
    window_bring_to_front (dialog);
329
}
330

    
331
static void show_export_dialog (QDialog * parent, const EqualizerPreset & preset)
332
{
333
    String filename;
334
    auto dialog = new QFileDialog (parent, _("Save Preset File"));
335

    
336
    dialog->setAttribute (Qt::WA_DeleteOnClose);
337
    dialog->setAcceptMode (QFileDialog::AcceptSave);
338
    dialog->setFileMode (QFileDialog::AnyFile);
339
    dialog->setLabelText (QFileDialog::Accept, _("Save"));
340
    dialog->setNameFilter (_(name_filter));
341

    
342
    /* TODO: replace other illegal characters on Win32 */
343

    
344
    /* JWT:OUR PRESET-FILENAME FILLIN CODE */
345
    int current_playlist = aud_playlist_get_playing ();
346
    bool dialog_set = false;
347
    aud_set_str (nullptr, "_eq_last_preset_filename", "");
348
    aud_set_str (nullptr, "_preset_dir", aud_get_path (AudPath::UserDir));
349
    dialog->setDirectory (QString (aud_get_path (AudPath::UserDir)));
350
    if (preset.name)  // AUDACIOUS 3.10+ SAYS SAVE USING SELECTED PRESET NAME, IF ONE SELECTED!:
351
    {
352
        auto safe = QString (preset.name).replace (QLatin1Char ('/'), QLatin1Char ('_'));
353
        dialog->selectFile (safe + ".preset");
354
        dialog_set = true;
355
    }
356
    else if (current_playlist >= 0)  // JWT:NONE SELECTED, CALCULATE THE EXPORT NAME:
357
    {
358
        int current_song = aud_playlist_get_position (current_playlist);
359
        if (current_song >= 0)
360
        {
361
            if (aud_get_bool (nullptr, "try_local_preset_files") && aud_get_bool (nullptr, "_save_as_dirdefault"))
362
            {
363
                String eqpreset_dir_default_file = aud_get_str (nullptr, "eqpreset_dir_default_file");
364
                if (eqpreset_dir_default_file && eqpreset_dir_default_file[0])
365
                {
366
                    filename = aud_playlist_entry_get_filename (current_playlist, current_song);
367
                    StringBuf scheme = uri_get_scheme (filename);
368
                    if (! strcmp (scheme, "file"))  // JWT:WE'RE A "FILE" AND SAVE TO LOCAL DIR, AND SAVE AS DIR-PRESET:
369
                    {
370
                        StringBuf path = filename_get_parent (uri_to_filename (filename));
371
                        aud_set_str (nullptr, "_preset_dir", (const char *) path);
372
                        dialog->setDirectory (QString ((const char *) path));
373
                        String preset_file_namepart = eqpreset_dir_default_file;
374
                        aud_set_str (nullptr, "_eq_last_preset_filename", String (filename_to_uri
375
                                (str_concat ({aud_get_str (nullptr, "_preset_dir"), "/",
376
                                preset_file_namepart}))));
377
                        auto safe = QString (preset_file_namepart).replace (QLatin1Char ('/'), QLatin1Char ('_'));
378
                        dialog->selectFile (safe);
379
                        dialog_set = true;
380
                    }
381
                }
382
            }
383
            if (! dialog_set)
384
            {
385
                const char * slash;
386
                const char * base;
387
                filename = aud_playlist_entry_get_filename (current_playlist, current_song);
388
                const char * dross = aud_get_bool (nullptr, "eqpreset_nameonly") ? strstr (filename, "?") : nullptr;
389
                int ln = -1;
390
                StringBuf scheme = uri_get_scheme (filename);
391
                if (aud_get_bool (nullptr, "eqpreset_use_url_sitename")
392
                        && strcmp (scheme, "file") && strcmp (scheme, "stdin")
393
                        && strcmp (scheme, "cdda") && strcmp (scheme, "dvd"))
394
                {
395
                    /* WE'RE A URL AND USER WANTS TO SAVE PRESETFILE FOR THE BASE SITE NAME, IE. "www.site.com": */
396
                    slash = strstr (filename, "//");
397
                    if (slash)
398
                    {
399
                        slash+=2;
400
                        const char * endbase = strstr (slash, "/");
401
                        ln = endbase ? endbase - slash : -1;
402
                        String urlbase = String (str_copy (slash, ln));
403
                        auto split = str_list_to_index (slash, "?&#:/");
404
                        for (auto & str : split)
405
                        {
406
                            urlbase = String (str_copy (str));
407
                            break;
408
                        }
409
                        String preset_file_namepart = String (str_concat ({urlbase, ".preset"}));
410
                        aud_set_str (nullptr, "_eq_last_preset_filename", String (filename_to_uri
411
                                (str_concat ({aud_get_path (AudPath::UserDir), "/",
412
                                preset_file_namepart}))));
413
                        auto safe = QString (preset_file_namepart).replace (QLatin1Char ('/'), QLatin1Char ('_'));
414
                        dialog->selectFile (safe);
415
                        dialog_set = true;
416
                    }
417
                }
418
                if (! dialog_set)
419
                {
420
                    /* JWT: EXTRACT JUST THE "NAME" PART (URLs MAY END W/"/") TO USE TO NAME THE EQ. FILE: */
421
                    slash = filename ? strrchr (filename, '/') : nullptr;
422
                    if (slash && dross && slash > dross)
423
                    {
424
                        slash = dross;
425
                        while (slash > filename && slash[0] != '/')
426
                        {
427
                            --slash;
428
                        }
429
                        if (slash[0] != '/')
430
                            slash = nullptr;
431
                    }
432
                    base = slash ? slash + 1 : nullptr;
433
                    if (slash && (!base || base[0] == '\0'))  // FILENAME (URL) ENDS IN A "/"!
434
                    {
435
                        do
436
                        {
437
                            --slash;
438
                            ++ln;
439
                        } while (slash && slash > filename && slash[0] != '/');
440
                        base = slash ? slash + 1 : (const char *) filename;
441
                        if (ln > 0)
442
                        {
443
                            String preset_file_namepart = String (str_concat ({str_encode_percent (base, ln), ".preset"}));
444
                            aud_set_str (nullptr, "_eq_last_preset_filename", String (filename_to_uri
445
                                    (str_concat ({aud_get_path (AudPath::UserDir), "/",
446
                                    preset_file_namepart}))));
447
                            auto safe = QString (preset_file_namepart).replace (QLatin1Char ('/'), QLatin1Char ('_'));
448
                            dialog->selectFile (safe);
449
                            dialog_set = true;
450
                        }
451
                    }
452
                    else if (base && base[0] != '\0' && strncmp (base, "-.", 2))
453
                    {
454
                        const char * iscue = dross ? dross : strstr (filename, "?");
455
                        StringBuf scheme = uri_get_scheme (filename);
456
                        if (aud_get_bool (nullptr, "try_local_preset_files") && ! strcmp (scheme, "file"))
457
                        {
458
                            StringBuf path = filename_get_parent (uri_to_filename (filename));
459
                            aud_set_str (nullptr, "_preset_dir", (const char *) path);
460
                            dialog->setDirectory (QString ((const char *) path));
461
                        }
462
                        if (iscue && base[0] != '?')  // WE'RE A CUE-SHEET FILE:
463
                        {
464
                            /* JWT:SONGS FROM CUE FILES HAVE A TRAILING "?<cue#>" THAT'S NOT ON THE FILENAME IN output.cc
465
                                SO WE HAVE TO STRIP IT OFF THE "filename" HERE, BUT ONLY IF WE'RE A "file://..." SCHEME,
466
                                LEST WE WHACK OFF A URL LIKE "https://www.youtube.com/watch?t=4&v=BaW_jenozKc"!
467
                                THE DRAWBACK W/THIS IS THAT ALL CUES OF THE SAME BASE FILE NAME WILL HAVE THE SAME
468
                                EQ. PRESET, BUT THE ALTERNATIVE IS THAT EQ. PRESETS WON'T WORK AT ALL FOR CUE-BASED
469
                                FILES, SINCE WE DON'T SEEM TO HAVE THE <cue#> IN output.cc for output_open_audio()!
470
                            */
471
                            if (dross || ! strcmp (scheme, "file"))
472
                            {
473
                                int ln = iscue - base;
474
                                String preset_file_namepart = String (str_concat ({str_encode_percent (base, ln), ".preset"}));
475
                                aud_set_str (nullptr, "_eq_last_preset_filename", String (filename_to_uri
476
                                        (str_concat ({aud_get_str (nullptr, "_preset_dir"), "/",
477
                                        preset_file_namepart}))));
478
                                auto safe = QString (preset_file_namepart).replace (QLatin1Char ('/'), QLatin1Char ('_'));
479
                                dialog->selectFile (safe);
480
                                dialog_set = true;
481
                            }
482
                        }
483
                        if (! dialog_set)
484
                        {
485
                            String preset_file_namepart = String (str_concat ({str_encode_percent (base, -1), ".preset"}));
486
                            if (! strcmp (scheme, "cdda") || ! strcmp (scheme, "dvd"))
487
                            {
488
                                String playingdiskid = aud_get_str (nullptr, "playingdiskid");
489
                                if (playingdiskid[0])
490
                                    preset_file_namepart = String (str_concat ({playingdiskid, ".preset"}));
491
                            }
492
                            aud_set_str (nullptr, "_eq_last_preset_filename", String (filename_to_uri
493
                                    (str_concat ({aud_get_str (nullptr, "_preset_dir"), "/",
494
                                    preset_file_namepart}))));
495
                            auto safe = QString (preset_file_namepart).replace (QLatin1Char ('/'), QLatin1Char ('_'));
496
                            dialog->selectFile (safe);
497
                            dialog_set = true;
498
                        }
499
                    }
500
                }
501
            }
502
        }
503
    }
504
    if (! dialog_set)
505
    {
506
        dialog->selectFile ("<NAMEME!>.preset");
507
    }
508
    /* JWT:END OUR PRESET-FILENAME FILLIN CODE */
509

    
510
    QObject::connect (dialog, & QFileDialog::accepted, [dialog, preset] () {
511
        auto urls = dialog->selectedUrls ();
512
        if (urls.size () != 1)
513
            return;
514

    
515
        auto filename = urls[0].toEncoded ();
516

    
517
        if (export_file (filename, preset))
518
            dialog->deleteLater ();
519
        else
520
            aud_ui_show_error (str_printf (_("Error saving %s."), filename.constData ()));
521
    });
522

    
523
    window_bring_to_front (dialog);
524
}
525

    
526
static QDialog * create_preset_win ()
527
{
528
    auto win = new QDialog;
529
    win->setAttribute (Qt::WA_DeleteOnClose);
530
    win->setWindowTitle (_("Equalizer Presets - Fauxdacious"));
531
    win->setContentsMargins (margins.TwoPt);
532

    
533
    auto edit = new QLineEdit;
534
    auto save_btn = new QPushButton (_("Save Preset"));
535
    save_btn->setIcon (get_icon ("document-save"));
536
    save_btn->setDisabled (true);
537

    
538
    auto hbox = make_hbox (nullptr);
539
    hbox->addWidget (edit);
540
    hbox->addWidget (save_btn);
541

    
542
    /* JWT:ADD OUR CHECKBOXES: */
543
    auto localsave_checkbox = new QCheckBox (_("Use entry's local directory for preset files, if file."));
544
    auto save_as_dirdefault_checkbox = new QCheckBox (_("Save as Directory-wide Preset, IF file & above box checked."));
545
    auto urlbase_checkbox = new QCheckBox (_("Use only base site name for URLs."));
546
    auto nameonly_checkbox = new QCheckBox (_("Exclude arg. lists from URLs to create preset filename."));
547
    auto save_effects2_checkbox = new QCheckBox (_("Save Effects (plugins) with presets."));
548
    /* JWT:END ADD OUR CHECKBOXES: */
549

    
550
    auto import_btn = new QPushButton (_("Import"));
551
    import_btn->setIcon (get_icon ("document-open"));
552

    
553
    auto export_btn = new QPushButton (_("Export"));
554
    export_btn->setIcon (get_icon ("document-save"));
555

    
556
    auto view = new PresetView (export_btn);
557

    
558
    auto hbox2 = make_hbox (nullptr);
559
    hbox2->addWidget (import_btn);
560
    hbox2->addWidget (export_btn);
561
    hbox2->addStretch (1);
562

    
563
    auto remove_btn = new QPushButton (_("Delete Selected"));
564
    remove_btn->setIcon (get_icon ("edit-delete"));
565
    // remove_btn->setDisabled (true);
566

    
567
    auto revert_btn = new QPushButton (_("Revert Changes"));
568
    revert_btn->setIcon (get_icon ("edit-undo"));
569
    revert_btn->setDisabled (true);
570

    
571
    auto close_btn = new QPushButton (_("Close"));
572
    close_btn->setIcon (get_icon ("window-close"));
573

    
574
    auto hbox3 = make_hbox (nullptr);
575
    hbox3->addWidget (remove_btn);
576
    hbox3->addStretch (1);
577
    hbox3->addWidget (revert_btn);
578
    hbox3->addWidget (close_btn);
579

    
580
    auto vbox = make_vbox (win);
581
    vbox->addLayout (hbox);
582
    /* JWT:OUR CHECKBOXES: */
583
    vbox->addWidget (localsave_checkbox);
584
    String eqpreset_dir_default_file = aud_get_str (nullptr, "eqpreset_dir_default_file");
585
    if (eqpreset_dir_default_file && eqpreset_dir_default_file[0])
586
        vbox->addWidget (save_as_dirdefault_checkbox);
587
    else
588
        aud_set_bool (nullptr, "_save_as_dirdefault", false);
589
    vbox->addWidget (urlbase_checkbox);
590
    vbox->addWidget (nameonly_checkbox);
591
    bool eqpreset_use_effects = aud_get_bool (nullptr, "eqpreset_use_effects");
592
    if (eqpreset_use_effects)
593
        vbox->addWidget (save_effects2_checkbox);
594
    else
595
        aud_set_bool (nullptr, "eqpreset_save_effects", false);
596
    /* JWT:END OUR CHECKBOXES */
597
    vbox->addWidget (view);
598
    vbox->addLayout (hbox2);
599
    vbox->addLayout (hbox3);
600

    
601
    auto pmodel = view->pmodel ();
602

    
603
    /* JWT:OUR CHECKBOXES: */
604
    localsave_checkbox->setCheckState (aud_get_bool (nullptr, "try_local_preset_files") 
605
            ? Qt::Checked : Qt::Unchecked);
606
    QObject::connect (localsave_checkbox, & QCheckBox::stateChanged, [] (int state) {
607
        aud_set_bool (nullptr, "try_local_preset_files", (state == Qt::Checked));
608
    });
609

    
610
    if (eqpreset_dir_default_file && eqpreset_dir_default_file[0])
611
    {
612
        save_as_dirdefault_checkbox->setCheckState (aud_get_bool (nullptr, "_save_as_dirdefault") 
613
                ? Qt::Checked : Qt::Unchecked);
614
        QObject::connect (save_as_dirdefault_checkbox, & QCheckBox::stateChanged, [] (int state) {
615
            aud_set_bool (nullptr, "_save_as_dirdefault", (state == Qt::Checked));
616
        });
617
    }
618

    
619
    urlbase_checkbox->setCheckState (aud_get_bool (nullptr, "eqpreset_use_url_sitename")
620
            ? Qt::Checked : Qt::Unchecked);
621
    QObject::connect (urlbase_checkbox, & QCheckBox::stateChanged, [] (int state) {
622
        aud_set_bool (nullptr, "eqpreset_use_url_sitename", (state == Qt::Checked));
623
    });
624

    
625
    nameonly_checkbox->setCheckState (aud_get_bool (nullptr, "eqpreset_nameonly") 
626
            ? Qt::Checked : Qt::Unchecked);
627
    QObject::connect (nameonly_checkbox, & QCheckBox::stateChanged, [] (int state) {
628
        aud_set_bool (nullptr, "eqpreset_nameonly", (state == Qt::Checked));
629
    });
630

    
631
    if (eqpreset_use_effects)
632
    {
633
        save_effects2_checkbox->setCheckState (aud_get_bool (nullptr, "eqpreset_save_effects") 
634
                ? Qt::Checked : Qt::Unchecked);
635
        QObject::connect (save_effects2_checkbox, & QCheckBox::stateChanged, [] (int state) {
636
            aud_set_bool (nullptr, "OUR CHECKBOXES", (state == Qt::Checked));
637
        });
638
    }
639

    
640
    /* JWT:END OUR CHECKBOXES */
641

    
642
    QObject::connect (edit, & QLineEdit::textChanged, [save_btn] (const QString & text) {
643
        save_btn->setEnabled (! text.isEmpty ());
644
    });
645

    
646
    QObject::connect (save_btn, & QPushButton::clicked, [view, pmodel, edit, revert_btn] () {
647
        auto added = pmodel->add_preset (edit->text ().toUtf8 ());
648
        view->setCurrentIndex (added);
649
        revert_btn->setDisabled (false);
650
    });
651

    
652
    QObject::connect (import_btn, & QPushButton::clicked, [win, view] () {
653
        show_import_dialog (win, view);
654
    });
655

    
656
    QObject::connect (export_btn, & QPushButton::clicked, [win, view] () {
657
        auto preset = view->preset_for_export ();
658
        // JWT:USE CURRENT INSTEAD OF FAIL:  g_return_if_fail (preset);
659
        EqualizerPreset current_preset;
660
        if (preset == nullptr)
661
        {
662
            aud_eq_update_preset (current_preset);
663
            preset = & current_preset;
664
        }
665
        if (preset != nullptr)
666
            show_export_dialog (win, * preset);
667
    });
668

    
669
    QObject::connect (pmodel, & PresetModel::rowsRemoved, [revert_btn] () {
670
        revert_btn->setDisabled (false);
671
    });
672

    
673
    QObject::connect (revert_btn, & QPushButton::clicked, [pmodel, revert_btn] () {
674
        pmodel->load_all ();
675
        revert_btn->setDisabled (true);
676
    });
677

    
678
    QObject::connect (remove_btn, & QPushButton::clicked, [win, view] () {
679
        view->removeSelRows ();
680
    });
681

    
682
    QObject::connect (close_btn, & QPushButton::clicked, win, & QObject::deleteLater);
683

    
684
    QObject::connect (win, & QObject::destroyed, [pmodel] () {
685
        pmodel->save_all ();
686
    });
687

    
688
    return win;
689
}
690

    
691
static QPointer<QDialog> s_preset_win;
692

    
693
EXPORT void eq_presets_show ()
694
{
695
    if (! s_preset_win)
696
        s_preset_win = create_preset_win ();
697

    
698
    window_bring_to_front (s_preset_win);
699
}
700

    
701
EXPORT void eq_presets_hide ()
702
{
703
    delete s_preset_win;
704
}
705

    
706
} // namespace audqt