OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [tools/] [src/] [tools/] [configtool/] [standalone/] [wxwin/] [configitem.cpp] - Blame information for rev 438

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 26 unneback
//####COPYRIGHTBEGIN####
2
//
3
// ----------------------------------------------------------------------------
4
// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.
5
//
6
// This program is part of the eCos host tools.
7
//
8
// This program is free software; you can redistribute it and/or modify it
9
// under the terms of the GNU General Public License as published by the Free
10
// Software Foundation; either version 2 of the License, or (at your option)
11
// any later version.
12
//
13
// This program is distributed in the hope that it will be useful, but WITHOUT
14
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
16
// more details.
17
//
18
// You should have received a copy of the GNU General Public License along with
19
// this program; if not, write to the Free Software Foundation, Inc.,
20
// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21
//
22
// ----------------------------------------------------------------------------
23
//
24
//####COPYRIGHTEND####
25
// configitem.cpp :
26
//
27
//===========================================================================
28
//#####DESCRIPTIONBEGIN####
29
//
30
// Author(s):   julians
31
// Contact(s):  julians
32
// Date:        2000/09/01
33
// Version:     $Id: configitem.cpp,v 1.1.1.1 2004-02-14 13:28:47 phoenix Exp $
34
// Purpose:
35
// Description: Implementation file for the ConfigTool application class
36
// Requires:
37
// Provides:
38
// See also:
39
// Known bugs:
40
// Usage:
41
//
42
//####DESCRIPTIONEND####
43
//
44
//===========================================================================
45
 
46
// ============================================================================
47
// declarations
48
// ============================================================================
49
 
50
// ----------------------------------------------------------------------------
51
// headers
52
// ----------------------------------------------------------------------------
53
#ifdef __GNUG__
54
    #pragma implementation "configitem.h"
55
#endif
56
 
57
// Includes other headers for precompiled compilation
58
#include "ecpch.h"
59
 
60
#ifdef __BORLANDC__
61
    #pragma hdrstop
62
#endif
63
 
64
#include "wx/settings.h"
65
#include "wx/valgen.h"
66
 
67
#include "configitem.h"
68
#include "configtree.h"
69
#include "configtooldoc.h"
70
#include "configtoolview.h"
71
#include "ecutils.h"
72
 
73
IMPLEMENT_CLASS(ecConfigItem, wxObject)
74
 
75
/*
76
 * ecConfigItem
77
 * Represents a node in the configuration hierarchy.
78
 * For every ecConfigItem, there is also an ecTreeItemData
79
 * that points to it.
80
 */
81
 
82
ecConfigItem::ecConfigItem(ecConfigItem* parent, const wxString& name, ecConfigType ctype,
83
                           ecOptionFlavor flavor, ecOptionType otype,
84
                           bool active, bool enabled, ecUIHint hint)
85
{
86
    m_CdlItem = NULL;
87
    m_name = name;
88
    m_configType = ctype;
89
    m_optionType = otype;
90
    m_optionFlavor = flavor;
91
    m_enabled = enabled;
92
    m_active = active;
93
    m_parent = parent;
94
    m_hint = hint;
95
    m_treeItem = wxTreeItemId();
96
 
97
    switch (otype)
98
    {
99
    case ecDouble:
100
        {
101
            m_value = 0.0;
102
            break;
103
        }
104
    case ecString:
105
    case ecEnumerated:
106
        {
107
            m_value = wxT("");
108
            break;
109
        }
110
    case ecLong:
111
        {
112
            m_value = (long) 0;
113
            break;
114
        }
115
    case ecBool:
116
        {
117
            m_value = (bool) FALSE;
118
            break;
119
        }
120
    default:
121
        {
122
            break;
123
        }
124
    }
125
}
126
 
127
ecConfigItem::ecConfigItem(ecConfigItem* parent, CdlUserVisible vitem)
128
{
129
    m_name = wxT("UNNAMED");
130
    m_configType = ecConfigTypeNone;
131
    m_optionType = ecOptionTypeNone;
132
    m_optionFlavor = ecFlavorNone;
133
    m_enabled = FALSE;
134
    m_active = FALSE;
135
    m_parent = parent;
136
    m_CdlItem = vitem;
137
    m_hint = ecHintNone;
138
    m_treeItem = wxTreeItemId();
139
 
140
    ecConfigTreeCtrl* treeCtrl = wxGetApp().GetTreeCtrl();
141
    m_treeItem = treeCtrl->AppendItem(parent->GetTreeItem(), m_name, -1, -1, new ecTreeItemData(this));
142
 
143
    ConvertFromCdl();
144
    UpdateTreeItem(* treeCtrl);
145
}
146
 
147
ecConfigItem::~ecConfigItem()
148
{
149
    // Make sure that the tree item no longer references this object
150
    ecConfigTreeCtrl* treeCtrl = wxGetApp().GetTreeCtrl();
151
    if (m_treeItem && treeCtrl)
152
    {
153
        ecTreeItemData* data = (ecTreeItemData*) treeCtrl->GetItemData(m_treeItem);
154
        data->SetConfigItem(NULL);
155
    }
156
 
157
    ecConfigToolDoc* doc = wxGetApp().GetConfigToolDoc();
158
    if (doc)
159
    {
160
        doc->GetItems().DeleteObject(this);
161
    }
162
}
163
 
164
// Convert from Cdl to internal representation
165
bool ecConfigItem::ConvertFromCdl()
166
{
167
    if (!GetCdlItem())
168
        return FALSE;
169
 
170
    m_name = GetCdlItem()->get_display ().c_str ();
171
    m_macro = GetCdlItem()->get_name().c_str();
172
    m_strDescr = ecUtils::StripExtraWhitespace (wxString (GetCdlItem()->get_description ().c_str ()));
173
 
174
 
175
    // FIXME: re-implement using CdlValuableBody::get_widget_hint()
176
    // (comment from original MFC configtool)
177
 
178
    if (IsPackage())
179
    {
180
        // If a package item, display the package version string
181
        m_optionType = ecString;
182
        m_configType = ecPackage;
183
        m_optionFlavor = ecFlavorNone;
184
    }
185
    else
186
    {
187
        const CdlValuable valuable = dynamic_cast<CdlValuable> (GetCdlItem());
188
        switch (valuable->get_flavor ()){
189
        case CdlValueFlavor_None:
190
            m_optionFlavor = ecFlavorNone;
191
            m_optionType=ecOptionTypeNone; //??? Shouldn't it be ecBool for CdlValueFlavor_Bool?
192
            m_configType = ecContainer;
193
            break;
194
        case CdlValueFlavor_Bool:
195
            m_optionFlavor = ecFlavorBool;
196
            m_optionType=ecOptionTypeNone; //??? Shouldn't it be ecBool for CdlValueFlavor_Bool?
197
            m_configType = ecOption;
198
            m_hint = (HasRadio() ? ecHintRadio : ecHintCheck);
199
            break;
200
        case CdlValueFlavor_Data:
201
        case CdlValueFlavor_BoolData:
202
 
203
            m_optionFlavor = (valuable->get_flavor() == CdlValueFlavor_Data ? ecFlavorData : ecFlavorBoolData);
204
            m_configType = ecOption;
205
            m_hint = (HasRadio() ? ecHintRadio : ecHintCheck);
206
 
207
            if (! valuable->has_legal_values ()) {
208
                m_optionType=ecString;
209
            } else if (0 == valuable->get_legal_values ()->ranges.size ()) {
210
                m_optionType=ecEnumerated;
211
            } else {
212
                CdlListValue list_value;
213
                CdlEvalContext context (NULL, valuable, valuable->get_property (CdlPropertyId_LegalValues));
214
                valuable->get_legal_values ()->eval (context, list_value);
215
                m_optionType=list_value.get_double_ranges ().size () ? ecDouble : ecLong;
216
            }
217
            break;
218
        default:
219
            wxASSERT (0); // specified flavor not supported
220
            break;
221
        }
222
    }
223
 
224
    m_active = IsActive();
225
    m_enabled = IsEnabled();
226
 
227
    return TRUE;
228
}
229
 
