OSDN Git Service

307376110797e391a29e71f78447880a7978c895
[molby/Molby.git] / wxSources / RubyDialogFrame.cpp
1 /*
2  *  RubyDialogFrame.cpp
3  *  Molby
4  *
5  *  Created by Toshi Nagata on 08/12/05.
6  *  Copyright 2008 Toshi Nagata. All rights reserved.
7  *
8  This program is free software; you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation version 2 of the License.
11  
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  GNU General Public License for more details.
16  */
17
18 #include "wx/gdicmn.h"
19 #include "wx/stattext.h"
20 #include "wx/textctrl.h"
21 #include "wx/button.h"
22 #include "wx/tglbtn.h"
23 #include "wx/filedlg.h"
24 #include "wx/dirdlg.h"
25 #include "wx/dcclient.h"
26 #include "wx/choice.h"
27 #include "wx/checkbox.h"
28 #include "wx/radiobut.h"
29 #include "wx/statline.h"
30 #include "wx/settings.h"
31
32 #include "RubyDialogFrame.h"
33 #include "MyApp.h"
34 #include "MyMBConv.h"
35 #include "MyDocument.h"
36
37 BEGIN_EVENT_TABLE(RubyDialogFrame, wxDialog)
38   EVT_TIMER(-1, RubyDialogFrame::OnTimerEvent)
39   EVT_BUTTON(wxID_OK, RubyDialogFrame::OnDefaultButtonPressed)
40   EVT_BUTTON(wxID_CANCEL, RubyDialogFrame::OnDefaultButtonPressed)
41   EVT_SIZE(RubyDialogFrame::OnSize)
42 END_EVENT_TABLE()
43
44 RubyDialogFrame::RubyDialogFrame(wxWindow* parent, wxWindowID wid, const wxString& title, const wxPoint& pos, const wxSize& size, long style):
45         wxDialog(parent, wid, title, pos, size, style)
46 {
47         ditems = NULL;
48         nditems = 0;
49         dval = NULL;
50         mySize = gZeroSize;
51         autoResizeEnabled = true;
52         messageData = NULL;
53         countMessageData = 0;
54         
55         //  Create a vertical box sizer that contains a panel containing all controls and a sizer containing
56         //  OK/Cancel buttons
57         contentSizer = new wxBoxSizer(wxVERTICAL);
58         contentPanel = NULL;
59         buttonSizer = NULL;  //  Will be created later
60         myTimer = NULL;  //  Will be created when necessary
61         boxSizer = new wxBoxSizer(wxVERTICAL);
62         boxSizer->Add(contentSizer, 1, wxALL | wxEXPAND, 14);
63         this->SetSizer(boxSizer);
64         boxSizer->Layout();
65         this->CentreOnScreen();
66 }
67
68 RubyDialogFrame::~RubyDialogFrame()
69 {
70         if (myTimer != NULL)
71                 delete myTimer;
72         if (ditems != NULL)
73                 free(ditems);
74         DiscardMessageData();
75 }
76
77 void
78 RubyDialogFrame::DiscardMessageData()
79 {
80         int i;
81         for (i = 0; i < countMessageData; i++) {
82                 if (messageData[i * 5] != NULL) {
83                         wxEventType eventType = (wxEventType)messageData[i * 5 + 2];
84                         wxEvtHandler *handler = NULL;
85                         if (eventType == MyDocumentEvent)
86                                 handler = MyDocumentFromMolecule((Molecule *)messageData[i * 5]);
87                         if (handler != NULL) {
88                                 handler->Disconnect((int)messageData[i * 5 + 1], eventType, wxCommandEventHandler(RubyDialogFrame::HandleDocumentEvent), NULL, this);
89                         }
90                 }
91         }
92         free(messageData);
93         messageData = NULL;
94         countMessageData = 0;
95 }
96
97 int
98 RubyDialogFrame::AddDialogItem(RDItem *item)
99 {
100         if (nditems % 8 == 0) {
101                 if (nditems == 0)
102                         ditems = (RDItem **)malloc(sizeof(RDItem *) * 8);
103                 else
104                         ditems = (RDItem **)realloc(ditems, sizeof(RDItem *) * (nditems + 8));
105         }
106         ditems[nditems++] = item;
107         if (item != NULL && ((wxWindow *)item)->IsKindOf(CLASSINFO(wxPanel))) {
108                 wxSize size = ((wxPanel *)item)->GetSize();
109                 if (contentPanel == NULL)
110                         contentSizer->Add((wxPanel *)item, 1, wxEXPAND);
111                 else
112                         contentSizer->Replace(contentPanel, (wxPanel *)item);
113                 contentSizer->SetItemMinSize((wxPanel *)item, size.GetWidth(), size.GetHeight());
114                 contentPanel = (wxPanel *)item;
115                 boxSizer->Layout();
116                 Fit();
117         }
118         return nditems - 1;
119 }
120
121 RDItem *
122 RubyDialogFrame::DialogItemAtIndex(int index)
123 {
124         if (index >= 0 && index < nditems)
125                 return ditems[index];
126         else return NULL;
127 }
128
129 int
130 RubyDialogFrame::SearchDialogItem(RDItem *item)
131 {
132         int i;
133         for (i = 0; i < nditems; i++) {
134                 if (item == ditems[i])
135                         return i;
136         }
137         return -1;
138 }
139
140 void
141 RubyDialogFrame::SetRubyObject(RubyValue val)
142 {
143         dval = val;
144         if (dval == NULL) {
145                 /*  Stop message mechanism (because this object is already disconnected from the Ruby world)  */
146                 DiscardMessageData();
147         }
148 }
149
150 /*  Create standard buttons. If oktitle/canceltitle == NULL, then the button is created but set hidden.
151     If the title is "", then the default titles are used.  */
152 void
153 RubyDialogFrame::CreateStandardButtons(const char *oktitle, const char *canceltitle)
154 {
155         wxSizer *sizer = CreateButtonSizer(wxOK | wxCANCEL);
156         if (oktitle != NULL || canceltitle != NULL) {
157                 if (sizer == NULL)
158                         return;  /*  Cannot create  */
159                 if (buttonSizer == NULL) {
160                         boxSizer->Add(sizer, 0, wxBOTTOM | wxLEFT | wxRIGHT | wxEXPAND, 14);
161                         buttonSizer = sizer;
162                 } else {
163                         boxSizer->Replace(buttonSizer, sizer);
164                         buttonSizer = sizer;
165                 }
166         } else {
167                 /*  Buttons are created but sizer is left unregistered  */
168                 if (buttonSizer != NULL)
169                         boxSizer->Remove(buttonSizer);
170                 buttonSizer = NULL;
171         }
172         while (nditems < 2)
173                 AddDialogItem(NULL);
174         if (ditems[0] != NULL)
175                 ((wxWindow *)ditems[0])->Destroy();
176         if (ditems[1] != NULL)
177                 ((wxWindow *)ditems[1])->Destroy();
178         ditems[0] = (RDItem *)wxWindow::FindWindowById(wxID_OK, this);
179         ditems[1] = (RDItem *)wxWindow::FindWindowById(wxID_CANCEL, this);
180         if (oktitle == NULL) {
181                 ((wxWindow *)ditems[0])->Show(false);
182                 ((wxWindow *)ditems[0])->Enable(false);
183         } else {
184                 if (oktitle[0] != 0) {
185                         wxString label1(oktitle, WX_DEFAULT_CONV);
186                         ((wxButton *)ditems[0])->SetLabel(label1);
187                 }
188                 ((wxWindow *)ditems[0])->Connect(-1, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(RubyDialogFrame::OnDialogItemAction), NULL, this);
189         }
190         if (canceltitle == NULL) {
191                 ((wxWindow *)ditems[1])->Show(false);
192                 ((wxWindow *)ditems[1])->Enable(false);
193         } else {
194                 if (canceltitle[0] != 0) {
195                         wxString label2(canceltitle, WX_DEFAULT_CONV);
196                         ((wxButton *)ditems[1])->SetLabel(label2);
197                 }
198                 ((wxWindow *)ditems[1])->Connect(-1, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(RubyDialogFrame::OnDialogItemAction), NULL, this);
199         }
200 }
201
202 int
203 RubyDialogFrame::StartIntervalTimer(int millisec)
204 {
205         if (myTimer == NULL) {
206                 myTimer = new wxTimer(this);
207         }
208         return myTimer->Start(millisec);
209 }
210
211 void
212 RubyDialogFrame::StopIntervalTimer(void)
213 {
214         if (myTimer != NULL)
215                 myTimer->Stop();
216 }
217
218 void
219 RubyDialogFrame::OnDialogItemAction(wxCommandEvent &event)
220 {
221         RubyDialog_doItemAction((RubyValue)dval, (RDItem *)(event.GetEventObject()));
222 }
223
224 void
225 RubyDialogFrame::OnDefaultButtonPressed(wxCommandEvent &event)
226 {
227         /*  Ignore the wxID_OK and wxID_CANCEL requests if the default buttons are hidden  */
228         wxWindow *item = wxWindow::FindWindowById(event.GetId(), this);
229         if (!item->IsShown())
230                 return;
231         event.Skip();
232 }
233
234 void
235 RubyDialogFrame::OnTimerEvent(wxTimerEvent &event)
236 {
237         RubyDialog_doTimerAction((RubyValue)dval);
238 }
239
240 static void
241 sResizeSubWindows(RubyValue dval, wxWindow *win, int dx, int dy)
242 {
243         wxWindowList & children = win->GetChildren();
244         wxWindowList::Node *node;
245         for (node = children.GetFirst(); node; node = node->GetNext()) {
246                 int i, d, f, d1, d2, d3, ddx, ddy;
247                 wxWindow *current = (wxWindow *)node->GetData();
248                 wxRect frame = current->GetRect();
249                 int flex = RubyDialog_getFlexFlags(dval, (RDItem *)current);
250                 if (flex < 0)
251                         continue;               
252                 for (i = 0, f = flex; i < 2; i++, f /= 2) {
253                         if (i == 0)
254                                 d = dx;
255                         else
256                                 d = dy;
257                         switch (f & 21) {  /*  left, right, width (or top, bottom, height) */
258                                 case 21:  /*  all flex  */
259                                         d1 = d2 = d / 3;
260                                         d3 = d - d1 - d2;
261                                         break;
262                                 case 5:   /*  left & right  */
263                                         d1 = d / 2;
264                                         d2 = 0;
265                                         d3 = d - d1;
266                                         break;
267                                 case 17:  /*  left & width  */
268                                         d1 = d / 2;
269                                         d2 = d - d1;
270                                         d3 = 0;
271                                         break;
272                                 case 20:  /*  right & width  */
273                                         d1 = 0;
274                                         d2 = d / 2;
275                                         d3 = d - d2;
276                                         break;
277                                 case 1:   /*  left  */
278                                         d1 = d;
279                                         d2 = d3 = 0;
280                                         break;
281                                 case 4:   /*  right */
282                                         d3 = d;
283                                         d1 = d2 = 0;
284                                         break;
285                                 case 16:  /*  width  */
286                                         d2 = d;
287                                         d1 = d3 = 0;
288                                         break;
289                         }
290                         if (i == 0) {
291                                 frame.x += d1;
292                                 frame.width += d2;
293                                 ddx = d2;
294                         } else {
295                                 frame.y += d1;
296                                 frame.height += d2;
297                                 ddy = d2;
298                         }
299                 }
300                 if (ddx != 0 || ddy != 0)
301                         sResizeSubWindows(dval, current, ddx, ddy);
302                 current->SetSize(frame);
303         }
304 }
305
306 void
307 RubyDialogFrame::OnSize(wxSizeEvent &event)
308 {
309         wxSize size = GetClientSize();
310         if (mySize.width != 0 && mySize.height != 0 && /*(mySize.width != size.x || mySize.height != size.y) &&*/ autoResizeEnabled) {
311                 /*  Resize the subviews  */
312                 sResizeSubWindows((RubyValue)dval, this, size.x - mySize.width, size.y - mySize.height);
313         }
314         mySize.width = size.x;
315         mySize.height = size.y;
316         event.Skip();
317 }
318
319 int
320 RubyDialogFrame::ListenToObject(void *obj, const char *objtype, const char *msg, RubyValue oval, RubyValue pval)
321 {
322         int i, j, eventId;
323         wxEventType eventType;
324         wxEvtHandler *handler;
325         if (strcmp(objtype, "Molecule") == 0) {
326                 eventType = MyDocumentEvent;
327                 handler = MyDocumentFromMolecule((Molecule *)obj);
328                 if (handler == NULL)
329                         return -1;  /*  obj is not an event handler  */
330                 if (msg == NULL)
331                         eventId = -1;
332                 else if (strcmp(msg, "documentModified") == 0)
333                         eventId = MyDocumentEvent_documentModified;
334                 else if (strcmp(msg, "documentWillClose") == 0)
335                         eventId = MyDocumentEvent_documentWillClose;
336                 else return -2; /*  this event type is not supported  */
337         } else return -1;
338         
339         if (pval == NULL || pval == RubyNil) {
340                 /*  Remove the registration  */
341                 for (i = 0; i < countMessageData; i++) {
342                         if (messageData[i * 5] == obj && 
343                                 messageData[i * 5 + 1] == (void *)eventId &&
344                                 messageData[i * 5 + 2] == (void *)eventType) {
345                                 handler->Disconnect(eventId, eventType, wxCommandEventHandler(RubyDialogFrame::HandleDocumentEvent), NULL, this);
346                                 if (eventType == MyDocumentEvent)
347                                         MoleculeRelease((Molecule *)obj);
348                                 break;
349                         }
350                 }
351                 if (i == countMessageData)
352                         return -3;  /*  No such message  */
353                 messageData[i * 5] = NULL;
354                 return i;
355         } else {
356                 /*  Check the duplicate  */
357                 j = countMessageData;  /*  The position to store info if it is new  */
358                 for (i = 0; i < countMessageData; i++) {
359                         if (messageData[i * 5] == obj && 
360                                 messageData[i * 5 + 1] == (void *)eventId &&
361                                 messageData[i * 5 + 2] == (void *)eventType) {
362                                 /*  Just replace the arguments  */
363                                 messageData[i * 5 + 3] = (void *)oval;
364                                 messageData[i * 5 + 4] = (void *)pval;
365                                 break;
366                         }
367                         if (messageData[i * 5] == NULL)
368                                 j = i;
369                 }
370                 if (i == countMessageData) {
371                         /*  Register the data and establish a new connection  */
372                         if (j == countMessageData) {
373                                 /*  Create a new entry  */
374                                 InsertArray(&messageData, &countMessageData, sizeof(void *) * 5, i, 1, NULL);
375                         }
376                         messageData[j * 5] = obj;
377                         messageData[j * 5 + 1] = (void *)eventId;
378                         messageData[j * 5 + 2] = (void *)eventType;
379                         messageData[j * 5 + 3] = (void *)oval;
380                         messageData[j * 5 + 4] = (void *)pval;
381                         handler->Connect(eventId, eventType, wxCommandEventHandler(RubyDialogFrame::HandleDocumentEvent), NULL, this);
382                         if (eventType == MyDocumentEvent)
383                                 MoleculeRetain((Molecule *)obj);
384                         i = j;
385                 }
386                 return i;
387         }
388 }
389
390 void
391 RubyDialogFrame::HandleDocumentEvent(wxCommandEvent &event)
392 {
393         int i;
394         int eventId = event.GetId();
395         int eventType = event.GetEventType();
396         wxObject *eventObject = event.GetEventObject();
397         void *obj;
398
399         if (eventType == MyDocumentEvent) {
400                 if (wxDynamicCast(eventObject, MyDocument) != NULL) {
401                         obj = ((MyDocument *)eventObject)->GetMolecule();
402                 } else return;
403         } else return;
404         
405         /*  Look up the message table  */
406         for (i = 0; i < countMessageData; i++) {
407                 if (messageData[i * 5] == obj && 
408                         messageData[i * 5 + 1] == (void *)eventId &&
409                         messageData[i * 5 + 2] == (void *)eventType) {
410                         int status;
411                         RubyValue oval = (RubyValue)messageData[i * 5 + 3];
412                         RubyValue pval = (RubyValue)messageData[i * 5 + 4];
413                         Ruby_funcall2_protect_extern(pval, g_RubyID_call, 1, &oval, &status);
414                 }
415         }
416         event.Skip();
417 }
418
419 #pragma mark ====== MyListCtrlDataSource methods ======
420
421 int
422 RubyDialogFrame::GetItemCount(MyListCtrl *ctrl)
423 {
424         return RubyDialog_GetTableItemCount((RubyValue)dval, (RDItem *)ctrl);
425 }
426
427 wxString 
428 RubyDialogFrame::GetItemText(MyListCtrl *ctrl, long row, long column) const
429 {
430         char buf[1024];
431         RubyDialog_GetTableItemText((RubyValue)dval, (RDItem *)ctrl, row, column, buf, sizeof buf);
432         wxString str(buf, WX_DEFAULT_CONV);
433         return str;
434 }
435
436 int 
437 RubyDialogFrame::SetItemText(MyListCtrl *ctrl, long row, long column, const wxString &value)
438 {
439         return RubyDialog_SetTableItemText((RubyValue)dval, (RDItem *)ctrl, row, column, value.mb_str(WX_DEFAULT_CONV));
440 }
441
442 void 
443 RubyDialogFrame::DragSelectionToRow(MyListCtrl *ctrl, long row)
444 {
445         RubyDialog_DragTableSelectionToRow((RubyValue)dval, (RDItem *)ctrl, row);
446 }
447
448 bool 
449 RubyDialogFrame::IsItemEditable(MyListCtrl *ctrl, long row, long column)
450 {
451         return RubyDialog_IsTableItemEditable((RubyValue)dval, (RDItem *)ctrl, row, column);
452 }
453
454 bool 
455 RubyDialogFrame::IsDragAndDropEnabled(MyListCtrl *ctrl)
456 {
457         return RubyDialog_IsTableDragAndDropEnabled((RubyValue)dval, (RDItem *)ctrl);
458 }
459
460 void 
461 RubyDialogFrame::OnSelectionChanged(MyListCtrl *ctrl)
462 {
463         RubyDialog_OnTableSelectionChanged((RubyValue)dval, (RDItem *)ctrl);
464 }
465
466 int 
467 RubyDialogFrame::SetItemColor(MyListCtrl *ctrl, long row, long col, float *fg, float *bg)
468 {
469         return RubyDialog_SetTableItemColor((RubyValue)dval, (RDItem *)ctrl, row, col, fg, bg);
470 }
471
472 int
473 RubyDialogFrame::HasPopUpMenu(MyListCtrl *ctrl, long row, long column, char ***menu_titles)
474 {
475         return RubyDialog_HasPopUpMenu((RubyValue)dval, (RDItem *)ctrl, row, column, menu_titles);
476 }
477
478 void
479 RubyDialogFrame::OnPopUpMenuSelected(MyListCtrl *ctrl, long row, long column, int selected_index)
480 {
481         RubyDialog_OnPopUpMenuSelected((RubyValue)dval, (RDItem *)ctrl, row, column, selected_index);
482 }
483
484 #pragma mark ====== Plain C interface ======
485
486 RubyDialog *
487 RubyDialogCallback_new(int style)
488 {
489         /*  RubyDialogFrame should not have a close box  */
490         RubyDialogFrame *dref;
491         int fstyle = wxCAPTION | wxSYSTEM_MENU;
492         if (style & rd_Resizable)
493                 fstyle |= wxRESIZE_BOX | wxRESIZE_BORDER;
494         dref = new RubyDialogFrame(GetMainFrame(), -1, _T("Ruby Dialog"), wxDefaultPosition, wxDefaultSize, fstyle);
495         return (RubyDialog *)dref;
496 }
497
498 void
499 RubyDialogCallback_release(RubyDialog *dref)
500 {
501         ((RubyDialogFrame *)dref)->Destroy();
502 }
503
504 void
505 RubyDialogCallback_setRubyObject(RubyDialog *dref, RubyValue val)
506 {
507         ((RubyDialogFrame *)dref)->SetRubyObject(val);
508 }
509
510 void
511 RubyDialogCallback_setWindowTitle(RubyDialog *dref, const char *title)
512 {
513         wxString str(title, WX_DEFAULT_CONV);
514         ((RubyDialogFrame *)dref)->SetLabel(str);
515 }
516
517 int
518 RubyDialogCallback_runModal(RubyDialog *dref)
519 {
520         int retval = ((RubyDialogFrame *)dref)->ShowModal();
521         if (retval == wxID_OK)
522                 return 0;  /*  OK  */
523         else return 1;  /* Cancel */
524 }
525
526 void
527 RubyDialogCallback_endModal(RubyDialog *dref, int status)
528 {
529         ((RubyDialogFrame *)dref)->StopIntervalTimer();
530         if (((RubyDialogFrame *)dref)->IsModal())
531                 ((RubyDialogFrame *)dref)->EndModal(status == 0 ? wxID_OK : wxID_CANCEL);
532         else ((RubyDialogFrame *)dref)->Close();
533 }
534
535 void
536 RubyDialogCallback_close(RubyDialog *dref)
537 {
538         ((RubyDialogFrame *)dref)->StopIntervalTimer();
539         ((RubyDialogFrame *)dref)->Close();
540 }
541
542 void
543 RubyDialogCallback_show(RubyDialog *dref)
544 {
545         if (((RubyDialogFrame *)dref)->myTimer != NULL)
546                 ((RubyDialogFrame *)dref)->StartIntervalTimer(-1);
547         ((RubyDialogFrame *)dref)->Show(true);
548         ((RubyDialogFrame *)dref)->Raise();
549 }
550
551 void
552 RubyDialogCallback_hide(RubyDialog *dref)
553 {
554         ((RubyDialogFrame *)dref)->StopIntervalTimer();
555         ((RubyDialogFrame *)dref)->Show(false);
556 }
557
558 int
559 RubyDialogCallback_startIntervalTimer(RubyDialog *dref, float interval)
560 {
561         return ((RubyDialogFrame *)dref)->StartIntervalTimer(interval * 1000);
562 }
563
564 void
565 RubyDialogCallback_stopIntervalTimer(RubyDialog *dref)
566 {
567         ((RubyDialogFrame *)dref)->StopIntervalTimer();
568 }
569
570 static inline RDRect
571 RDRectFromwxRect(const wxRect &frame)
572 {
573         RDRect rframe;
574         rframe.origin.x = frame.x;
575         rframe.origin.y = frame.y;
576         rframe.size.width = frame.width;
577         rframe.size.height = frame.height;
578         return rframe;
579 }
580
581 static inline wxRect
582 wxRectFromRDRect(RDRect rframe)
583 {
584         wxRect frame(rframe.origin.x, rframe.origin.y, rframe.size.width, rframe.size.height);
585         return frame;
586 }
587
588 RDSize
589 RubyDialogCallback_windowMinSize(RubyDialog *dref)
590 {
591         wxSize minSize = ((RubyDialogFrame *)dref)->GetMinSize();
592         RDSize rminSize;
593         rminSize.width = minSize.GetWidth();
594         rminSize.height = minSize.GetHeight();
595         return rminSize;
596 }
597
598 void
599 RubyDialogCallback_setWindowMinSize(RubyDialog *dref, RDSize size)
600 {
601         wxSize minSize;
602         minSize.x = size.width;
603         minSize.y = size.height;
604         ((RubyDialogFrame *)dref)->SetMinSize(minSize);
605 }
606
607 RDSize
608 RubyDialogCallback_windowSize(RubyDialog *dref)
609 {
610         wxSize minSize = ((RubyDialogFrame *)dref)->GetSize();
611         RDSize rminSize;
612         rminSize.width = minSize.GetWidth();
613         rminSize.height = minSize.GetHeight();
614         return rminSize;
615 }
616 void
617 RubyDialogCallback_setWindowSize(RubyDialog *dref, RDSize size)
618 {
619         wxSize wsize(size.width, size.height);
620         ((RubyDialogFrame *)dref)->SetSize(wsize);
621         ((RubyDialogFrame *)dref)->CentreOnScreen();
622 }
623
624 void
625 RubyDialogCallback_setAutoResizeEnabled(RubyDialog *dref, int flag)
626 {
627         ((RubyDialogFrame *)dref)->SetAutoResizeEnabled(flag);
628 }
629
630 int
631 RubyDialogCallback_isAutoResizeEnabled(RubyDialog *dref)
632 {
633         return ((RubyDialogFrame *)dref)->IsAutoResizeEnabled();
634 }
635
636 int
637 RubyDialogCallback_Listen(RubyDialog *dref, void *obj, const char *objtype, const char *msg, RubyValue oval, RubyValue pval)
638 {
639         return ((RubyDialogFrame *)dref)->ListenToObject(obj, objtype, msg, oval, pval);
640 }
641
642 void
643 RubyDialogCallback_createStandardButtons(RubyDialog *dref, const char *oktitle, const char *canceltitle)
644 {
645         ((RubyDialogFrame *)dref)->CreateStandardButtons(oktitle, canceltitle);
646 }
647
648 static wxRect
649 OffsetForItemRect(const char *type)
650 {
651         wxRect offset(0, 0, 0, 0);
652         if (strcmp(type, "textfield") == 0) {
653 #if defined(__WXMAC__)
654                 offset.height = 4;
655 #endif
656         }
657         else if (strcmp(type, "button") == 0) {
658 #if defined(__WXMAC__)
659                 offset.width = 24;
660                 offset.height = 14;
661 #else
662                 offset.width = 8;
663                 offset.height = 0;
664 #endif
665         } else if (strcmp(type, "checkbox") == 0) {
666                 offset.width = 10;
667         }
668         return offset;
669 }
670
671 RDItem *
672 RubyDialogCallback_createItem(RubyDialog *dref, const char *type, const char *title, RDRect frame)
673 {
674         wxWindow *control = NULL;
675         wxRect rect, offset;
676         RubyDialogFrame *parent = ((RubyDialogFrame *)dref);
677         wxString tstr((title ? title : ""), WX_DEFAULT_CONV);
678         bool no_action = false;
679         
680         rect = wxRectFromRDRect(frame);
681         offset = OffsetForItemRect(type);
682         if (rect.width == 0 && rect.height == 0) {
683                 rect.SetPosition(wxDefaultPosition);
684                 rect.SetSize(wxDefaultSize);
685         } else {        
686                 rect.SetX(rect.x + offset.x);
687                 rect.SetY(rect.y + offset.y);
688                 rect.SetWidth(rect.width + offset.width);
689                 rect.SetHeight(rect.height + offset.height);
690         }
691
692         if (strcmp(type, "text") == 0) {
693                 /*  Static text */              
694                 long style = wxST_NO_AUTORESIZE;
695                 if (rect.width == wxDefaultSize.x && rect.height == wxDefaultSize.y)
696                         style = 0;  /*  Allow autoresize  */
697                 wxStaticText *st = new wxStaticText(parent, -1, tstr, rect.GetPosition(), rect.GetSize(), style);
698                 control = st;
699                 no_action = true;
700         } else if (strcmp(type, "textfield") == 0) {
701                 /*  Editable text  */
702                 wxTextCtrl *tc = new wxTextCtrl(parent, -1, tstr, rect.GetPosition(), rect.GetSize());
703                 control = tc;
704                 tc->Connect(-1, wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler(RubyDialogFrame::OnDialogItemAction), NULL, parent);
705         } else if (strcmp(type, "textview") == 0) {
706                 /*  Text view  */
707                 wxTextCtrl *tc = new wxTextCtrl(parent, -1, tstr, rect.GetPosition(), rect.GetSize(), wxTE_MULTILINE | wxTE_RICH);
708                 control = tc;
709                 tc->Connect(-1, wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler(RubyDialogFrame::OnDialogItemAction), NULL, parent);
710         } else if (strcmp(type, "view") == 0) {
711                 /*  Panel  */
712                 wxPanel *pn = new wxPanel(parent, -1, rect.GetPosition(), rect.GetSize());
713                 control = pn;
714         } else if (strcmp(type, "line") == 0) {
715                 /*  Separator line  */
716                 int direction = (rect.width > rect.height ? wxLI_HORIZONTAL : wxLI_VERTICAL);
717                 wxStaticLine *ln = new wxStaticLine(parent, -1, rect.GetPosition(), rect.GetSize(), direction);
718                 control = ln;
719         /*      printf("is_vertical = %d\n", (int)ln->IsVertical()); */
720         } else if (strcmp(type, "button") == 0) {
721                 /*  Button  */
722                 wxButton *bn = new wxButton(parent, -1, tstr, rect.GetPosition(), rect.GetSize());
723                 control = bn;
724                 bn->Connect(-1, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(RubyDialogFrame::OnDialogItemAction), NULL, parent);
725         } else if (strcmp(type, "togglebutton") == 0) {
726                 /*  Button  */
727                 wxToggleButton *bn = new wxToggleButton(parent, -1, tstr, rect.GetPosition(), rect.GetSize());
728                 control = bn;
729                 bn->Connect(-1, wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(RubyDialogFrame::OnDialogItemAction), NULL, parent);
730         } else if (strcmp(type, "popup") == 0) {
731                 /*  Popup button (wxChoice)  */
732                 wxString du[1] = { _T(" ") };
733                 wxChoice *ch = new wxChoice(parent, -1, rect.GetPosition(), rect.GetSize(), 1, du);
734                 control = ch;
735                 ch->Connect(-1, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler(RubyDialogFrame::OnDialogItemAction), NULL, parent);
736         } else if (strcmp(type, "checkbox") == 0) {
737                 /*  Checkbox (wxCheckBox)  */
738                 wxCheckBox *cb = new wxCheckBox(parent, -1, tstr, rect.GetPosition(), rect.GetSize());
739                 control = cb;
740                 cb->Connect(-1, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(RubyDialogFrame::OnDialogItemAction), NULL, parent);
741         } else if (strcmp(type, "radio") == 0) {
742                 /*  Radio button (not grouped)  */
743                 wxRadioButton *rb = new wxRadioButton(parent, -2, tstr, rect.GetPosition(), rect.GetSize(), wxRB_SINGLE);
744                 control = rb;
745                 rb->Connect(-1, wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler(RubyDialogFrame::OnDialogItemAction), NULL, parent);
746         } else if (strcmp(type, "table") == 0) {
747                 /*  Table view = MyListCtrl  */
748                 MyListCtrl *tb = new MyListCtrl();
749                 tb->Create(parent, -1, rect.GetPosition(), rect.GetSize());
750                 control = tb;
751                 tb->SetDataSource(parent);
752         } else return NULL;
753         
754         if (title[0] != 0 || strcmp(type, "textfield") == 0) {
755                 /*  Resize the frame rect as necessary  */
756                 RDSize minSize = RubyDialogCallback_sizeOfString((RDItem *)control, title);
757                 wxSize size = control->GetSize();
758                 if (size.GetHeight() < minSize.height)
759                         size.SetHeight(minSize.height);
760                 if (size.GetWidth() < minSize.width)
761                         size.SetWidth(minSize.width);
762                 size.SetWidth(size.GetWidth() + offset.width);
763                 size.SetHeight(size.GetHeight() + offset.height);
764                 control->SetSize(size);
765         }
766         
767         if (wxDynamicCast(control, wxTextCtrl) != NULL) {
768                 /*  Set default font  */
769                 wxTextAttr attr;
770                 attr.SetFont(wxSystemSettings::GetFont(wxSYS_SYSTEM_FONT));
771                 ((wxTextCtrl *)control)->SetDefaultStyle(attr);
772         }
773
774         ((RubyDialogFrame *)dref)->AddDialogItem((RDItem *)control);
775         
776         return (RDItem *)control;
777 }
778
779 RDItem *
780 RubyDialogCallback_dialogItemAtIndex(RubyDialog *dref, int idx)
781 {
782         if (idx == -1)
783                 return (RDItem *)dref;
784         else return ((RubyDialogFrame *)dref)->DialogItemAtIndex(idx);
785 }
786
787 int
788 RubyDialogCallback_indexOfItem(RubyDialog *dref, RDItem *item)
789 {
790         return ((RubyDialogFrame *)dref)->SearchDialogItem(item);
791 }
792
793 void
794 RubyDialogCallback_moveItemUnderView(RDItem *item, RDItem *superView, RDPoint origin)
795 {
796         if (item == NULL || superView == NULL || item == superView)
797                 return;
798         if (((wxWindow *)item)->Reparent((wxWindow *)superView)) {
799                 ((wxWindow *)item)->Move(origin.x, origin.y);
800         }
801 }
802
803 RDItem *
804 RubyDialogCallback_superview(RDItem *item)
805 {
806         return (RDItem *)(((wxWindow *)item)->GetParent());
807 }
808
809 RDRect
810 RubyDialogCallback_frameOfItem(RDItem *item)
811 {
812         wxRect rect = ((wxWindow *)item)->GetRect();
813         if (gRubyDialogIsFlipped) {
814                 wxWindow *parent = ((wxWindow *)item)->GetParent();
815                 if (parent != NULL) {
816                         wxRect superRect = parent->GetRect();
817                         rect.SetY(superRect.GetHeight() - rect.GetHeight() - rect.GetY());
818                 }
819         }
820         return RDRectFromwxRect(rect);
821 }
822
823 void
824 RubyDialogCallback_setFrameOfItem(RDItem *item, RDRect rect)
825 {
826         wxRect wrect = wxRectFromRDRect(rect);
827         if (gRubyDialogIsFlipped) {
828                 wxWindow *parent = ((wxWindow *)item)->GetParent();
829                 if (parent != NULL) {
830                         wxRect srect = parent->GetRect();
831                         wrect.SetY(srect.GetHeight() - wrect.GetHeight() - wrect.GetY());
832                 }
833         }
834         ((wxWindow *)item)->SetSize(wrect);
835 }
836
837 void
838 RubyDialogCallback_setStringToItem(RDItem *item, const char *s)
839 {
840         wxString str(s, WX_DEFAULT_CONV);
841         if (wxDynamicCast((wxWindow *)item, wxTextCtrl) != NULL) {
842                 ((wxTextCtrl *)item)->SetValue(str);
843         }
844 }
845
846 void
847 RubyDialogCallback_getStringFromItem(RDItem *item, char *buf, int bufsize)
848 {
849         wxString str;
850         if (wxDynamicCast((wxWindow *)item, wxTextCtrl) != NULL) {
851                 str = ((wxTextCtrl *)item)->GetValue();
852         } else {
853                 buf[0] = 0;
854                 return;
855         }
856         strncpy(buf, str.mb_str(WX_DEFAULT_CONV), bufsize - 1);
857         buf[bufsize - 1] = 0;
858 }
859
860 char *
861 RubyDialogCallback_getStringPtrFromItem(RDItem *item)
862 {
863         wxString str;
864         if (wxDynamicCast((wxWindow *)item, wxTextCtrl) != NULL) {
865                 str = ((wxTextCtrl *)item)->GetValue();
866         } else {
867                 return NULL;
868         }
869         return strdup(str.mb_str(WX_DEFAULT_CONV));
870 }
871
872 char *
873 RubyDialogCallback_titleOfItem(RDItem *item)
874 {
875         wxString str;
876         if (wxDynamicCast((wxWindow *)item, wxTextCtrl) != NULL) {
877                 str = ((wxTextCtrl *)item)->GetValue();
878         } else {
879                 str = ((wxWindow *)item)->GetLabel();
880         }
881         return strdup(str.mb_str(WX_DEFAULT_CONV));
882 }
883
884 void
885 RubyDialogCallback_setTitleToItem(RDItem *item, const char *s)
886 {
887         wxString str(s, WX_DEFAULT_CONV);
888         if (wxDynamicCast((wxWindow *)item, wxTextCtrl) != NULL) {
889                 ((wxTextCtrl *)item)->SetValue(str);
890         } else {
891                 ((wxWindow *)item)->SetLabel(str);
892         }
893 }
894
895 void
896 RubyDialogCallback_setEnabledForItem(RDItem *item, int flag)
897 {
898         ((wxWindow *)item)->Enable(flag);
899 }
900
901 int
902 RubyDialogCallback_isItemEnabled(RDItem *item)
903 {
904 /*      if (wxDynamicCast((wxWindow *)item, wxTextCtrl) != NULL)
905                 return ((wxTextCtrl *)item)->IsEditable();
906         else */
907         return ((wxWindow *)item)->IsEnabled();
908 }
909
910 void
911 RubyDialogCallback_setEditableForItem(RDItem *item, int flag)
912 {
913         if (wxDynamicCast((wxWindow *)item, wxTextCtrl) != NULL)
914                 return ((wxTextCtrl *)item)->SetEditable(flag);
915 }
916
917 int
918 RubyDialogCallback_isItemEditable(RDItem *item)
919 {
920         if (wxDynamicCast((wxWindow *)item, wxTextCtrl) != NULL)
921                 return ((wxTextCtrl *)item)->IsEditable();
922         else return 0;
923 }
924
925 void
926 RubyDialogCallback_setStateForItem(RDItem *item, int state)
927 {
928         if (wxDynamicCast((wxWindow *)item, wxRadioButton) != NULL) {
929                 ((wxRadioButton *)item)->SetValue(state);
930         } else if (wxDynamicCast((wxWindow *)item, wxCheckBox) != NULL) {
931                 ((wxCheckBox *)item)->SetValue(state);
932         } else if (wxDynamicCast((wxWindow *)item, wxToggleButton) != NULL) {
933                 ((wxToggleButton *)item)->SetValue(state);
934         }
935 }
936
937 int
938 RubyDialogCallback_getStateForItem(RDItem *item)
939 {
940         if (wxDynamicCast((wxWindow *)item, wxRadioButton) != NULL) {
941                 return ((wxRadioButton *)item)->GetValue();
942         } else if (wxDynamicCast((wxWindow *)item, wxCheckBox) != NULL) {
943                 return ((wxCheckBox *)item)->GetValue();
944         } else if (wxDynamicCast((wxWindow *)item, wxToggleButton) != NULL) {
945                 return ((wxToggleButton *)item)->GetValue();
946         } else return -1;
947 }
948
949 void
950 RubyDialogCallback_setHiddenForItem(RDItem *item, int flag)
951 {
952         ((wxWindow *)item)->Show(flag == 0);
953 }
954
955 int
956 RubyDialogCallback_isItemHidden(RDItem *item)
957 {
958         return !(((wxWindow *)item)->IsShown());
959 }
960
961 void
962 RubyDialogCallback_setFontForItem(RDItem *item, int size, int family, int style, int weight)
963 {
964         wxTextCtrl *ctrl;
965         wxStaticText *stxt;
966         wxFont font;
967         if ((ctrl = wxDynamicCast((wxWindow *)item, wxTextCtrl)) != NULL) {
968                 wxTextAttr attr = ctrl->GetDefaultStyle();
969                 font = attr.GetFont();
970         } else if ((stxt = wxDynamicCast((wxWindow *)item, wxStaticText)) != NULL) {
971                 font = stxt->GetFont();
972         }
973         if (size == 0)
974                 size = font.GetPointSize();
975         if (family == 0)
976                 family = font.GetFamily();
977         else {
978                 family = (family == 2 ? wxFONTFAMILY_ROMAN :
979                                   (family == 3 ? wxFONTFAMILY_SWISS :
980                                    (family == 4 ? wxFONTFAMILY_MODERN :
981                                         wxFONTFAMILY_DEFAULT)));
982         }
983         if (style == 0)
984                 style = font.GetStyle();
985         else {
986                 style = (style == 2 ? wxFONTSTYLE_SLANT :
987                                  (style == 3 ? wxFONTSTYLE_ITALIC :
988                                   wxFONTSTYLE_NORMAL));
989         }
990         if (weight == 0)
991                 weight = font.GetWeight();
992         else {
993                 weight = (weight == 2 ? wxFONTWEIGHT_BOLD :
994                                   (weight == 3 ? wxFONTWEIGHT_LIGHT :
995                                    wxFONTWEIGHT_NORMAL));
996         }
997         if (ctrl != NULL) {
998                 wxTextAttr newAttr;
999                 newAttr.SetFont(wxFont(size, family, style, weight));
1000                 ctrl->SetDefaultStyle(newAttr);
1001         } else if (stxt != NULL) {
1002                 stxt->SetFont(wxFont(size, family, style, weight));
1003                 wxString label = stxt->GetLabel();
1004                 stxt->SetLabel(_(""));
1005                 stxt->SetLabel(label);  /*  Update the control size  */
1006         }
1007 }
1008
1009 int
1010 RubyDialogCallback_getFontForItem(RDItem *item, int *size, int *family, int *style, int *weight)
1011 {
1012         int n;
1013         wxTextCtrl *ctrl;
1014         if ((ctrl = wxDynamicCast((wxWindow *)item, wxTextCtrl)) != NULL) {
1015                 wxTextAttr attr = ctrl->GetDefaultStyle();
1016                 wxFont font = attr.GetFont();
1017                 if (size != NULL)
1018                         *size = font.GetPointSize();
1019                 if (family != NULL) {
1020                         n = font.GetFamily();
1021                         *family = (n == wxFONTFAMILY_DEFAULT ? 1 :
1022                                            (n == wxFONTFAMILY_ROMAN ? 2 :
1023                                                 (n == wxFONTFAMILY_SWISS ? 3 :
1024                                                  (n == wxFONTFAMILY_MODERN ? 4 :
1025                                                   0))));
1026                 }
1027                 if (style != NULL) {
1028                         n = font.GetStyle();
1029                         *style = (n == wxFONTSTYLE_NORMAL ? 1 :
1030                                           (n == wxFONTSTYLE_SLANT ? 2 :
1031                                            (n == wxFONTSTYLE_ITALIC ? 3 :
1032                                                 0)));
1033                 }
1034                 if (weight != NULL) {
1035                         n = font.GetWeight();
1036                         *weight = (n == wxFONTWEIGHT_NORMAL ? 1 :
1037                                            (n == wxFONTWEIGHT_BOLD ? 2 :
1038                                                 (n == wxFONTWEIGHT_LIGHT ? 3 :
1039                                                  0)));
1040                 }
1041                 return 1;
1042         } else return 0;
1043 }
1044
1045 int
1046 RubyDialogCallback_appendString(RDItem *item, const char *str)
1047 {
1048         wxTextCtrl *ctrl;
1049         if ((ctrl = wxDynamicCast((wxWindow *)item, wxTextCtrl)) != NULL) {
1050                 ctrl->AppendText(wxString(str, WX_DEFAULT_CONV));
1051                 return 1;
1052         } else return 0;
1053 }
1054
1055 void
1056 RubyDialogCallback_setNeedsDisplay(RDItem *item, int flag)
1057 {
1058         if (flag)
1059                 ((wxWindow *)item)->Refresh();
1060 }
1061
1062 int
1063 RubyDialogCallback_countSubItems(RDItem *item)
1064 {
1065         if (wxDynamicCast((wxWindow *)item, wxChoice) != NULL) {
1066                 return ((wxChoice *)item)->GetCount();
1067         } else return 0;
1068 }
1069
1070 int
1071 RubyDialogCallback_appendSubItem(RDItem *item, const char *s)
1072 {
1073         wxString str(s, WX_DEFAULT_CONV);
1074         if (wxDynamicCast((wxWindow *)item, wxChoice) != NULL) {
1075                 return ((wxChoice *)item)->Append(str);
1076         } else return -1;
1077 }
1078
1079 int
1080 RubyDialogCallback_insertSubItem(RDItem *item, const char *s, int pos)
1081 {
1082         wxString str(s, WX_DEFAULT_CONV);
1083         if (wxDynamicCast((wxWindow *)item, wxChoice) != NULL && pos >= 0 && pos < ((wxChoice *)item)->GetCount()) {
1084                 return ((wxChoice *)item)->Insert(str, pos);
1085         } else return -1;
1086 }
1087
1088 int
1089 RubyDialogCallback_deleteSubItem(RDItem *item, int pos)
1090 {       
1091         if (wxDynamicCast((wxWindow *)item, wxChoice) != NULL && pos >= 0 && pos < ((wxChoice *)item)->GetCount()) {
1092                 ((wxChoice *)item)->Delete(pos);
1093                 return pos;
1094         } else return -1;
1095 }
1096
1097 char *
1098 RubyDialogCallback_titleOfSubItem(RDItem *item, int pos)
1099 {
1100         if (wxDynamicCast((wxWindow *)item, wxChoice) != NULL && pos >= 0 && pos < ((wxChoice *)item)->GetCount()) {
1101                 wxString str = ((wxChoice *)item)->GetString(pos);
1102                 return strdup(str.mb_str(WX_DEFAULT_CONV));
1103         } else return NULL;
1104 }
1105
1106 void
1107 RubyDialogCallback_setSelectedSubItem(RDItem *item, int pos)
1108 {
1109         if (wxDynamicCast((wxWindow *)item, wxChoice) != NULL && pos >= 0 && pos < ((wxChoice *)item)->GetCount()) {
1110                 ((wxChoice *)item)->SetSelection(pos);
1111         }
1112 }
1113
1114 int
1115 RubyDialogCallback_selectedSubItem(RDItem *item)
1116 {
1117         if (wxDynamicCast((wxWindow *)item, wxChoice) != NULL) {
1118                 return ((wxChoice *)item)->GetSelection();
1119         } else return -1;
1120 }
1121
1122 RDSize
1123 RubyDialogCallback_sizeOfString(RDItem *item, const char *s)
1124 {
1125         RDSize size;
1126         wxCoord w, h, descent, leading;
1127         wxPaintDC dc((wxWindow *)item);
1128         int len;
1129         const char *s1, *s2, *sfin;
1130         size.width = size.height = 0;
1131         s1 = (s == NULL || s[0] == 0 ? " " : s);
1132         len = strlen(s1);
1133         sfin = s1 + len;
1134         while (1) {
1135                 s2 = strchr(s1, '\n');
1136                 if (s2 == NULL)
1137                         s2 = sfin;
1138                 wxString str(s1, WX_DEFAULT_CONV, s2 - s1);
1139                 dc.GetTextExtent(str, &w, &h, &descent, &leading);
1140                 if (size.width < w)
1141                         size.width = w;
1142                 size.height += h + descent + leading;
1143                 if (s2 >= sfin)
1144                         break;
1145                 s1 = s2 + 1;
1146         }
1147         return size;
1148 }
1149
1150 RDSize
1151 RubyDialogCallback_resizeToBest(RDItem *item)
1152 {
1153         wxSize size;
1154         RDSize rsize;
1155         size = ((wxWindow *)item)->GetBestSize();
1156         ((wxWindow *)item)->SetSize(size);
1157         rsize.width = size.GetWidth();
1158         rsize.height = size.GetHeight();
1159         return rsize;
1160 }
1161
1162 char
1163 RubyDialogCallback_deleteTableColumn(RDItem *item, int col)
1164 {
1165         if (wxDynamicCast((wxWindow *)item, MyListCtrl) != NULL) {
1166                 return ((MyListCtrl *)item)->DeleteColumn(col);
1167         } else return false;
1168 }
1169
1170 char
1171 RubyDialogCallback_insertTableColumn(RDItem *item, int col, const char *heading, int format, int width)
1172 {
1173         if (wxDynamicCast((wxWindow *)item, MyListCtrl) != NULL) {
1174                 wxString hstr((heading ? heading : ""), WX_DEFAULT_CONV);
1175                 return ((MyListCtrl *)item)->InsertColumn(col, hstr, format, width);
1176         } else return false;
1177 }
1178
1179 int
1180 RubyDialogCallback_countTableColumn(RDItem *item)
1181 {
1182         if (wxDynamicCast((wxWindow *)item, MyListCtrl) != NULL) {
1183                 return ((MyListCtrl *)item)->GetColumnCount();
1184         } else return -1;
1185 }
1186
1187 char
1188 RubyDialogCallback_isTableRowSelected(RDItem *item, int row)
1189 {
1190         if (wxDynamicCast((wxWindow *)item, MyListCtrl) != NULL) {
1191                 return ((MyListCtrl *)item)->GetItemState(row, wxLIST_STATE_SELECTED) != 0;
1192         } else return false;
1193 }
1194
1195 char
1196 RubyDialogCallback_setTableRowSelected(RDItem *item, int row, int flag)
1197 {
1198         if (wxDynamicCast((wxWindow *)item, MyListCtrl) != NULL) {
1199                 long state = (flag ? wxLIST_STATE_SELECTED : 0);
1200                 return ((MyListCtrl *)item)->SetItemState(row, state, wxLIST_STATE_SELECTED);
1201         } else return false;
1202 }
1203
1204 void
1205 RubyDialogCallback_refreshTable(RDItem *item)
1206 {
1207         if (wxDynamicCast((wxWindow *)item, MyListCtrl) != NULL) {
1208                 ((MyListCtrl *)item)->RefreshTable();
1209         }
1210 }
1211
1212 int
1213 RubyDialogCallback_savePanel(const char *title, const char *dirname, const char *wildcard, char *buf, int bufsize)
1214 {
1215         int result;
1216         wxString pstr((dirname ? dirname : ""), WX_DEFAULT_CONV);
1217         wxString tstr((title ? title : "Choose a file"), WX_DEFAULT_CONV);
1218         wxString fstr(buf, WX_DEFAULT_CONV);
1219         wxString wstr((wildcard ? wildcard : "All files (*.*)|*.*"), WX_DEFAULT_CONV);
1220         wxWindow *old_focus = wxWindow::FindFocus();
1221         wxFileDialog *dialog = new wxFileDialog(NULL, tstr, pstr, fstr, wstr, wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
1222         if (dialog->ShowModal() == wxID_OK) {
1223                 strncpy(buf, dialog->GetPath().mb_str(wxConvFile), bufsize - 1);
1224                 buf[bufsize - 1] = 0;
1225                 result = 1;
1226         } else {
1227                 buf[0] = 0;
1228                 result = 0;
1229         }
1230         dialog->Destroy();
1231         if (old_focus != NULL)
1232                 old_focus->SetFocus();
1233         return result;
1234 }
1235
1236 int
1237 RubyDialogCallback_openPanel(const char *title, const char *dirname, const char *wildcard, char ***array, int for_directories, int multiple_selection)
1238 {
1239         int result = 0;
1240         wxString pstr((dirname ? dirname : ""), WX_DEFAULT_CONV);
1241         wxString wstr((wildcard ? wildcard : "All files (*.*)|*.*"), WX_DEFAULT_CONV);
1242         int style = wxFD_OPEN | (multiple_selection ? wxFD_MULTIPLE : 0);
1243         wxWindow *old_focus = wxWindow::FindFocus();
1244         if (for_directories) {
1245                 wxString tstr((title ? title : "Choose a directory"), WX_DEFAULT_CONV);
1246                 wxDirDialog *dialog = new wxDirDialog(NULL, tstr, pstr);
1247                 if (dialog->ShowModal() == wxID_OK) {
1248                         *array = (char **)malloc(sizeof(char *));
1249                         (*array)[0] = strdup(dialog->GetPath().mb_str(wxConvFile));
1250                         result = 1;
1251                 }
1252                 dialog->Destroy();
1253         } else {
1254                 wxString tstr((title ? title : "Choose a file"), WX_DEFAULT_CONV);
1255                 wxFileDialog *dialog = new wxFileDialog(NULL, tstr, pstr, _T(""), wstr, style);
1256                 if (dialog->ShowModal() == wxID_OK) {
1257                         if (multiple_selection) {
1258                                 int i, n;
1259                                 wxArrayString paths;
1260                                 dialog->GetPaths(paths);
1261                                 n = paths.GetCount();
1262                                 *array = (char **)malloc(sizeof(char *) * n);
1263                                 for (i = 0; i < n; i++) {
1264                                         (*array)[i] = strdup(paths[i].mb_str(wxConvFile));
1265                                 }
1266                                 result = n;
1267                         } else {
1268                                 *array = (char **)malloc(sizeof(char *));
1269                                 (*array)[0] = strdup(dialog->GetPath().mb_str(wxConvFile));
1270                                 result = 1;
1271                         }
1272                 }
1273                 dialog->Destroy();
1274         }
1275         if (old_focus != NULL)
1276                 old_focus->SetFocus();
1277         return result;
1278 }