// @(#)root/gui:$Id$
// Author: Fons Rademakers   20/02/98

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TRootDialog                                                          //
//                                                                      //
// A TRootDialog is used to prompt for the arguments of an object's     //
// member function. A TRootDialog is created via the context menu's     //
// when selecting a member function taking arguments.                   //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TRootDialog.h"
#include "TRootContextMenu.h"
#include "TContextMenu.h"
#include "TClassMenuItem.h"
#include "TList.h"
#include "TGLabel.h"
#include "TGTextEntry.h"
#include "TGButton.h"
#include "TObjString.h"
#include "KeySymbols.h"

extern TGTextEntry *gBlinkingEntry;

ClassImp(TRootDialog)

//______________________________________________________________________________
TRootDialog::TRootDialog(TRootContextMenu *cmenu, const TGWindow *main,
    const char *title, Bool_t okB, Bool_t cancelB, Bool_t applyB,
    Bool_t helpB) : TGTransientFrame(gClient->GetRoot(), main, 200, 100)
{
   // Create a method argument prompt dialog.

   fMenu   = cmenu;

   fOk     = okB;
   fCancel = cancelB;
   fApply  = applyB;
   fHelp   = helpB;

   fWidgets = new TList;

   fL1 = new TGLayoutHints(kLHintsTop | kLHintsCenterX, 0, 0, 5, 0);
   fL2 = new TGLayoutHints(kLHintsTop | kLHintsLeft, 5, 5, 5, 5);

   SetWindowName(title);
   SetIconName(title);
   SetEditDisabled(kEditDisable);

   AddInput(kKeyPressMask | kEnterWindowMask | kLeaveWindowMask);
}

//______________________________________________________________________________
TRootDialog::~TRootDialog()
{
   // Delete the dialog.

   fWidgets->Delete();
   delete fWidgets;
   delete fL1;
   delete fL2;
}

//______________________________________________________________________________
void TRootDialog::Add(const char *argname, const char *value, const char *type)
{
   // Add a label and text input field.

   TGLabel      *l = new TGLabel(this, argname);
   TString svalue(value);
   // keep double backslashes (e.g. in case of LateX formatting, like \\gamma)
   svalue.ReplaceAll("\\", "\\\\");
   TGTextBuffer *b = new TGTextBuffer(20); b->AddText(0, svalue.Data());
   TGTextEntry  *t = new TGTextEntry(this, b);

   t->Connect("TabPressed()", "TRootDialog", this, "TabPressed()");

   t->Associate(fMenu);
   t->Resize(260, t->GetDefaultHeight());
   AddFrame(l, fL1);
   AddFrame(t, fL2);

   fWidgets->Add(l);
   fWidgets->Add(t);   // TGTextBuffer will be deleted by TGTextEntry
   fWidgets->Add(new TObjString(type));
}

//______________________________________________________________________________
const char *TRootDialog::GetParameters()
{
   // Get parameter string (called by contextmenu after OK or Apply has
   // been selected).

   static TString params;
   TString param;

   TObjString   *str;
   TObject      *obj;

   Int_t selfobjpos;
   if (fMenu->GetContextMenu()->GetSelectedMenuItem())
      selfobjpos = fMenu->GetContextMenu()->GetSelectedMenuItem()->GetSelfObjectPos();
   else
      selfobjpos = -1;

   params.Clear();
   TIter next(fWidgets);
   Int_t nparam = 0;

   while ((obj = next())) {        // first element is label, skip...
      if (obj->IsA() != TGLabel::Class()) break;
      obj = next();                // get either TGTextEntry or TGComboBox
      str = (TObjString *) next(); // get type string

      nparam++;

      const char *type = str ? str->GetString().Data() : 0;
      const char *data = 0;

      if (obj && obj->IsA() == TGTextEntry::Class())
         data = ((TGTextEntry *) obj)->GetBuffer()->GetString();

      // TODO: Combobox...

      // if necessary, replace the selected object by it's address
      if (selfobjpos == nparam-1) {
         if (params.Length()) params += ",";
         param = TString::Format("(TObject*)0x%lx",
               (Long_t)fMenu->GetContextMenu()->GetSelectedObject());
         params += param;
      }

      if (params.Length()) params += ",";
      if (type && data) {
         if (!strncmp(type, "char*", 5))
            param = TString::Format("\"%s\"", data);
         else
            param = data;
      } else
         param = "0";

      params += param;
   }

   // if selected object is the last argument, have to insert it here
   if (selfobjpos == nparam) {
      if (params.Length()) params += ",";
      param = TString::Format("(TObject*)0x%lx",
            (Long_t)fMenu->GetContextMenu()->GetSelectedObject());
      params += param;
   }

   return params.Data();
}