230
wxString ecConfigItem::GetItemNameOrMacro() const
231
{
232
    return (wxGetApp().GetSettings().m_showMacroNames && !GetMacro().IsEmpty() ? GetMacro() : GetName());
233
}
234
 
235
// Sets the text and icon for this item
236
bool ecConfigItem::UpdateTreeItem(ecConfigTreeCtrl& treeCtrl)
237
{
238
    treeCtrl.SetItemText(m_treeItem, m_name);
239
 
240
    static wxColour normalColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_WINDOWTEXT);
241
    static wxColour disabledColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_GRAYTEXT);
242
 
243
    treeCtrl.SetItemTextColour(m_treeItem, GetActive() ? normalColour : disabledColour);
244
 
245
 
246
    // Find which icon state we're in so we can get the appropriate icon id
247
    int iconState = 0;
248
    wxString iconName;
249
 
250
    switch (GetConfigType())
251
    {
252
        case ecContainer:
253
            {
254
                iconName = _("Container");
255
                iconState = 0;
256
                break;
257
            }
258
        case ecPackage:
259
            {
260
                iconName = _("Package");
261
                iconState = 0;
262
                break;
263
            }
264
        case ecComponent:
265
            {
266
                iconName = _("??");
267
                iconState = 0;
268
                break;
269
            }
270
        case ecOption:
271
            {
272
                if (GetOptionFlavor() == ecFlavorData)
273
                {
274
                    switch (GetOptionType())
275
                    {
276
                    case ecDouble:
277
                    case ecLong:
278
                        {
279
                            iconName = _("Integer");
280
                            iconState = 0;
281
                            break;
282
                        }
283
                    case ecEnumerated:
284
                        {
285
                            iconName = _("Enumerated");
286
                            iconState = 0;
287
                            break;
288
                        }
289
                    case ecString:
290
                        {
291
                            iconName = _("Text");
292
                            iconState = 0;
293
                            break;
294
                        }
295
                    // ??? Actually I don't think there's such a think as ecBool type, only enabled/disabled
296
                    case ecBool:
297
                        {
298
                            if (GetUIHint() == ecHintCheck)
299
                                iconName = _("Checkbox");
300
                            else
301
                                iconName = _("Radiobox");
302
                            iconState = (m_value.GetBool() ? 0 : 1);
303
                            break;
304
                        }
305
                    default:
306
                        {
307
                            break;
308
                        }
309
                    }
310
                }
311
                if (GetOptionFlavor() == ecFlavorBoolData || GetOptionFlavor() == ecFlavorBool)
312
                {
313
                    if (GetUIHint() == ecHintCheck)
314
                        iconName = _("Checkbox");
315
                    else
316
                        iconName = _("Radiobox");
317
                    iconState = (m_enabled ? 0 : 1);
318
                }
319
                break;
320
            }
321
        default:
322
            {
323
                break;
324
            }
325
    }
326
 
327
    if (!iconName.IsEmpty())
328
    {
329
        int iconId = treeCtrl.GetIconDB().GetIconId(iconName, iconState, GetActive());
330
        treeCtrl.SetItemImage(m_treeItem, iconId, wxTreeItemIcon_Normal);
331
        treeCtrl.SetItemImage(m_treeItem, iconId, wxTreeItemIcon_Selected);
332
    }
333
 
334
    return TRUE;
335
}
336
 
337
// Handle a left click on the icon: e.g. (un)check the option
338
// In the old MFC tool, this was handled by CControlView::Bump
339
void ecConfigItem::OnIconLeftDown(ecConfigTreeCtrl& treeCtrl)
340
{
341
    if (GetConfigType() != ecOption)
342
        return;
343
 
344
    switch (GetOptionFlavor())
345
    {
346
    case ecFlavorBool:
347
    case ecFlavorBoolData:
348
        {
349
            if (GetActive())
350
            {
351
                wxGetApp().GetConfigToolDoc()->SetEnabled(*this, !m_enabled);
352
            }
353
            break;
354
        }
355
    case ecFlavorData:
356
        {
357
            if (GetActive())
358
            {
359
                switch (GetOptionType())
360
                {
361
                case ecLong:
362
                    {
363
                        int nInc = 1;
364
 
365
                        long nOldValue = Value();
366
                        if(nInc==1 && nOldValue == long(-1))
367
                        {
368
                            nOldValue=0;
369
                        } else if(nInc==-1 && nOldValue==0){
370
                            nOldValue = long(-1);
371
                        } else {
372
                            nOldValue+=nInc;
373
                        }
374
                        wxGetApp().GetConfigToolDoc()->SetValue(*this, nOldValue);
375
                        break;
376
                    }
377
                case ecEnumerated:
378
                    {
379
                        int nInc = 1;
380
 
381
                        wxArrayString arEnum;
382
                        EvalEnumStrings (arEnum); // calculate legal values just in time
383
                        if (0 == arEnum.GetCount()) // if no legal values...
384
                            break;           // ...do nothing
385
                        int nIndex = -1;
386
                        const wxString strCurrent = StringValue ();
387
                        int nEnum;
388
                        for (nEnum = 0; (nEnum < arEnum.GetCount()) && (nIndex == -1); nEnum++)
389
                            if (0 == arEnum[nEnum].CompareTo (strCurrent))
390
                                nIndex = nEnum; // the index of the current value
391
 
392
                            if (nIndex != -1) // if the current value is still legal
393
                                nIndex += (nInc < 0 ? -1 : 1); // increment/decrement the index
394
                            else
395
                                nIndex = 0; // otherwise select the first enum
396
 
397
                            if (nIndex < 0) // if the new index is negative
398
                                nIndex = arEnum.GetCount()-1; // make it positive
399
 
400
                            wxGetApp().GetConfigToolDoc()->SetValue(*this, arEnum[nIndex % arEnum.GetCount()]);
401
                            break;
402
                    }
403
                default:
404
                    {
405
                        break;
406
                    }
407
                }
408
            }
409
            break;
410
        }
411
    default:
412
        {
413
            break;
414
        }
415
    }
416
 
417
}
418
 
