31 #include "wx/wxprec.h"
41 #include <wx/graphics.h>
42 #include <wx/imaglist.h>
43 #include <wx/artprov.h>
46 #include <wx/evtloop.h>
47 #include <wx/notifmsg.h>
48 #include <wx/generic/notifmsg.h>
49 #include <wx/splash.h>
50 #include <wx/graphics.h>
51 #include <wx/gdicmn.h>
109 wxPanel::Create( parent,
id, pos,
size, style );
114 GetSizer()->SetSizeHints(
this);
149 wxArtProvider::Push(provider);
152 wxBitmap bitmap(wxArtProvider::GetBitmap(
wxT(
"menu::dm_tiles"), wxART_TOOLBAR, wxSize(16,16)));
153 wxImage image(bitmap.ConvertToImage());
169 wxBoxSizer* itemBoxSizer2 =
new wxBoxSizer(wxHORIZONTAL);
170 itemPanel1->SetSizer(itemBoxSizer2);
176 wxBoxSizer* sizer1 =
new wxBoxSizer(wxVERTICAL);
183 wxStaticBox* itemStaticBoxSizer6Static =
new wxStaticBox(itemPanel1,
wxID_ANY,
_(
"Parameters"));
184 wxStaticBoxSizer* itemStaticBoxSizer6 =
new wxStaticBoxSizer(itemStaticBoxSizer6Static, wxHORIZONTAL);
185 itemBoxSizer2->Add(itemStaticBoxSizer6, 0, wxGROW|wxALL, 0);
188 itemStaticBoxSizer6->Add(
m_Parameters, 0, wxGROW|wxALL, 5);
232 m_ScriptWindow->GetSizer()->Add(
label, 0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxRESERVE_SPACE_EVEN_IF_HIDDEN, 5);
248 sizer->Insert(index,
label, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5);
249 wxSizerItemList& children = sizer->GetChildren();
250 for (
size_t i = index;
i < children.size();
i++)
264 wxSizerItemList& children = sizer->GetChildren();
265 for (
size_t i = 0;
i < children.size();
i++)
279 label.second->Unselect();
306 wxSizerItemList& children = sizer->GetChildren();
307 for (
size_t i =
min(index, min_selected);
i < children.size() &&
i <
max(index, max_selected);
i++) {
328 wxSizerItemList& children = sizer->GetChildren();
329 for (
size_t i = 0;
i < children.size();
i++)
338 wxRect rect = win->GetRect();
341 int client_w, client_h;
350 if (rect_y + rect.height + 5 > view_y + client_h)
351 m_ScriptWindow->Scroll( -1, (rect_y + rect.height - client_h + hLine) / hLine );
380 wxSizerItemList& children = sizer->GetChildren();
381 for (
size_t i = 0;
i < children.size();
i++)
409 vector<pair<CRef<macro::CMacroRep>,
bool>> script;
411 wxSizerItemList& children = sizer->GetChildren();
412 script.reserve(children.size());
413 for (
size_t i = 0;
i < children.size();
i++) {
426 wxSizerItemList& children = sizer->GetChildren();
427 script.reserve(children.size());
428 for (
size_t i = 0;
i < children.size();
i++) {
440 wxSizerItemList& children = sizer->GetChildren();
441 if (script.size() != children.size()) {
444 for (
size_t i = 0;
i < children.size(); ++
i) {
460 wxSizerItemList& children = sizer->GetChildren();
469 macro::CMacroEngine engine;
470 auto syn_files = engine.GetSynonymFilenames(
GetMacros());
472 if (syn_files.empty()) {
475 else if (syn_files.size() > 1) {
486 wxSizerItemList& children = sizer->GetChildren();
487 for (
size_t i = 0;
i < children.size();
i++)
506 wxSetCursor(wxNullCursor);
523 int client_w, client_h;
526 wxSizerItemList& children = sizer->GetChildren();
527 bool rearranged =
false;
528 if (p.x > 0 && p.x < client_w && p.y >= 0 && p.y <= client_h && !lock) {
530 sizer->Detach(macro.second);
533 if (index < children.size()) {
535 sizer->Insert(index, macro.second, 0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxRESERVE_SPACE_EVEN_IF_HIDDEN, 5);
541 sizer->Add(macro.second, 0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxRESERVE_SPACE_EVEN_IF_HIDDEN, 5);
549 for (
size_t i = 0;
i < children.size();
i++) {
550 wxWindow* wxwin = children[
i]->GetWindow();
551 wxwin->SetPosition(wxDefaultPosition);
563 macro.second->ShowWithEffect(wxSHOW_EFFECT_EXPAND);
577 wxImage image(280, 80,
true);
578 wxColour bg(GetBackgroundColour());
579 image.SetRGB(wxRect(0, 0, 280, 80), bg.Red(), bg.Green(), bg.Blue());
580 image.Paste(bitmap.ConvertToImage(), 5, 40 - bitmap.GetHeight() / 2);
581 wxBitmap composite(image);
582 wxSplashScreen *splash =
new wxSplashScreen(composite, wxSPLASH_CENTRE_ON_PARENT | wxSPLASH_TIMEOUT, 2000, frame,
wxID_ANY);
583 wxWindow *win = splash->GetSplashWindow();
584 wxStaticText *
text =
new wxStaticText( win, wxID_STATIC,
wxT(
"Click the lock icon to enable dragging"), wxPoint(10 + bitmap.GetWidth(), 40 - bitmap.GetHeight() / 2 + 3));
585 wxGraphicsContext *gc = wxGraphicsContext::Create();
586 gc->SetFont(
text->GetFont(), *wxBLACK);
590 wxDouble externalLeading;
591 gc->GetTextExtent(
text->GetLabel(), &width, &height, &descent, &externalLeading);
592 splash->SetSize(ceil(width) + 20 + bitmap.GetWidth(), 80);
600 selected.
insert(macro.second);
603 size_t index = children.size();
605 for (
size_t i = 0;
i < children.size();
i++) {
609 if (selected.
find(win) != selected.
end())
611 wxPoint pos = win->GetPosition();
612 if (pos.y > y && pos.y < miny) {
628 sizer->Detach(macro.second);
629 macro.second->Unselect();
630 macro.second->Destroy();
633 wxSizerItemList& children = sizer->GetChildren();
634 for (
size_t i = 0;
i < children.size();
i++)
659 if (
abs(d.x) < 10 &&
abs(d.y) < 10)
681 else if ( p.y > client_h - 5) {
706 wxSizerItemList& children = sizer->GetChildren();
708 vector<int> displacement(children.size(), 0);
719 macro.second->HideWithEffect(wxSHOW_EFFECT_EXPAND);
722 for (
size_t i = 0;
i < children.size();
i++) {
726 if (!win->IsShown()) {
727 height += win->GetSize().GetHeight() + 10;
732 displacement[
i] = -height;
740 if (!win || !win->IsShown())
742 displacement[
i] += 50;
747 if (!win || !win->IsShown())
749 displacement[
i] -= 50;
752 for (
size_t i = 0;
i < children.size();
i++) {
753 int height = displacement[
i];
764 wxPoint displace(0, height);
765 wxPoint current = win->GetPosition();
766 win->SetPosition(current + displace);
772 if (!win || !win->IsShown())
801 wxSizerItemList& children = sizer->GetChildren();
802 for (
size_t i = 0;
i < children.size();
i++)
821 wxSizerItemList& children = sizer->GetChildren();
822 for (
size_t i = 0;
i < children.size();
i++)
850 itemMenu8.Append(
ID_MACROFLOW_CUT,
_(
"Cut\tCtrl+X"), wxEmptyString, wxITEM_NORMAL);
855 itemMenu8.Append(
ID_MACROFLOW_APPEND,
_(
"Add To Library\tAlt+A"), wxEmptyString, wxITEM_NORMAL);
856 itemMenu8.Append(
ID_MACROFLOW_ADD,
_(
"Add New Macro"), wxEmptyString, wxITEM_NORMAL);
857 itemMenu8.Append(
ID_SKIP_STEP,
_(
"Enable/Disable Step\tF3"), wxEmptyString, wxITEM_NORMAL);
858 itemMenu8.Append(
ID_MANUALEDITMACRO,
_(
"Edit Macro Script"), wxEmptyString, wxITEM_NORMAL);
861 PopupMenu(&itemMenu8);
880 m_panel->OnMouseUp();
889 if ( event.GetModifiers() != wxMOD_SHIFT) {
891 if (event.GetModifiers() != wxMOD_CONTROL) {
913 if (event.Dragging()) {
946 if (dlg.ShowModal() != wxID_OK)
960 #define LABEL_WIDTH 500
961 #define MAX_TITLE_LENGTH 200
981 TMacroLabelParent::Create( parent,
id, pos,
size, style );
986 GetSizer()->SetSizeHints(
this);
994 wxGraphicsPath path = wxGraphicsRenderer::GetDefaultRenderer()->CreatePath();
995 wxSize sz = GetSize();
996 path.AddRoundedRectangle(0, 0, sz.GetWidth(), sz.GetHeight(), 15);
1042 unsigned long hash = wxStringHash::stringHash(
str.c_str());
1043 wxColour old = *wxGREEN;
1044 wxImage::HSVValue hsv = wxImage::RGBtoHSV(wxImage::RGBValue(old.Red(), old.Green(), old.Blue()));
1045 hsv.hue = double(
hash % 360) / 360;
1046 hsv.saturation = 0.2;
1047 wxImage::RGBValue rgb = wxImage::HSVtoRGB(hsv);
1048 wxColour upd(rgb.red, rgb.green, rgb.blue);
1055 wxBoxSizer* itemBoxSizer2 =
new wxBoxSizer(wxHORIZONTAL);
1056 itemFrame1->SetSizer(itemBoxSizer2);
1059 itemBoxSizer2->Add(
m_panel, 1, wxGROW|wxALL, 0);
1062 m_panel->SetBackgroundColour(upd);
1068 wxBoxSizer* itemBoxSizer4 =
new wxBoxSizer(wxHORIZONTAL);
1069 m_panel->SetSizer(itemBoxSizer4);
1071 wxBoxSizer* itemBoxSizer5 =
new wxBoxSizer(wxVERTICAL);
1072 itemBoxSizer4->Add(itemBoxSizer5, 0, wxGROW, 0);
1076 itemBoxSizer5->Add(
m_bitmap, 0, wxALIGN_LEFT|wxRESERVE_SPACE_EVEN_IF_HIDDEN|wxALL, 0);
1081 itemBoxSizer5->AddStretchSpacer();
1083 m_index =
new wxStaticText(
m_panel, wxID_STATIC,
_(
" "), wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT );
1084 itemBoxSizer5->Add(
m_index, 0, wxALIGN_LEFT|wxLEFT, 5);
1089 m_text =
new wxStaticText(
m_panel, wxID_STATIC, title, wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE_HORIZONTAL );
1090 itemBoxSizer4->Add(
m_text, 1, wxGROW|wxALL, 5);
1095 wxBoxSizer* itemBoxSizer6 =
new wxBoxSizer(wxVERTICAL);
1096 itemBoxSizer4->Add(itemBoxSizer6, 0, wxGROW, 0);
1098 itemBoxSizer6->AddStretchSpacer();
1100 m_counter =
new wxStaticText(
m_panel, wxID_STATIC,
_(
" "), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT );
1101 itemBoxSizer6->Add(
m_counter, 0, wxALIGN_RIGHT|wxRIGHT, 5);
1110 wxString title = wxString(
m_macro->GetTitle());
1148 return wxNullBitmap;
1162 wxColour old =
m_panel->GetBackgroundColour();
1163 wxImage::HSVValue hsv = wxImage::RGBtoHSV(wxImage::RGBValue(old.Red(), old.Green(), old.Blue()));
1166 hsv.saturation = 0.1;
1168 hsv.saturation = 0.2;
1170 wxImage::RGBValue rgb = wxImage::HSVtoRGB(hsv);
1171 wxColour upd(rgb.red, rgb.green, rgb.blue);
1172 m_panel->SetBackgroundColour(upd);
1179 wxColour old =
m_panel->GetBackgroundColour();
1180 wxImage::HSVValue hsv = wxImage::RGBtoHSV(wxImage::RGBValue(old.Red(), old.Green(), old.Blue()));
1184 wxImage::RGBValue rgb = wxImage::HSVtoRGB(hsv);
1185 wxColour upd(rgb.red, rgb.green, rgb.blue);
1186 m_panel->SetBackgroundColour(upd);
1193 wxColour old =
m_panel->GetBackgroundColour();
1194 wxImage::HSVValue hsv = wxImage::RGBtoHSV(wxImage::RGBValue(old.Red(), old.Green(), old.Blue()));
1198 wxImage::RGBValue rgb = wxImage::HSVtoRGB(hsv);
1199 wxColour upd(rgb.red, rgb.green, rgb.blue);
1200 m_panel->SetBackgroundColour(upd);
1220 wxPoint current = GetPosition();
1221 SetPosition(current + d);
1266 wxSize text_sz =
m_text->GetSize();
1267 wxSize panel_sz = GetSize();
1268 wxFont font =
m_text->GetFont();
1275 wxSize new_text_sz =
m_text->GetSize();
1276 int new_height = panel_sz.GetHeight() + new_text_sz.GetHeight() - text_sz.GetHeight() +
m_text->GetCharHeight();
1277 SetMinSize(wxSize(panel_sz.GetWidth(), new_height));
1278 SetSize(wxSize(panel_sz.GetWidth(), new_height));
1284 wxSize text_sz =
m_text->GetSize();
1285 wxSize panel_sz = GetSize();
1286 wxFont font =
m_text->GetFont();
1293 wxSize new_text_sz =
m_text->GetSize();
1294 int new_height = panel_sz.GetHeight() + new_text_sz.GetHeight() - text_sz.GetHeight() +
m_text->GetCharHeight();
1295 SetMinSize(wxSize(panel_sz.GetWidth(), new_height));
1296 SetSize(wxSize(panel_sz.GetWidth(), new_height));
1302 return m_text->GetFont();
1307 wxSize text_sz =
m_text->GetSize();
1308 wxSize panel_sz = GetSize();
1312 wxSize new_text_sz =
m_text->GetSize();
1313 int new_height = panel_sz.GetHeight() + new_text_sz.GetHeight() - text_sz.GetHeight() +
m_text->GetCharHeight();
1314 SetMinSize(wxSize(panel_sz.GetWidth(), new_height));
1315 SetSize(wxSize(panel_sz.GetWidth(), new_height));
1317 GetParent()->FitInside();
1361 wxPanel::Create( parent,
id, pos,
size, style );
1366 GetSizer()->SetSizeHints(
this);
1385 wxBoxSizer* bs_vertical =
new wxBoxSizer(wxVERTICAL);
1386 SetSizer(bs_vertical);
1388 m_PropGridCtrl =
new wxPropertyGrid (
this,
wxID_ANY, wxDefaultPosition, wxSize(380, -1), wxPG_SPLITTER_AUTO_CENTER | wxPG_DEFAULT_STYLE );
1401 return wxNullBitmap;
1435 macro::IMacroVar* var =
m_macro->GetFirstVar(blk);
1436 wxPGProperty* property;
1440 if (var->IsGUIResolvable())
1442 string value = var->GetGUIResolvedValue();
1443 macro::CMacroVarAsk* pAsk =
dynamic_cast<macro::CMacroVarAsk*
>(var);
1446 property =
new wxStringProperty ( pAsk->GetName(), wxPG_LABEL,
value );
1450 macro::CMacroVarChoice* pChoice =
dynamic_cast<macro::CMacroVarChoice*
>(var);
1455 wxArrayString tchoices;
1456 const string* stored_value = pChoice->GetFirstChoice();
1457 while (stored_value)
1459 tchoices.Add(wxString(*stored_value));
1460 if (*stored_value ==
value)
1463 stored_value = pChoice->GetNextChoice();
1465 property =
new wxEnumProperty ( wxString(pChoice->GetName()), wxPG_LABEL, tchoices, wxArrayInt(), sel );
1471 m_props.push_back(make_pair(var, property));
1474 var =
m_macro->GetNextVar(blk);
1487 macro::IMacroVar* var = p.first;
1488 wxPGProperty*
property = p.second;
1489 if (var && property) {
1490 string old = var->GetGUIResolvedValue();
1491 string value =
property->GetValueAsString().ToStdString();
1492 var->SetGUIResolvedValue(
value);
1493 old_to_new[old] =
value;
1494 var_to_new[var->GetName()] =
value;
1495 var_to_old[var->GetName()] = old;
1498 string title =
m_macro->GetTitle();
1499 string old_title = title;
1500 for (
auto p : old_to_new) {
1503 if (title != old_title) {
1510 bool is_var =
false;
1514 string str = *++line_reader;
1519 new_source +=
str +
"\n";
1527 new_source +=
str +
"\n";
1532 new_source +=
str +
"\n";
1536 new_source +=
str +
"\n";
1539 list<string> row_values;
1541 if (row_values.size() == 2) {
1542 string var = row_values.front();
1543 string value = row_values.back();
1548 if (var_to_new.
find(var) != var_to_new.
end())
1552 new_source +=
str +
"\n";
1553 }
while (!line_reader.
AtEOF());
1555 if (
source != new_source) {
1556 m_macro->SetSource(new_source);
void OpenEditor(CRef< macro::CMacroRep > macro_rep)
void OnMouseDoubleClick(wxMouseEvent &event)
void OnMouseDown(wxMouseEvent &event)
void OnMouseUp(wxMouseEvent &event)
void OnMouseDrag(wxMouseEvent &event)
void OnMouseAndShiftDown()
wxGenericStaticBitmap * m_bitmap
void UpdateCounter(size_t counter)
CMacroLabel()
Constructors.
void UpdateMacroRep(CRef< macro::CMacroRep > macro)
CMacroLabelHandler * m_handler5
void SetIndex(size_t index)
CMacroLabelHandler * m_handler2
CMacroLabelHandler * m_handler1
wxIcon GetIconResource(const wxString &name)
Retrieves icon resources.
void Init()
Initialises member variables.
~CMacroLabel()
Destructor.
CRef< macro::CMacroRep > m_macro
static wxColour GetLabelColour(const string &str)
macro::CMacroEngine m_MEngine
wxString x_ConstructTitle() const
wxBitmap GetBitmapResource(const wxString &name)
Retrieves bitmap resources.
bool Create(wxWindow *parent, wxWindowID id=wxID_ANY, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=wxFRAME_SHAPED|wxBORDER_NONE)
void CreateControls()
Creates the controls and sizers.
CRef< macro::CMacroRep > GetMacro()
int x_GetTextWidth() const
static bool ShowToolTips()
Should we show tooltips?
CMacroLabelHandler * m_handler4
void UpdateMacro(CRef< macro::CMacroRep > macro)
CMacroLabelHandler * m_handler3
CRef< macro::CMacroRep > m_macro
void CreateControls()
Creates the controls and sizers.
wxIcon GetIconResource(const wxString &name)
Retrieves icon resources.
void Init()
Initialises member variables.
CMacroParamsPanel()
Constructors.
~CMacroParamsPanel()
Destructor.
wxPropertyGrid * m_PropGridCtrl
void OnPropertyChanged(wxPropertyGridEvent &event)
wxBitmap GetBitmapResource(const wxString &name)
Retrieves bitmap resources.
vector< pair< macro::IMacroVar *, wxPGProperty * > > m_props
bool Create(wxWindow *parent, wxWindowID id=wxID_ANY, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=wxTAB_TRAVERSAL)
Creation.
void SetMacro(CRef< macro::CMacroRep > macro, CMacroLabel *label=NULL)
static bool ShowToolTips()
Should we show tooltips?
CRef< macro::CMacroRep > GetMacro()
void Init()
Initialises member variables.
wxBitmap GetBitmapResource(const wxString &name)
Retrieves bitmap resources.
size_t x_GetInsertIndex(int y, wxSizerItemList &children)
wxPoint m_CurrentMousePos
CMacroParamsPanel * m_Parameters
wxIcon GetIconResource(const wxString &name)
Retrieves icon resources.
bool Create(wxWindow *parent, wxWindowID id=10001, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(400, 300), long style=wxTAB_TRAVERSAL)
Creation.
void SetMousePosition(wxPoint p)
void x_ShowSplashWindow(CMacroFlowEditor *frame)
CScriptPanel()
Constructors.
void CreateControls()
Creates the controls and sizers.
void SetSynonymFile(const string &filename)
wxScrolledWindow * m_ScriptWindow
vector< CRef< macro::CMacroRep > > TVecMacroRep
size_t GetIndex(CMacroLabel *label)
void SetModified(bool modified)
void SelectMacro(CMacroLabel *label)
void SelectItem(size_t item)
wxPoint GetMousePosition()
CMacroLabel * AddMacro(CRef< macro::CMacroRep > macro)
map< size_t, CMacroLabel * > m_selected_macros
void SelectMacros(CMacroLabel *label)
static const string sm_Multiple
void x_ShiftBottomLabels()
vector< pair< CRef< macro::CMacroRep >, bool > > GetScript()
bool UpdateMacroSources(const TVecMacroRep &script)
void UpdateCounter(size_t i, size_t counter)
static bool ShowToolTips()
Should we show tooltips?
CMacroLabelHandler * m_handler
wxPoint GetCurrentMousePosition()
void LookupSynonymFiles()
void OnRightClick(wxContextMenuEvent &evt)
~CScriptPanel()
Destructor.
CMacroLabel * InsertMacro(CRef< macro::CMacroRep > macro, size_t index)
Simple implementation of ILineReader for i(o)streams.
static wxString ResolvePath(const wxString &path, const wxString &rel_name)
Utility function to hide the platform specifics of locating our standard directories and files.
CwxSplittingArtProvider - an adapter for old-style image aliases.
const_iterator begin() const
const_iterator end() const
const_iterator find(const key_type &key) const
iterator_bool insert(const value_type &val)
const_iterator find(const key_type &key) const
const_iterator end() const
virtual void RegisterFileAlias(const wxArtID &anId, const wxArtClient &aClient, const wxSize &aSize, const wxString &aName, long aType=wxBITMAP_TYPE_ANY, int anIndex=-1)
int AddDirectory(wxString aDirName)
IMPLEMENT_CLASS(CFloatingFrame, CFloatingFrameBaseClass) const static long kFloatFrameStyle
CFloatingFrame.
bool AtEOF(void) const
Indicates (negatively) whether there is any more input.
void Reset(void)
Reset reference object.
#define END_NCBI_SCOPE
End previously defined NCBI scope.
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
static list< string > & Split(const CTempString str, const CTempString delim, list< string > &arr, TSplitFlags flags=0, vector< SIZE_TYPE > *token_pos=NULL)
Split a string using specified delimiters.
static void TruncateSpacesInPlace(string &str, ETrunc where=eTrunc_Both)
Truncate spaces in a string (in-place)
static bool StartsWith(const CTempString str, const CTempString start, ECase use_case=eCase)
Check if a string starts with a specified prefix value.
static string & ReplaceInPlace(string &src, const string &search, const string &replace, SIZE_TYPE start_pos=0, SIZE_TYPE max_replace=0, SIZE_TYPE *num_replace=0)
Replace occurrences of a substring within a string.
@ fSplit_MergeDelimiters
Merge adjacent delimiters.
@ eNocase
Case insensitive compare.
static const char label[]
Lightweight interface for getting lines of data with minimal memory copying.
#define ID_MACROFLOW_ZOOM_OUT
#define ID_MACROFLOW_APPEND
#define ID_MACROFLOW_DELETE
#define ID_MACROFLOW_COPY
#define ID_MACROFLOW_PASTE
#define ID_MACROFLOW_ZOOM_IN
#define ID_MANUALEDITMACRO
#define ID_MACROFLOW_DUPLICATE
static void text(MDB_val *v)
void ReportUsage(const wxString &dialog_name, const string &action_name)
Report events in the macro_flow_editor and in the macro_editor.
const struct ncbi::grid::netcache::search::fields::SIZE size
const CharType(& source)[N]
wxNonOwnedWindow TMacroLabelParent
#define ID_CSCRIPTPANEL_SCROLLEDWND1
#define ID_CSCRIPTPANEL_SCROLLEDWND
static const char * str(char *buf, int n)