//______________________________________________________________________________
void TRootDialog::Popup()
{
   // Popup dialog.

   //--- create the OK, Apply and Cancel buttons

   UInt_t  nb = 0, width = 0, height = 0;

   TGHorizontalFrame *hf = new TGHorizontalFrame(this, 60, 20, kFixedWidth);
   TGLayoutHints     *l1 = new TGLayoutHints(kLHintsCenterY | kLHintsExpandX, 5, 5, 0, 0);

   // put hf as last in the list to be deleted
   fWidgets->Add(l1);

   TGTextButton *b;
   if (fOk) {
      b = new TGTextButton(hf, "&OK", 1);
      fWidgets->Add(b);
      b->Associate(fMenu);
      hf->AddFrame(b, l1);
      height = b->GetDefaultHeight();
      width  = TMath::Max(width, b->GetDefaultWidth()); ++nb;
   }
   if (fApply) {
      b = new TGTextButton(hf, "&Apply", 2);
      fWidgets->Add(b);
      b->Associate(fMenu);
      hf->AddFrame(b, l1);
      height = b->GetDefaultHeight();
      width  = TMath::Max(width, b->GetDefaultWidth()); ++nb;
   }
   if (fCancel) {
      b = new TGTextButton(hf, "&Cancel", 3);
      fWidgets->Add(b);
      b->Associate(fMenu);
      hf->AddFrame(b, l1);
      height = b->GetDefaultHeight();
      width  = TMath::Max(width, b->GetDefaultWidth()); ++nb;
   }
   if (fHelp) {
      b = new TGTextButton(hf, "Online &Help", 4);
      fWidgets->Add(b);
      b->Associate(fMenu);
      hf->AddFrame(b, l1);
      height = b->GetDefaultHeight();
      width  = TMath::Max(width, b->GetDefaultWidth()); ++nb;
   }

   // place buttons at the bottom
   l1 = new TGLayoutHints(kLHintsBottom | kLHintsCenterX, 0, 0, 5, 5);
   fWidgets->Add(l1);
   fWidgets->Add(hf);

   AddFrame(hf, l1);

   // keep the buttons centered and with the same width
   hf->Resize((width + 20) * nb, height);

   // map all widgets and calculate size of dialog
   MapSubwindows();

   width  = GetDefaultWidth();
   height = GetDefaultHeight();

   Resize(width, height);

   // position relative to the parent's window
   CenterOnParent();

   // make the message box non-resizable
   SetWMSize(width, height);
   SetWMSizeHints(width, height, width, height, 0, 0);

   SetMWMHints(kMWMDecorAll | kMWMDecorResizeH  | kMWMDecorMaximize |
                              kMWMDecorMinimize | kMWMDecorMenu,
               kMWMFuncAll  | kMWMFuncResize    | kMWMFuncMaximize |
                              kMWMFuncMinimize,
               kMWMInputModeless);

   MapWindow();
   fClient->WaitFor(this);
}

//______________________________________________________________________________
void TRootDialog::CloseWindow()
{
   // Called when closed via window manager action.

   // Send Cancel button message to context menu eventhandler
   SendMessage(fMenu, MK_MSG(kC_COMMAND, kCM_BUTTON), 3, 0);
}