419
// Gets the value to display (often an empty string)
420
wxString ecConfigItem::GetDisplayValue() const
421
{
422
    wxString str;
423
    switch(GetOptionType())
424
    {
425
    case ecEnumerated:
426
    case ecLong:
427
    case ecDouble:
428
    case ecString:
429
        {
430
            if (GetCdlValuable())
431
                str = StringValue();
432
        }
433
        break;
434
    default:
435
        break;
436
    }
437
    return str;
438
#if 0
439
    switch (GetConfigType())
440
    {
441
        case ecComponent:
442
        case ecContainer:
443
            {
444
                return wxEmptyString;
445
                break;
446
            }
447
        case ecPackage:
448
            {
449
                return m_value.GetString();
450
                break;
451
            }
452
        case ecOption:
453
            {
454
                switch (GetOptionType())
455
                {
456
                    case ecDouble:
457
                        {
458
                            wxString val;
459
                            val.Printf("%.4lf", (double) m_value.GetDouble());
460
                            return val;
461
                        }
462
                    case ecLong:
463
                        {
464
                            wxString val;
465
                            val.Printf("%.ld", (long) m_value.GetLong());
466
                            return val;
467
                            break;
468
                        }
469
                    case ecEnumerated:
470
                    case ecString:
471
                        {
472
                            return m_value.GetString();
473
                            break;
474
                        }
475
                    case ecBool:
476
                        {
477
                            return wxEmptyString;
478
                            break;
479
                        }
480
                    default:
481
                        {
482
                            break;
483
                        }
484
                }
485
                break;
486
            }
487
        default:
488
            {
489
                break;
490
            }
491
    }
492
 
493
    return wxEmptyString;
494
#endif
495
}
496
 
497
// Can we start editing this item?
498
bool ecConfigItem::CanEdit() const
499
{
500
    if (!GetActive())
501
        return FALSE;
502
 
503
    if (GetConfigType() != ecOption)
504
        return FALSE;
505
 
506
    if (GetOptionFlavor() != ecFlavorData && GetOptionFlavor() != ecFlavorBoolData)
507
        return FALSE;
508
 
509
    // TODO: other criteria for editability
510
    return TRUE;
511
}
512
 
513
 
514
// Creates an edit window. It will be positioned by the caller.
515
wxWindow* ecConfigItem::CreateEditWindow(wxWindow* parent)
516
{
517
    wxWindow* window = NULL;
518
 
519
    switch(GetOptionType())
520
    {
521
    case ecEnumerated:
522
        {
523
            window = new ecEnumEditorCtrl(parent, ecID_ITEM_EDIT_WINDOW, wxDefaultPosition, wxDefaultSize,
524
                /* wxNO_BORDER */ 0);
525
            wxArrayString arEnumStrings;
526
            EvalEnumStrings(arEnumStrings);
527
            int i;
528
            for (i = 0; i < arEnumStrings.GetCount(); i++)
529
            {
530
                ((ecEnumEditorCtrl*) window)->Append(arEnumStrings[i]);
531
            }
532
            break;
533
        }
534
    case ecLong:
535
        {
536
            window = new ecIntegerEditorCtrl(parent, ecID_ITEM_EDIT_WINDOW, wxDefaultPosition, wxDefaultSize,
537
                /* wxNO_BORDER | */ wxSP_ARROW_KEYS);
538
            break;
539
        }
540
    case ecDouble:
541
        {
542
            window = new ecDoubleEditorCtrl(parent, ecID_ITEM_EDIT_WINDOW, wxDefaultPosition, wxDefaultSize,
543
                /* wxNO_BORDER|*/ wxTE_PROCESS_ENTER);
544
            break;
545
        }
546
    case ecString:
547
        {
548
            window = new ecTextEditorCtrl(parent, ecID_ITEM_EDIT_WINDOW, wxDefaultPosition, wxDefaultSize,
549
                /* wxNO_BORDER|*/ wxTE_PROCESS_ENTER);
550
            break;
551
        }
552
    default:
553
        break;
554
    }
555
 
556
    wxASSERT (window != NULL) ;
557
 
558
    return window;
559
}
560
 
561
// Transfers data between item and window
562
bool ecConfigItem::TransferDataToWindow(wxWindow* window)
563
{
564
    if (window->IsKindOf(CLASSINFO(ecTextEditorCtrl)))
565
    {
566
        ecTextEditorCtrl* win = (ecTextEditorCtrl*) window;
567
        win->SetValue(GetDisplayValue());
568
    }
569
    else if (window->IsKindOf(CLASSINFO(ecDoubleEditorCtrl)))
570
    {
571
        ecDoubleEditorCtrl* win = (ecDoubleEditorCtrl*) window;
572
        win->SetValue(GetDisplayValue());
573
    }
574
    else if (window->IsKindOf(CLASSINFO(ecEnumEditorCtrl)))
575
    {
576
        ecEnumEditorCtrl* win = (ecEnumEditorCtrl*) window;
577
        win->SetStringSelection(GetDisplayValue());
578
    }
579
    else if (window->IsKindOf(CLASSINFO(ecIntegerEditorCtrl)))
580
    {
581
        ecIntegerEditorCtrl* win = (ecIntegerEditorCtrl*) window;
582
        long i;
583
        ecUtils::StrToItemIntegerType(StringValue(), i);
584
 
585
        wxString val;
586
        val.Printf(wxT("%ld"), i);
587
 
588
        win->SetValue(val);
589
    }
590
    return TRUE;
591
}
592
 
593
bool ecConfigItem::TransferDataFromWindow(wxWindow* window)
594
{
595
    ecConfigToolDoc* doc = wxGetApp().GetConfigToolDoc();
596
    wxASSERT (doc != NULL);
597
 
598
    if (!doc)
599
        return FALSE;
600
 
601
    if (window->IsKindOf(CLASSINFO(ecTextEditorCtrl)))
602
    {
603
        ecTextEditorCtrl* win = (ecTextEditorCtrl*) window;
604
 
605
        wxASSERT ( GetOptionType() == ecString );
606
 
607
        // TODO: do checking
608
        doc->SetValue(*this, win->GetValue());
609
    }
610
    else if (window->IsKindOf(CLASSINFO(ecDoubleEditorCtrl)))
611
    {
612
        ecDoubleEditorCtrl* win = (ecDoubleEditorCtrl*) window;
613
 
614
        wxASSERT ( GetOptionType() == ecString );
615
 
616
        // TODO: do checking
617
        doc->SetValue(*this, atof(win->GetValue()));
618
    }
619
    else if (window->IsKindOf(CLASSINFO(ecEnumEditorCtrl)))
620
    {
621
        ecEnumEditorCtrl* win = (ecEnumEditorCtrl*) window;
622
 
623
        wxASSERT ( GetOptionType() == ecEnumerated );
624
 
625
        // TODO: do checking
626
        doc->SetValue(*this, win->GetStringSelection());
627
    }
628
    else if (window->IsKindOf(CLASSINFO(ecIntegerEditorCtrl)))
629
    {
630
        ecIntegerEditorCtrl* win = (ecIntegerEditorCtrl*) window;
631
 
632
        wxASSERT ( GetOptionType() == ecLong );
633
 
634
        // TODO: do checking
635
        doc->SetValue(*this, (long) win->GetValue());
636
    }
637
 
638
    return TRUE;
639
}
640
 
641
//// Taken from MFC version
642
 
643
const ecFileName ecConfigItem::GetFilename() const
644
{
645
    wxString sep(wxFILE_SEP_PATH);
646
 
647
    ecFileName strFile;
648
    const CdlNode node = dynamic_cast<CdlNode> (m_CdlItem);
649
    if (node){
650
        // get the package which owns the configuration item
651
        const CdlPackage package = GetOwnerPackage();
652
        if (package){
653
 
654
            // return the filename of the config header
655
            wxString pkg(wxT("include"));
656
            pkg += sep;
657
            pkg += wxT("pkgconf");
658
            strFile=ecFileName(wxGetApp().GetConfigToolDoc()->GetInstallTree()+sep+pkg) + package->get_config_header ().c_str ();
659
        }
660
    }
661
    return strFile;
662
}
663
 
664
// Change version (of a package)
665
bool ecConfigItem::ChangeVersion(const wxString &strVersion)
666
{
667
    bool rc=FALSE;
668
    CdlPackage package=dynamic_cast<CdlPackage>(GetCdlItem());
669
    wxASSERT(package != 0);
670
    const CdlValuable valuable = GetCdlValuable();
671
    wxASSERT (valuable != 0);
672
    const wxString strMacroName(GetMacro());
673
    if (strVersion != valuable->get_value ().c_str ()) { // if the wrong version is loaded
674
        // TRACE (wxT("Changing package %s to version '%s'\n"), strMacroName, strVersion);
675
        try {
676
            wxGetApp().GetConfigToolDoc()->GetCdlConfig()->change_package_version (package, ecUtils::UnicodeToStdStr (strVersion), ecConfigToolDoc::CdlParseErrorHandler, ecConfigToolDoc::CdlParseWarningHandler);
677
            rc=TRUE;
678
        }
679
        catch (CdlStringException exception) {
680
            wxString msg;
681
            msg.Printf(wxT("Error changing package %s to version '%s':\n\n%s"), (const wxChar*) strMacroName, (const wxChar*) strVersion, (const wxChar*) wxString (exception.get_message ().c_str ())) ;
682
            wxMessageBox(msg);
683
        }
684
        catch (...) {
685
            wxString msg;
686
            msg.Printf(wxT("Error changing package %s to version '%s'"), (const wxChar*) strMacroName, (const wxChar*) strVersion) ;
687
            wxMessageBox(msg);
688
        }
689
    }
690
    return rc;
691
}
692
 
693
// Unload (a package)
694
bool ecConfigItem::Unload()
695
{
696
    bool rc=FALSE;
697
    CdlPackage package=dynamic_cast<CdlPackage>(GetCdlItem());
698
    wxASSERT(package);
699
    ecConfigToolDoc* pDoc=wxGetApp().GetConfigToolDoc();
700
 
701
    // Remove its objects from the view to prevent any painting problems
702
    ecTreeItemData* data = (ecTreeItemData*) wxGetApp().GetTreeCtrl()->GetItemData(GetTreeItem());
703
    wxASSERT(data);
704
 
705
    // I _think_ we should do this to stop 'this' from being deleted when we delete the item.
706
    // But, in that case, where do we delete this item?
707
    // Perhaps should store them in an array in the document, as per the MFC tool.
708
    data->SetConfigItem(NULL);
709
 
710
    wxGetApp().GetTreeCtrl()->Delete(GetTreeItem());
711
 
712
    wxNode* node = pDoc->GetItems().First();
713
    while (node)
714
    {
715
        ecConfigItem* item = wxDynamicCast(node->Data(), ecConfigItem);
716
        if (package == item->GetOwnerPackage())
717
        {
718
            item->SetTreeItem(wxTreeItemId()); // Make sure we can't attempt to paint it
719
            item->SetCdlItem(NULL); // Make sure we can't access stale data
720
        }
721
        node = node->Next();
722
    }
723
 
724
    const wxString strMacroName(GetMacro());
725
    //TRACE (wxT("Unloading package %s\n"), strMacroName);
726
    try {
727
        pDoc->GetCdlConfig()->unload_package (package);
728
        rc=TRUE;
729
    }
730
    catch (CdlStringException exception) {
731
        wxString msg;
732
        wxString exceptionMsg(exception.get_message ().c_str ());
733
        msg.Printf(wxT("Error unloading package %s:\n\n%s"), (const wxChar*) strMacroName, (const wxChar*) exceptionMsg );
734
        wxMessageBox(msg);
735
    }
736
    catch (...) {
737
        wxString msg;
738
        msg.Printf(wxT("Error unloading package %s"), (const wxChar*) strMacroName);
739
        wxMessageBox(msg);
740
    }
741
    m_treeItem=wxTreeItemId();   // Make sure we can't attempt to paint it
742
    m_CdlItem=NULL; // Make sure we can't access stale data
743
    return rc;
744
}
745
 
746
wxString ecConfigItem::GetURL() const
747
{
748
    for(const ecConfigItem *pItem=this;pItem;pItem=pItem->GetParent()){
749
        if(pItem->GetCdlItem()){
750
            wxString strURL;
751
            strURL=pItem->GetCdlItem()->get_doc_url().c_str();
752
            if(strURL.Len()){
753
                return strURL;
754
            }
755
            strURL=pItem->GetCdlItem()->get_doc().c_str();
756
            if(strURL.Len()){
757
                return strURL;
758
            }
759
        }
760
    }
761
    return wxT("ref/ecos-ref.html"); // the default URL
762
}
763
 
764
bool ecConfigItem::SetValue(const wxString& value, CdlTransaction transaction/*=NULL*/)
765
{
766
    wxASSERT ((m_optionType == ecString) || (m_optionType == ecEnumerated));
767
    const CdlValuable valuable = GetCdlValuable();
768
    wxASSERT (valuable);
769
    const std::string str = value.c_str();
770
    if(transaction){
771
        if (CdlValueFlavor_BoolData == valuable->get_flavor ()){
772
            // set the user bool to the current bool when changing a booldata
773
            // value to avoid a possible change in the current bool
774
            valuable->set_enabled_and_value (transaction, valuable->is_enabled (), str, CdlValueSource_User);
775
        } else {// CdlValueFlavor_Data
776
            valuable->set_value (transaction, str, CdlValueSource_User);
777
        }
778
    } else {
779
        if (CdlValueFlavor_BoolData == valuable->get_flavor ()){
780
            // set the user bool to the current bool when changing a booldata
781
            // value to avoid a possible change in the current bool
782
            valuable->set_enabled_and_value (valuable->is_enabled (), str, CdlValueSource_User);
783
        } else {// CdlValueFlavor_Data
784
            valuable->set_value (str, CdlValueSource_User);
785
        }
786
    }
787
 
788
    // TODO: eliminate m_value, since the value is always taken from the Cdl object.
789
    m_value = value;
790
 
791
    return TRUE;
792
}
793
 
794
bool ecConfigItem::SetValue (double dValue, CdlTransaction transaction/*=NULL*/)
795
{
796
    wxASSERT (m_optionType == ecDouble);
797
 
798
    const CdlValuable valuable = GetCdlValuable();
799
    wxASSERT (valuable);
800
 
801
    if(transaction) {
802
        if (CdlValueFlavor_BoolData == valuable->get_flavor ()) {
803
            // set the user bool to the current bool when changing a booldata
804
            // value to avoid a possible change in the current bool
805
            valuable->set_enabled_and_value (transaction, valuable->is_enabled (), dValue, CdlValueSource_User);
806
        } else {// CdlValueFlavor_Data
807
            valuable->set_double_value (transaction, dValue, CdlValueSource_User);
808
        }
809
    } else {
810
        if (CdlValueFlavor_BoolData == valuable->get_flavor ()) {
811
            // set the user bool to the current bool when changing a booldata
812
            // value to avoid a possible change in the current bool
813
            valuable->set_enabled_and_value (valuable->is_enabled (), dValue, CdlValueSource_User);
814
        } else {// CdlValueFlavor_Data
815
            valuable->set_double_value (dValue, CdlValueSource_User);
816
        }
817
    }
818
 
819
    // TODO: BoolData?
820
    m_value = dValue;
821
 
822
    return TRUE;
823
}
824
 