//______________________________________________________________________________
void TRootDialog::TabPressed()
{
   // Handle Tab keyboard navigation in this dialog.

   Bool_t setNext = kFALSE;
   TGTextEntry *entry;
   TIter next(fWidgets);

   while ( TObject* obj = next() ) {
      if ( obj->IsA() == TGTextEntry::Class() ) {
         entry = (TGTextEntry*) obj;
         if ( entry == gBlinkingEntry ) {
            setNext = kTRUE;
         } else if ( setNext ) {
            entry->SetFocus();
            entry->End();
            return;
         }
      }
   }

   next.Reset();
   while ( TObject* obj = next() ) {
      if ( obj->IsA() == TGTextEntry::Class() ) {
         entry = (TGTextEntry*) obj;
         entry->SetFocus();
         entry->End();
         return;
      }
   }
}

//______________________________________________________________________________
Bool_t TRootDialog::HandleKey(Event_t* event)
{
   // The key press event handler in this dialog.

   char   tmp[10];
   UInt_t keysym;
   gVirtualX->LookupString(event, tmp, sizeof(tmp), keysym);
   if ((EKeySym)keysym  == kKey_Tab) {

      TGTextEntry *entry;
      TIter next(fWidgets);

      while ( TObject* obj = next() ) {
         if ( obj->IsA() == TGTextEntry::Class() ) {
            entry = (TGTextEntry*) obj;
            entry->TabPressed();
            return kTRUE;
         }
      }
   }

   return TGMainFrame::HandleKey(event);
}
 TRootDialog.cxx:1
 TRootDialog.cxx:2
 TRootDialog.cxx:3
 TRootDialog.cxx:4
 TRootDialog.cxx:5
 TRootDialog.cxx:6
 TRootDialog.cxx:7
 TRootDialog.cxx:8
 TRootDialog.cxx:9
 TRootDialog.cxx:10
 TRootDialog.cxx:11
 TRootDialog.cxx:12
 TRootDialog.cxx:13
 TRootDialog.cxx:14
 TRootDialog.cxx:15
 TRootDialog.cxx:16
 TRootDialog.cxx:17
 TRootDialog.cxx:18
 TRootDialog.cxx:19
 TRootDialog.cxx:20
 TRootDialog.cxx:21
 TRootDialog.cxx:22
 TRootDialog.cxx:23
 TRootDialog.cxx:24
 TRootDialog.cxx:25
 TRootDialog.cxx:26
 TRootDialog.cxx:27
 TRootDialog.cxx:28
 TRootDialog.cxx:29
 TRootDialog.cxx:30
 TRootDialog.cxx:31
 TRootDialog.cxx:32
 TRootDialog.cxx:33
 TRootDialog.cxx:34
 TRootDialog.cxx:35
 TRootDialog.cxx:36
 TRootDialog.cxx:37
 TRootDialog.cxx:38
 TRootDialog.cxx:39
 TRootDialog.cxx:40
 TRootDialog.cxx:41
 TRootDialog.cxx:42
 TRootDialog.cxx:43
 TRootDialog.cxx:44
 TRootDialog.cxx:45
 TRootDialog.cxx:46
 TRootDialog.cxx:47
 TRootDialog.cxx:48
 TRootDialog.cxx:49
 TRootDialog.cxx:50
 TRootDialog.cxx:51
 TRootDialog.cxx:52
 TRootDialog.cxx:53
 TRootDialog.cxx:54
 TRootDialog.cxx:55
 TRootDialog.cxx:56
 TRootDialog.cxx:57
 TRootDialog.cxx:58
 TRootDialog.cxx:59
 TRootDialog.cxx:60
 TRootDialog.cxx:61
 TRootDialog.cxx:62
 TRootDialog.cxx:63
 TRootDialog.cxx:64
 TRootDialog.cxx:65
 TRootDialog.cxx:66
 TRootDialog.cxx:67
 TRootDialog.cxx:68
 TRootDialog.cxx:69
 TRootDialog.cxx:70
 TRootDialog.cxx:71
 TRootDialog.cxx:72
 TRootDialog.cxx:73
 TRootDialog.cxx:74
 TRootDialog.cxx:75
 TRootDialog.cxx:76
 TRootDialog.cxx:77
 TRootDialog.cxx:78
 TRootDialog.cxx:79
 TRootDialog.cxx:80
 TRootDialog.cxx:81
 TRootDialog.cxx:82
 TRootDialog.cxx:83
 TRootDialog.cxx:84
 TRootDialog.cxx:85
 TRootDialog.cxx:86
 TRootDialog.cxx:87
 TRootDialog.cxx:88
 TRootDialog.cxx:89
 TRootDialog.cxx:90
 TRootDialog.cxx:91
 TRootDialog.cxx:92
 TRootDialog.cxx:93
 TRootDialog.cxx:94
 TRootDialog.cxx:95
 TRootDialog.cxx:96
 TRootDialog.cxx:97
 TRootDialog.cxx:98
 TRootDialog.cxx:99
 TRootDialog.cxx:100
 TRootDialog.cxx:101
 TRootDialog.cxx:102
 TRootDialog.cxx:103
 TRootDialog.cxx:104
 TRootDialog.cxx:105
 TRootDialog.cxx:106
 TRootDialog.cxx:107
 TRootDialog.cxx:108
 TRootDialog.cxx:109
 TRootDialog.cxx:110
 TRootDialog.cxx:111
 TRootDialog.cxx:112
 TRootDialog.cxx:113
 TRootDialog.cxx:114
 TRootDialog.cxx:115
 TRootDialog.cxx:116
 TRootDialog.cxx:117
 TRootDialog.cxx:118
 TRootDialog.cxx:119
 TRootDialog.cxx:120
 TRootDialog.cxx:121
 TRootDialog.cxx:122
 TRootDialog.cxx:123
 TRootDialog.cxx:124
 TRootDialog.cxx:125
 TRootDialog.cxx:126
 TRootDialog.cxx:127
 TRootDialog.cxx:128
 TRootDialog.cxx:129
 TRootDialog.cxx:130
 TRootDialog.cxx:131
 TRootDialog.cxx:132
 TRootDialog.cxx:133
 TRootDialog.cxx:134
 TRootDialog.cxx:135
 TRootDialog.cxx:136
 TRootDialog.cxx:137
 TRootDialog.cxx:138
 TRootDialog.cxx:139
 TRootDialog.cxx:140
 TRootDialog.cxx:141
 TRootDialog.cxx:142
 TRootDialog.cxx:143
 TRootDialog.cxx:144
 TRootDialog.cxx:145
 TRootDialog.cxx:146
 TRootDialog.cxx:147
 TRootDialog.cxx:148
 TRootDialog.cxx:149
 TRootDialog.cxx:150
 TRootDialog.cxx:151
 TRootDialog.cxx:152
 TRootDialog.cxx:153
 TRootDialog.cxx:154
 TRootDialog.cxx:155
 TRootDialog.cxx:156
 TRootDialog.cxx:157
 TRootDialog.cxx:158
 TRootDialog.cxx:159
 TRootDialog.cxx:160
 TRootDialog.cxx:161
 TRootDialog.cxx:162
 TRootDialog.cxx:163
 TRootDialog.cxx:164
 TRootDialog.cxx:165
 TRootDialog.cxx:166
 TRootDialog.cxx:167
 TRootDialog.cxx:168
 TRootDialog.cxx:169
 TRootDialog.cxx:170
 TRootDialog.cxx:171
 TRootDialog.cxx:172
 TRootDialog.cxx:173
 TRootDialog.cxx:174
 TRootDialog.cxx:175
 TRootDialog.cxx:176
 TRootDialog.cxx:177
 TRootDialog.cxx:178
 TRootDialog.cxx:179
 TRootDialog.cxx:180
 TRootDialog.cxx:181
 TRootDialog.cxx:182
 TRootDialog.cxx:183
 TRootDialog.cxx:184
 TRootDialog.cxx:185
 TRootDialog.cxx:186
 TRootDialog.cxx:187
 TRootDialog.cxx:188
 TRootDialog.cxx:189
 TRootDialog.cxx:190
 TRootDialog.cxx:191
 TRootDialog.cxx:192
 TRootDialog.cxx:193
 TRootDialog.cxx:194
 TRootDialog.cxx:195
 TRootDialog.cxx:196
 TRootDialog.cxx:197
 TRootDialog.cxx:198
 TRootDialog.cxx:199
 TRootDialog.cxx:200
 TRootDialog.cxx:201
 TRootDialog.cxx:202
 TRootDialog.cxx:203
 TRootDialog.cxx:204
 TRootDialog.cxx:205
 TRootDialog.cxx:206
 TRootDialog.cxx:207
 TRootDialog.cxx:208
 TRootDialog.cxx:209
 TRootDialog.cxx:210
 TRootDialog.cxx:211
 TRootDialog.cxx:212
 TRootDialog.cxx:213
 TRootDialog.cxx:214
 TRootDialog.cxx:215
 TRootDialog.cxx:216
 TRootDialog.cxx:217
 TRootDialog.cxx:218
 TRootDialog.cxx:219
 TRootDialog.cxx:220
 TRootDialog.cxx:221
 TRootDialog.cxx:222
 TRootDialog.cxx:223
 TRootDialog.cxx:224
 TRootDialog.cxx:225
 TRootDialog.cxx:226
 TRootDialog.cxx:227
 TRootDialog.cxx:228
 TRootDialog.cxx:229
 TRootDialog.cxx:230
 TRootDialog.cxx:231
 TRootDialog.cxx:232
 TRootDialog.cxx:233
 TRootDialog.cxx:234
 TRootDialog.cxx:235
 TRootDialog.cxx:236
 TRootDialog.cxx:237
 TRootDialog.cxx:238
 TRootDialog.cxx:239
 TRootDialog.cxx:240
 TRootDialog.cxx:241
 TRootDialog.cxx:242
 TRootDialog.cxx:243
 TRootDialog.cxx:244
 TRootDialog.cxx:245
 TRootDialog.cxx:246
 TRootDialog.cxx:247
 TRootDialog.cxx:248
 TRootDialog.cxx:249
 TRootDialog.cxx:250
 TRootDialog.cxx:251
 TRootDialog.cxx:252
 TRootDialog.cxx:253
 TRootDialog.cxx:254
 TRootDialog.cxx:255
 TRootDialog.cxx:256
 TRootDialog.cxx:257
 TRootDialog.cxx:258
 TRootDialog.cxx:259
 TRootDialog.cxx:260
 TRootDialog.cxx:261
 TRootDialog.cxx:262
 TRootDialog.cxx:263
 TRootDialog.cxx:264
 TRootDialog.cxx:265
 TRootDialog.cxx:266
 TRootDialog.cxx:267
 TRootDialog.cxx:268
 TRootDialog.cxx:269
 TRootDialog.cxx:270
 TRootDialog.cxx:271
 TRootDialog.cxx:272
 TRootDialog.cxx:273
 TRootDialog.cxx:274
 TRootDialog.cxx:275
 TRootDialog.cxx:276
 TRootDialog.cxx:277
 TRootDialog.cxx:278
 TRootDialog.cxx:279
 TRootDialog.cxx:280
 TRootDialog.cxx:281
 TRootDialog.cxx:282
 TRootDialog.cxx:283
 TRootDialog.cxx:284
 TRootDialog.cxx:285
 TRootDialog.cxx:286
 TRootDialog.cxx:287
 TRootDialog.cxx:288
 TRootDialog.cxx:289
 TRootDialog.cxx:290
 TRootDialog.cxx:291
 TRootDialog.cxx:292
 TRootDialog.cxx:293
 TRootDialog.cxx:294
 TRootDialog.cxx:295
 TRootDialog.cxx:296
 TRootDialog.cxx:297
 TRootDialog.cxx:298
 TRootDialog.cxx:299
 TRootDialog.cxx:300
 TRootDialog.cxx:301
 TRootDialog.cxx:302
 TRootDialog.cxx:303
 TRootDialog.cxx:304
 TRootDialog.cxx:305
 TRootDialog.cxx:306
 TRootDialog.cxx:307
 TRootDialog.cxx:308
 TRootDialog.cxx:309
 TRootDialog.cxx:310
 TRootDialog.cxx:311
 TRootDialog.cxx:312
 TRootDialog.cxx:313
 TRootDialog.cxx:314
 TRootDialog.cxx:315