825
bool ecConfigItem::SetValue (long nValue, CdlTransaction transaction/*=NULL*/)
826
{
827
    wxASSERT (m_optionType == ecLong);
828
    const CdlValuable valuable = GetCdlValuable();
829
    wxASSERT (valuable);
830
 
831
    if(transaction) {
832
        if (CdlValueFlavor_BoolData == valuable->get_flavor ()) {
833
            // set the user bool to the current bool when changing a booldata
834
            // value to avoid a possible change in the current bool
835
            valuable->set_enabled_and_value (transaction, valuable->is_enabled (), (cdl_int) nValue, CdlValueSource_User);
836
        } else { // CdlValueFlavor_Data
837
            valuable->set_integer_value (transaction, nValue, CdlValueSource_User);
838
        }
839
    } else {
840
        if (CdlValueFlavor_BoolData == valuable->get_flavor ()) {
841
            // set the user bool to the current bool when changing a booldata
842
            // value to avoid a possible change in the current bool
843
            valuable->set_enabled_and_value (valuable->is_enabled (), (cdl_int) nValue, CdlValueSource_User);
844
        } else { // CdlValueFlavor_Data
845
            valuable->set_integer_value (nValue, CdlValueSource_User);
846
        }
847
    }
848
 
849
    // TODO: BoolData?
850
    m_value = nValue;
851
 
852
    return TRUE;
853
}
854
 
855
bool ecConfigItem::HasRadio() const
856
{
857
    const CdlValuable valuable = GetCdlValuable();
858
    if (! valuable)
859
        return FALSE;
860
 
861
    CdlWidgetHint hint;
862
    valuable->get_widget_hint (hint);
863
    return (CdlBoolWidget_Radio == hint.bool_widget);
864
}
865
 
866
ecConfigItem *ecConfigItem::FirstRadio() const
867
{
868
    wxASSERT(HasRadio ());
869
 
870
    for(ecConfigItem *h=GetParent()->FirstChild();h;h=h->NextSibling()){
871
        if(h->HasRadio ()){
872
            return h;
873
        }
874
    }
875
    // No radio buttons found
876
    wxASSERT(FALSE);
877
    return FALSE;
878
}
879
 
880
ecConfigItem *ecConfigItem::FirstChild() const
881
{
882
    ecConfigTreeCtrl* treeCtrl = wxGetApp().GetTreeCtrl();
883
 
884
    long cookie;
885
    wxTreeItemId hChild=treeCtrl->GetFirstChild(GetTreeItem(), cookie);
886
    if (hChild)
887
    {
888
        ecTreeItemData* data = (ecTreeItemData*) wxGetApp().GetTreeCtrl()->GetItemData(hChild);
889
        wxASSERT(data);
890
 
891
        return data->GetConfigItem();
892
    }
893
    else
894
        return NULL;
895
}
896
 
897
ecConfigItem *ecConfigItem::NextSibling() const
898
{
899
    ecConfigTreeCtrl* treeCtrl = wxGetApp().GetTreeCtrl();
900
 
901
    wxTreeItemId hChild=treeCtrl->GetNextSibling(GetTreeItem());
902
    if (hChild)
903
    {
904
        ecTreeItemData* data = (ecTreeItemData*) wxGetApp().GetTreeCtrl()->GetItemData(hChild);
905
        wxASSERT(data);
906
 
907
        return data->GetConfigItem();
908
    }
909
    else
910
        return NULL;
911
}
912
 
913
bool ecConfigItem::IsEnabled() const
914
{
915
    const CdlValuable valuable = GetCdlValuable();
916
    return NULL==valuable ||valuable->is_enabled();
917
}
918
 
919
bool ecConfigItem::IsActive() const
920
{
921
//    return GetCdlItem()->is_active();
922
    const CdlValuable valuable = GetCdlValuable();
923
    if (valuable && ((GetOptionType() != ecOptionTypeNone) || HasBool()))
924
    {
925
        return (valuable->is_modifiable () && valuable->is_active ());
926
    }
927
    else
928
        return GetCdlItem()->is_active();
929
}
930
 
931
bool ecConfigItem::HasModifiedChildren() const
932
{
933
    for(ecConfigItem *pItem=FirstChild();pItem;pItem=pItem->NextSibling()){
934
        if(pItem->Modified()||pItem->HasModifiedChildren()){
935
            return TRUE;
936
        }
937
    }
938
    return FALSE;
939
}
940
 
941
bool ecConfigItem::Modified () const
942
{
943
    const CdlValuable valuable = GetCdlValuable();
944
    return
945
        valuable        // accommodate the root config item which has no CDL item
946
        && !IsPackage() // packages are never modified
947
        && valuable->get_source () != CdlValueSource_Default;
948
}
949
 
950
void ecConfigItem::DumpItem()
951
{
952
    //TRACE(wxT("Item %08x\n\tDisplay Name='%s'\n\tMacro Name='%s'\n\tType=%s"), this,  Name(),           Macro(),    TreeItemTypeImage[m_Type]);
953
    //TRACE(wxT("\n\tValue=%s\n\tURL=%s\n\tParent=%08x"),StringValue(), GetURL(), Parent());
954
 
955
    //TRACE(wxT("\n"));
956
}
957
 
958
ecConfigItem * ecConfigItem::NextRadio() const
959
{
960
    wxASSERT(this->HasRadio ());
961
    for(ecConfigItem *pItem=NextSibling();pItem;pItem=pItem->NextSibling()){
962
        if(pItem->HasRadio()){
963
            return pItem;
964
        }
965
    }
966
    return NULL;
967
}
968
 
969
bool ecConfigItem::IsDescendantOf(ecConfigItem * pAncestor)
970
{
971
    for(ecConfigItem *pItem=GetParent();pItem;pItem=pItem->GetParent()){
972
        if(pItem==pAncestor){
973
            return TRUE;
974
        }
975
    }
976
    return FALSE;
977
}
978
 
979
bool ecConfigItem::ViewHeader()
980
{
981
    bool rc=FALSE;
982
    const ecFileName strFile(GetFilename());
983
    if(!strFile.IsEmpty())
984
    {
985
        ecConfigToolDoc *pDoc=wxGetApp().GetConfigToolDoc();
986
        if(pDoc->GetBuildTree().IsEmpty()){
987
            wxString msg;
988
            msg.Printf(wxT("Cannot display header file until configuration is saved"));
989
            wxMessageBox(msg);
990
        } else
991
        {
992
            rc=wxGetApp().Launch(strFile, wxGetApp().GetSettings().m_strViewer);
993
        }
994
    }
995
    return rc;
996
}
997
 
998
bool ecConfigItem::ViewURL()
999
{
1000
    return wxGetApp().GetConfigToolDoc()->ShowURL(GetURL());
1001
}
1002
 
1003
bool ecConfigItem::HasBool() const
1004
{
1005
    if (!m_CdlItem) {
1006
        return FALSE;
1007
    } else if (IsPackage()) {
1008
        return FALSE;
1009
    } else {
1010
        const CdlValuable valuable = GetCdlValuable();
1011
        CdlValueFlavor flavor = valuable->get_flavor ();
1012
        return (flavor == CdlValueFlavor_Bool) || (flavor == CdlValueFlavor_BoolData);
1013
    }
1014
}
1015
 
1016
bool ecConfigItem::SetEnabled(bool bEnabled, CdlTransaction current_transaction/*=NULL*/)
1017
{
1018
    const CdlValuable valuable = GetCdlValuable();
1019
    wxASSERT (valuable);
1020
 
1021
    // use a transaction object to ensure that all config items are changed together
1022
    CdlTransaction transaction = current_transaction ? current_transaction : CdlTransactionBody::make (wxGetApp().GetConfigToolDoc ()->GetCdlConfig ());
1023
 
1024
    if (HasRadio () && bEnabled) { // if a new radio button has been selected
1025
        for (ecConfigItem *pItem = FirstRadio(); pItem; pItem = pItem->NextRadio ()) { // for each radio button in the group
1026
            if (pItem != this) { // if not the newly selected radio button
1027
                pItem->SetEnabled (FALSE, transaction); // disable the radio button
1028
            }
1029
        }
1030
    }
1031
 
1032
    if (CdlValueFlavor_BoolData == valuable->get_flavor ()) {
1033
        // set the user value to the current data value when enabling/disabling
1034
        // a booldata item to avoid a possible change in the current data value
1035
        CdlSimpleValue simple_value = valuable->get_simple_value ();
1036
        valuable->set_enabled_and_value (transaction, bEnabled, simple_value, CdlValueSource_User);
1037
    } else { // CdlValueFlavor_Bool
1038
        valuable->set_enabled (transaction, bEnabled, CdlValueSource_User);
1039
    }
1040
 
1041
    if (! current_transaction) { // if not a recursive call to disable a radio button
1042
        transaction->body (); // commit the transaction
1043
        delete transaction;
1044
        transaction = NULL;
1045
    }
1046
 
1047
    return TRUE;
1048
}
1049
 
1050
long ecConfigItem::DefaultValue () const
1051
{
1052
    return (long) atoi (StringValue (CdlValueSource_Default)) ;
1053
}
1054
 
1055
long ecConfigItem::Value () const
1056
{
1057
    wxASSERT (!IsPackage()); // not a package item
1058
    const CdlValuable valuable = GetCdlValuable();
1059
    wxASSERT (valuable);
1060
    long nValue (0);
1061
 
1062
    switch (valuable->get_flavor ())
1063
    {
1064
        //      case CdlValueFlavor_Bool:
1065
        //              nValue = valuable->is_enabled (CdlValueSource_Current) ? 1 : 0;
1066
        //              break;
1067
 
1068
    case CdlValueFlavor_BoolData:
1069
    case CdlValueFlavor_Data:
1070
        nValue = (long) valuable->get_integer_value (CdlValueSource_Current);
1071
        break;
1072
 
1073
    default:
1074
        wxASSERT (0); // specified flavor not supported
1075
    }
1076
 
1077
    return nValue;
1078
}
1079
 
1080
const double ecConfigItem::DoubleValue (CdlValueSource source /* = CdlValueSource_Current */ ) const
1081
{
1082
    wxASSERT (!IsPackage()); // not a package item
1083
    const CdlValuable valuable = GetCdlValuable();
1084
    wxASSERT (valuable);
1085
    wxASSERT (valuable->has_double_value (source));
1086
    return valuable->get_double_value (source);
1087
}
1088
 
1089
const wxString ecConfigItem::StringValue (CdlValueSource source /* = CdlValueSource_Current */ ) const
1090
{
1091
    //  wxASSERT (!IsPackage()); // not a package item
1092
    const CdlValuable valuable = GetCdlValuable();
1093
    wxASSERT (valuable);
1094
    wxString strValue (wxT(""));
1095
 
1096
    switch (valuable->get_flavor ())
1097
    {
1098
    case CdlValueFlavor_Data:
1099
    case CdlValueFlavor_BoolData:
1100
    case CdlValueFlavor_None: // a package
1101
        if (m_optionType == ecLong)
1102
            strValue = ecUtils::IntToStr (Value (), wxGetApp().GetSettings().m_bHex);
1103
        else if (m_optionType == ecDouble)
1104
            strValue = ecUtils::DoubleToStr (DoubleValue ());
1105
        else
1106
            strValue = valuable->get_value (source).c_str ();
1107
        break;
1108
 
1109
    default:
1110
        wxASSERT (0); // specified flavor not supported
1111
    }
1112
 
1113
    return strValue;
1114
}
1115
 
1116
const wxString ecConfigItem::StringValue(ecWhereType where) const
1117
{
1118
    wxString str;
1119
    switch(where){
1120
    case ecInName:
1121
        str=GetName();
1122
        break;
1123
    case ecInMacro:
1124
        str=GetMacro();
1125
        break;
1126
    case ecInDesc:
1127
        str=GetDescription();
1128
        break;
1129
    case ecInCurrentValue:
1130
        if (ecOptionTypeNone==GetOptionType())
1131
            str = wxEmptyString;
1132
        else
1133
            str = StringValue(CdlValueSource_Current);
1134
        break;
1135
    case ecInDefaultValue:
1136
        if (ecOptionTypeNone==GetOptionType())
1137
            str = wxEmptyString;
1138
        else
1139
            str = StringValue(CdlValueSource_Default);
1140
        break;
1141
    default:
1142
        wxASSERT(FALSE);
1143
        break;
1144
    }
1145
    return str;
1146
}
1147
 
1148
int ecConfigItem::EvalEnumStrings (wxArrayString &arEnumStrings) const
1149
{
1150
    const CdlValuable valuable = GetCdlValuable();
1151
    wxASSERT (valuable);
1152
    /*
1153
    if (m_Type == Boolean)
1154
    {
1155
    arEnumStrings.SetSize (2);
1156
    arEnumStrings.SetAt (0, wxT("True"));
1157
    arEnumStrings.SetAt (1, wxT("False"));
1158
    }
1159
    else
1160
    */
1161
    {
1162
        wxASSERT (m_optionType == ecEnumerated);
1163
        CdlListValue list_value;
1164
        CdlEvalContext context (NULL, m_CdlItem, m_CdlItem->get_property (CdlPropertyId_LegalValues));
1165
        valuable->get_legal_values ()->eval (context, list_value);
1166
        const std::vector<CdlSimpleValue> & table = list_value.get_table ();
1167
 
1168
        // add legal values to the list
1169
        for (unsigned int nValue = 0; nValue < table.size (); nValue++)
1170
        {
1171
            arEnumStrings.Add (table [nValue].get_value ().c_str ());
1172
        }
1173
    }
1174
    return arEnumStrings.GetCount();
1175
}
1176
 
1177
static const wxChar* gs_whereTypes[] =
1178
{
1179
        _("Macro names"),
1180
        _("Item names"),
1181
        _("Short descriptions"),
1182
        _("Current Values"),
1183
        _("Default Values")
1184
};
1185
 
1186
// Convert a string representation of 'where' (e.g. "Macro names") to
1187
// ecWhereType
1188
ecWhereType ecConfigItem::WhereStringToType(const wxString& whereString)
1189
{
1190
    int sz = 5;
1191
    int i;
1192
    for (i = 0; i < sz; i++)
1193
        if (whereString == gs_whereTypes[i])
1194
            return (ecWhereType) i;
1195
 
1196
    wxASSERT( FALSE );
1197
 
1198
    return (ecWhereType) 0;
1199
}
1200
 
1201
// Convert a type representation of 'where' to a string
1202
wxString ecConfigItem::WhereTypeToString(ecWhereType whereType)
1203
{
1204
    return gs_whereTypes[(size_t) whereType] ;
1205
}
1206
 
1207
// Bump by specified amount, or toggle if a boolean value
1208
bool ecConfigItem::BumpItem(int nInc)
1209
{
1210
    bool rc = FALSE;
1211
 
1212
    // Take an action for clicking on the icon
1213
    ecConfigToolDoc* pDoc = wxGetApp().GetConfigToolDoc();
1214
 
1215
    // do not modify the option value if it is inactive or not modifiable
1216
    const CdlValuable valuable = GetCdlValuable();
1217
    if (!valuable || (valuable->is_modifiable () && valuable->is_active ()))
1218
    {
1219
        if (0 == nInc) // if a toggle request
1220
        {
1221
            if (HasBool () && ! (HasRadio () && IsEnabled ())) { // only enable (not disable) a radio button
1222
                rc = pDoc->SetEnabled (*this, ! this->IsEnabled ()); // toggle enabled/disabled state
1223
            }
1224
        } else if (IsEnabled ()) { // the item is enabled...
1225
            switch(GetOptionType())
1226
            {
1227
            case ecOptionTypeNone:
1228
            case ecString:
1229
            case ecDouble:
1230
                break;
1231
            case ecEnumerated:
1232
                {
1233
                    wxArrayString arEnum;
1234
                    EvalEnumStrings (arEnum); // calculate legal values just in time
1235
                    if (0==arEnum.Count()) // if no legal values...
1236
                        break;           // ...do nothing
1237
                    int nIndex = -1;
1238
                    const wxString strCurrent = StringValue ();
1239
                    int nEnum;
1240
                    for (nEnum = 0; (nEnum < arEnum.Count()) && (nIndex == -1); nEnum++)
1241
                        if (strCurrent == arEnum[nEnum])
1242
                            nIndex = nEnum; // the index of the current value
1243
 
1244
                        if (nIndex != -1) // if the current value is still legal
1245
                            nIndex += (nInc < 0 ? -1 : 1); // increment/decrement the index
1246
                        else
1247
                            nIndex = 0; // otherwise select the first enum
1248
 
1249
                        if (nIndex < 0) // if the new index is negative
1250
                            nIndex = arEnum.Count()-1; // make it positive
1251
 
1252
                        rc=pDoc->SetValue (*this, arEnum[nIndex % arEnum.Count()]);
1253
                }
1254
                break;
1255
            case ecLong:
1256
                {
1257
                    // TODO: if we're editing, we should get the value in the edit item
1258
                    // and not the ecConfigItem.
1259
                    long nOldValue = Value();
1260
                    if(nInc==1 && nOldValue==-1){
1261
                        nOldValue=0;
1262
                    } else if(nInc==-1 && nOldValue==0){
1263
                        nOldValue=-1;
1264
                    } else {
1265
                        nOldValue+=nInc;
1266
                    }
1267
                    rc=pDoc->SetValue(*this, nOldValue);
1268
                    break;
1269
                }
1270
 
1271
                break;
1272
                /*
1273
                case CConfigItem::Boolean:
1274
 
1275
                  {
1276
                  ItemIntegerType nOldValue=Value(h);
1277
                  pDoc->SetValue(ti,nOldValue^1);
1278
                  }
1279
                  break;
1280
                  case CConfigItem::Radio:
1281
 
1282
                    if(0==Value(h)){
1283
                    pDoc->SetValue(ti, (ItemIntegerType) 1);
1284
                    }
1285
                    break;
1286
                */
1287
            default:
1288
                break;
1289
            }
1290
        }
1291
    }
1292
    return rc;
1293
}
1294
 
1295
#if 0
1296
 
1297
/* Presumably we don't need this since we use the m_parent member instead
1298
ecConfigItem *ecConfigItem::Parent() const
1299
{
1300
    CTreeCtrl &tree=CConfigTool::GetControlView()->GetTreeCtrl();
1301
    HTREEITEM hParent=tree.GetParentItem(HItem());
1302
    return (NULL==hParent||TVI_ROOT==hParent)?NULL:(ecConfigItem *)tree.GetItemData(hParent);
1303
}
1304
*/
1305
 
1306
#endif
1307
 
1308
/*
1309
 * ecTextEditorCtrl
1310
 * A specialised wxTextCtrl, for editing config values
1311
 */
1312
 
1313
BEGIN_EVENT_TABLE(ecTextEditorCtrl, wxTextCtrl)
1314
    EVT_TEXT_ENTER(-1, ecTextEditorCtrl::OnEnter)
1315
    EVT_KILL_FOCUS(ecTextEditorCtrl::OnKillFocus)
1316
    EVT_LEFT_DCLICK(ecTextEditorCtrl::OnLeftDClick)
1317
END_EVENT_TABLE()
1318
 
1319
IMPLEMENT_CLASS(ecTextEditorCtrl, wxTextCtrl)
1320
 
1321
ecTextEditorCtrl::ecTextEditorCtrl(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size,
1322
                                   long style):
1323
    wxTextCtrl(parent, id, wxEmptyString, pos, size, style)
1324
{
1325
}
1326
 
1327
void ecTextEditorCtrl::OnEnter(wxCommandEvent& event)
1328
{
1329
    ecValueWindow* parent = (ecValueWindow*) GetParent();
1330
    parent->EndEditing();
1331
}
1332
 
1333
void ecTextEditorCtrl::OnKillFocus(wxFocusEvent& event)
1334
{
1335
    ecValueWindow* parent = (ecValueWindow*) GetParent();
1336
    parent->EndEditing();
1337
}
1338
 
1339
// Edit the string in a separate dialog, for convenience
1340
void ecTextEditorCtrl::OnLeftDClick(wxMouseEvent& event)
1341
{
1342
    ecValueWindow* parent = (ecValueWindow*) GetParent();
1343
    ecConfigItem* item = parent->GetCurrentConfigItem();
1344
    ecConfigToolDoc* doc = wxGetApp().GetConfigToolDoc();
1345
 
1346
    wxString initialValue(GetValue());
1347
 
1348
    ecEditStringDialog dialog(initialValue, wxGetApp().GetTopWindow(), ecID_EDIT_STRING_DIALOG);
1349
    if (dialog.ShowModal() == wxID_OK)
1350
    {
1351
        wxString val = dialog.GetValue() ;
1352
        // This control will have been deleted at this point, due to losing the focus.
1353
        // So update the item, not the control.
1354
        // wxTextCtrl::SetValue(val);
1355
        doc->SetValue(*item, val);
1356
    }
1357
}
1358
 
1359
/*
1360
 * ecDoubleEditorCtrl
1361
 * A specialised wxTextCtrl, for editing double config values
1362
 */
1363
 
1364
BEGIN_EVENT_TABLE(ecDoubleEditorCtrl, wxTextCtrl)
1365
    EVT_TEXT_ENTER(-1, ecDoubleEditorCtrl::OnEnter)
1366
    EVT_KILL_FOCUS(ecDoubleEditorCtrl::OnKillFocus)
1367
END_EVENT_TABLE()
1368
 
1369
IMPLEMENT_CLASS(ecDoubleEditorCtrl, wxTextCtrl)
1370
 
1371
ecDoubleEditorCtrl::ecDoubleEditorCtrl(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size,
1372
                                   long style):
1373
    wxTextCtrl(parent, id, wxEmptyString, pos, size, style)
1374
{
1375
}
1376
 
1377
void ecDoubleEditorCtrl::OnEnter(wxCommandEvent& event)
1378
{
1379
    ecValueWindow* parent = (ecValueWindow*) GetParent();
1380
    parent->EndEditing();
1381
}
1382
 
1383
void ecDoubleEditorCtrl::OnKillFocus(wxFocusEvent& event)
1384
{
1385
    ecValueWindow* parent = (ecValueWindow*) GetParent();
1386
    parent->EndEditing();
1387
}
1388
 
1389
/*
1390
 * ecIntegerEditorCtrl
1391
 * A specialised wxTextCtrl, for editing double config values
1392
 */
1393
 
1394
BEGIN_EVENT_TABLE(ecIntegerEditorCtrl, wxSpinCtrl)
1395
    EVT_TEXT_ENTER(-1, ecIntegerEditorCtrl::OnEnter)
1396
    EVT_KILL_FOCUS(ecIntegerEditorCtrl::OnKillFocus)
1397
END_EVENT_TABLE()
1398
 
1399
IMPLEMENT_CLASS(ecIntegerEditorCtrl, wxSpinCtrl)
1400
 
1401
ecIntegerEditorCtrl::ecIntegerEditorCtrl(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size,
1402
                                   long style):
1403
    wxSpinCtrl(parent, id, wxEmptyString, pos, size, style, -32000, 32000, 0)
1404
{
1405
}
1406
 
1407
void ecIntegerEditorCtrl::OnEnter(wxCommandEvent& event)
1408
{
1409
    ecValueWindow* parent = (ecValueWindow*) GetParent();
1410
    parent->EndEditing();
1411
}
1412
 
1413
void ecIntegerEditorCtrl::OnKillFocus(wxFocusEvent& event)
1414
{
1415
    ecValueWindow* parent = (ecValueWindow*) GetParent();
1416
    parent->EndEditing();
1417
}
1418
 
1419
/*
1420
 * ecEnumEditorCtrl
1421
 * A specialised wxChoice, for editing enumerated config values
1422
 */
1423
 
1424
BEGIN_EVENT_TABLE(ecEnumEditorCtrl, wxChoice)
1425
    EVT_CHAR(ecEnumEditorCtrl::OnChar)
1426
    EVT_KILL_FOCUS(ecEnumEditorCtrl::OnKillFocus)
1427
END_EVENT_TABLE()
1428
 
1429
IMPLEMENT_CLASS(ecEnumEditorCtrl, wxChoice)
1430
 
1431
ecEnumEditorCtrl::ecEnumEditorCtrl(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size,
1432
                                   long style):
1433
    wxChoice(parent, id, pos, size, 0, 0, style)
1434
{
1435
}
1436
 
1437
void ecEnumEditorCtrl::OnChar(wxKeyEvent& event)
1438
{
1439
    if (event.GetKeyCode() == WXK_RETURN)
1440
    {
1441
        ecValueWindow* parent = (ecValueWindow*) GetParent();
1442
        parent->EndEditing();
1443
    }
1444
    else
1445
        event.Skip();
1446
}
1447
 
1448
void ecEnumEditorCtrl::OnKillFocus(wxFocusEvent& event)
1449
{
1450
    ecValueWindow* parent = (ecValueWindow*) GetParent();
1451
    parent->EndEditing();
1452
}
1453
 
1454
/*
1455
 * ecEditStringDialog
1456
 * Pops up to make it easier to edit large string values
1457
 */
1458
 
1459
BEGIN_EVENT_TABLE(ecEditStringDialog, ecDialog)
1460
    EVT_BUTTON(wxID_OK, ecEditStringDialog::OnOK)
1461
END_EVENT_TABLE()
1462
 
1463
ecEditStringDialog::ecEditStringDialog(const wxString& initialValue, wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size,
1464
        long style)
1465
{
1466
    m_value = initialValue;
1467
    //SetExtraStyle(wxDIALOG_EX_CONTEXTHELP);
1468
 
1469
    ecDialog::Create(parent, id, _("String Edit"),
1470
        wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER);
1471
 
1472
    CreateControls(this);
1473
 
1474
    TransferDataToWindow();
1475
 
1476
    Centre(wxBOTH);
1477
}
1478
 
1479
ecEditStringDialog::~ecEditStringDialog()
1480
{
1481
}
1482
 
1483
//// Event handlers
1484
 
1485
void ecEditStringDialog::OnOK(wxCommandEvent& event)
1486
{
1487
    wxDialog::OnOK(event);
1488
}
1489
 
1490
//// Operations
1491
void ecEditStringDialog::CreateControls(wxWindow* parent)
1492
{
1493
    wxSizer *item0 = new wxBoxSizer( wxVERTICAL );
1494
 
1495
    wxSizer *item1 = new wxBoxSizer( wxHORIZONTAL );
1496
 
1497
    item1->Add( 20, 20, 10, wxALIGN_CENTRE|wxALL, 5 );
1498
 
1499
    wxButton *item2 = new wxButton( parent, wxID_OK, _("&OK"), wxDefaultPosition, wxDefaultSize, 0 );
1500
    item2->SetDefault();
1501
    item1->Add( item2, 0, wxALIGN_CENTRE|wxALL, 5 );
1502
 
1503
    wxButton *item3 = new wxButton( parent, wxID_CANCEL, _("&Cancel"), wxDefaultPosition, wxDefaultSize, 0 );
1504
    item1->Add( item3, 0, wxALIGN_CENTRE|wxALL, 5 );
1505
 
1506
    item0->Add( item1, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxTOP, 5 );
1507
 
1508
    wxTextCtrl *item4 = new wxTextCtrl( parent, ecID_STRING_EDIT_TEXTCTRL, _(""), wxDefaultPosition, wxSize(420,250), wxTE_MULTILINE );
1509
    item0->Add( item4, 1, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxBOTTOM, 5 );
1510
 
1511
    parent->SetAutoLayout( TRUE );
1512
    parent->SetSizer( item0 );
1513
    parent->Layout();
1514
    item0->Fit( parent );
1515
    item0->SetSizeHints( parent );
1516
 
1517
    FindWindow(ecID_STRING_EDIT_TEXTCTRL)->SetValidator(wxGenericValidator(& m_value));
1518
    FindWindow(ecID_STRING_EDIT_TEXTCTRL)->SetFocus();
1519
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.