News:

Accounts with zero posts and zero activity during the last months will be deleted periodically to fight SPAM!

Main Menu

Misc questions around CB and wxWidgets integration

Started by eranon, May 10, 2012, 02:51:22 PM

Previous topic - Next topic

eranon

Hello,

I'm an independent developer and just switching from Windows specific development (I'm using VC6 intensively since some years until now) to cross-platforms one. So, I've tested several IDE/GUI-lib pairs these last weeks and finally choosen to adopt Code::Blocks/wxWidgets :)

Well, so, I've well built wxWidgets libs I need w/ compiler I'm choosen (ie. TDM-GCC) and binded both to CB environment. Also, these last days I've followed the official wxSmith tutorial (discovering the sizers realm - lol).

At this step, I'm wondering some basic questions. Here they are (w/o special order) :

- How to quickly reach an implementation method from the events list of an item ? Should I do a text search every time or is there a quick way (knowing double-click or right-click doesn't seems to do anything ; from my test) ? Maybe a plugin ?

- Is there a way to have wxWidgets autocompletion ?
- Is there a way to have a quick view of any wxWidgets class, method or property pointed by mouse in current code ? I've configured the help plugin to launch wxwidgets.chm when I hit F1, but it just fill-in the index field in the help window ; so, not a direct and smart access as done with MSDN and VC IDE).

Well, so, as you can see just some stuffs about comfort, but it's important to stay concentrated on code (and even more when we - me in this occurence - have to learn the wxWidgets architecture) :)

All your lighted tips and tricks are obviously welcome ;)
[Independent dev. - wxWidgets 3.0.0 under "Win 7 Pro 64-bit, C::B SVN 9435 & wxSmith, TDM64-GCC 4.7 & MSVC9" + "OS X 10.8, FSF GCC 4.7 & C::B SVN 8909"]

MortenMacFly

You forgot to provide any platform/version information, so answers are general.

Quote from: eanon on May 10, 2012, 02:51:22 PM
- How to quickly reach an implementation method from the events list of an item ? Should I do a text search every time or is there a quick way (knowing double-click or right-click doesn't seems to do anything ; from my test) ? Maybe a plugin ?
Double-click on the item in the wxSmith UI editor

Quote from: eanon on May 10, 2012, 02:51:22 PM
- Is there a way to have wxWidgets autocompletion ?
Yes, works well in recent nightlies and fine here.

Quote from: eanon on May 10, 2012, 02:51:22 PM
- Is there a way to have a quick view of any wxWidgets class, method or property pointed by mouse in current code ?
Yes, works well in recent nightlies and fine here.
Compiler logging: Settings->Compiler & Debugger->tab "Other"->Compiler logging="Full command line"
C::B Manual: [url="https://www.codeblocks.org/docs/main_codeblocks_en.html"]https://www.codeblocks.org/docs/main_codeblocks_en.html[/url]
C::B FAQ: [url="https://wiki.codeblocks.org/index.php?title=FAQ"]https://wiki.codeblocks.org/index.php?title=FAQ[/url]

eranon

Thanx for your accurate reply, MortenMacFly. Effectively, you're right (forgotten to indicate my environment) : I'm currently under Windows using Code::Blocks 10.05 (so last stable one, unless error) and wxWidgets 2.8.12.0. So, if I understand, I just have to get the last nightly C::B and all will become marvellous :)

QuoteDouble-click on the item in the wxSmith UI editor
Hmm, OK when it's about control with default event. But how when it's about a menu item or not-default event, for example ?

-
EDIT : OK, installed nightly build svn 7932 and I've now nice autocompletion and quick tip on mouse hover. So, It just remains to find a smart way to reach every no-default event handlers from resource browser and UI editor ::)
[Independent dev. - wxWidgets 3.0.0 under "Win 7 Pro 64-bit, C::B SVN 9435 & wxSmith, TDM64-GCC 4.7 & MSVC9" + "OS X 10.8, FSF GCC 4.7 & C::B SVN 8909"]

MortenMacFly

Quote from: eanon on May 10, 2012, 05:59:20 PM
EDIT : OK, installed nightly build svn 7932 and I've now nice autocompletion and quick tip on mouse hover. So, It just remains to find a smart way to reach every no-default event handlers from resource browser and UI editor ::)
Use the CC toolbar - it offers quick access to all methods in/of that file.
Compiler logging: Settings->Compiler & Debugger->tab "Other"->Compiler logging="Full command line"
C::B Manual: [url="https://www.codeblocks.org/docs/main_codeblocks_en.html"]https://www.codeblocks.org/docs/main_codeblocks_en.html[/url]
C::B FAQ: [url="https://wiki.codeblocks.org/index.php?title=FAQ"]https://wiki.codeblocks.org/index.php?title=FAQ[/url]

eranon

OK, thanks, I'm starting to enter in the C::B spirit ^^
[Independent dev. - wxWidgets 3.0.0 under "Win 7 Pro 64-bit, C::B SVN 9435 & wxSmith, TDM64-GCC 4.7 & MSVC9" + "OS X 10.8, FSF GCC 4.7 & C::B SVN 8909"]

ollydbg

Quote from: MortenMacFly on May 10, 2012, 07:44:33 PM
Quote from: eanon on May 10, 2012, 05:59:20 PM
EDIT : OK, installed nightly build svn 7932 and I've now nice autocompletion and quick tip on mouse hover. So, It just remains to find a smart way to reach every no-default event handlers from resource browser and UI editor ::)
Use the CC toolbar - it offers quick access to all methods in/of that file.

Today, I have the same question about this, and search the forum, I found that it was discussed here.

Now, for the image below:


I think there need a context menu on the entry like "goto declaration and goto implementation", When I search the related code, I found that wxsmith definitely know those information.

Here is the code:
cb_trunk\src\plugins\contrib\wxSmith\wxwidgets\wxseventseditor.cpp

void wxsEventsEditor::PGChanged(wxsItem* Item,wxsPropertyGridManager* Grid,wxPGId Id)
{
    // Just small check to avoid some invalid updates
    if ( Item != m_Item )
    {
        return;
    }

    int Index;
for ( Index=0; Index<(int)m_Ids.Count(); Index++ )
{
    if ( m_Ids[Index] == Id ) break;
}

if ( Index>=(int)m_Ids.Count() )
{
    return;
}

wxString Selection = Grid->GetPropertyValueAsString(Id);

    if ( Selection == NoneStr )
    {
        m_Events->SetHandler(Index,_T(""));
    }
    else if ( Selection == AddNewStr )
    {
        m_Events->SetHandler(Index,GetNewFunction(m_Events->GetDesc(Index)));
        BuildEvents(m_Item,Grid);
    }
    else
    {
        m_Events->SetHandler(Index,Selection);
        GotoHandler(Index);
    }

    m_Data->NotifyChange(m_Item);
}


and


bool wxsEventsEditor::GotoHandler(int Index)
{
    cbEditor* Editor = Manager::Get()->GetEditorManager()->Open(m_Source);
    if ( !Editor )
    {
        return false;
    }

wxString FunctionName = m_Events->GetHandler(Index);
if ( FunctionName.IsEmpty() )
{
    return false;
}

    cbStyledTextCtrl* Ctrl = Editor->GetControl();
    wxString FullText = Ctrl->GetText();
    int Begin = 0;
    int End = Ctrl->GetLength();
    while ( Begin < End )
    {
        int Pos = Ctrl->FindText(Begin,End,FunctionName,wxSCI_FIND_MATCHCASE);
        if ( Pos < 0 ) break;

        // Checking if there's <ClassName> :: sequence before function

        int Before = Pos;
        while ( --Before >= 0 )
        {
            wxChar Ch = Ctrl->GetCharAt(Before);
            if ( Ch!=' ' && Ch!='\t' && Ch!='\r' && Ch!='\n' ) break;
        }
        if ( Before >= 1 )
        {
            if ( Ctrl->GetCharAt(Before) == ':' && Ctrl->GetCharAt(Before-1) == ':' )
            {
                Before--;
                while ( --Before >= 0 )
                {
                    wxChar Ch = Ctrl->GetCharAt(Before);
                    if ( Ch!=' ' && Ch!='\t' && Ch!='\r' && Ch!='\n' ) break;
                }
                if ( Before > 0 )
                {
                    wxString ClassName;
                    while ( Before>=0 )
                    {
                        wxChar Ch = Ctrl->GetCharAt(Before--);
                        if ( (Ch<'a' || Ch>'z') && (Ch<'A' || Ch>'Z') && (Ch<'0' || Ch>'9') && (Ch!='_') ) break;
                        ClassName = Ch + ClassName;
                    }

                    if ( ClassName == m_Class )
                    {
                        // Test if there's ( after function name
                        int After = Pos + FunctionName.Length();
                        while ( After < End )
                        {
                            wxChar Ch = Ctrl->GetCharAt(After);
                            if ( Ch!=' ' && Ch!='\t' && Ch!='\r' && Ch!='\n' ) break;
                            After++;
                        }
                        if ( After < End )
                        {
                            if ( Ctrl->GetCharAt(After) == '(' )
                            {
                                Editor->GotoLine(Ctrl->LineFromPosition(Pos));
                                return true;
                            }
                        }
                    }
                }
            }
        }

        Begin = Pos + FunctionName.Length();

    }
    return false;
}


So, you see the two default entry is:

namespace
{
    const wxString NoneStr   = _("-- None --");
    const wxString AddNewStr = _("-- Add new handler --");
}


What I think is that we can call wxsmith's function

GotoHandler(Index);


I think wxsmith know every thing about this. (at least the implementation and declaration).

But I'm not a wxsmith guru, so you may find some time to implement this nice feature.
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

ollydbg

I have a very dirty patch, that emulate the same OnChange event, so you double click on the event item, and it will jump to the event handler implementation.


Index: wxspropertygridmanager.cpp
===================================================================
--- wxspropertygridmanager.cpp (revision 8067)
+++ wxspropertygridmanager.cpp (working copy)
@@ -101,6 +101,41 @@
    MainContainer->OnExtraPropertyChanged(this,ID);
}

+void wxsPropertyGridManager::OnDoubleClick(wxPropertyGridEvent& event)
+{
+    wxPGId ID = event.GetProperty();
+    for ( size_t i = PGIDs.Count(); i-- > 0; )
+    {
+        if ( PGIDs[i] == ID )
+        {
+            wxsPropertyContainer* Container = PGContainers[i];
+            if ( !PGEnteries[i]->PGRead(Container,this,ID,PGIndexes[i]) )
+            {
+                wxString ErrorMsg;
+                ErrorMsg << _T("wxSmith: Couldn't read value from wxsPropertyGridManager")
+                         << _T(", propgrid name=") << PGEnteries[i]->GetPGName()
+                         << _T(", date name=")     << PGEnteries[i]->GetDataName()
+                         << _T(", type name=")     << PGEnteries[i]->GetTypeName();
+                Manager::Get()->GetLogManager()->DebugLogError(ErrorMsg);
+            }
+
+            // Notifying about property change
+            Container->NotifyPropertyChangeFromPropertyGrid();
+
+            // Notifying about sub property change
+            if ( Container!=MainContainer && MainContainer!=0 )
+            {
+                MainContainer->OnSubPropertyChanged(Container);
+            }
+            Update(0);
+            return;
+        }
+    }
+
+    // Did not found changed id, it's time to say to container
+    MainContainer->OnExtraPropertyChanged(this,ID);
+}
+
void wxsPropertyGridManager::Update(wxsPropertyContainer* PC)
{
    if ( PC && PGContainersSet.find(PC) == PGContainersSet.end() )
@@ -306,4 +341,5 @@

BEGIN_EVENT_TABLE(wxsPropertyGridManager,wxPropertyGridManager)
    EVT_PG_CHANGED(-1,wxsPropertyGridManager::OnChange)
+    EVT_PG_DOUBLE_CLICK(-1,wxsPropertyGridManager::OnDoubleClick)
END_EVENT_TABLE()
Index: wxspropertygridmanager.h
===================================================================
--- wxspropertygridmanager.h (revision 8067)
+++ wxspropertygridmanager.h (working copy)
@@ -95,7 +95,7 @@

        /** \brief Function unbinding given container
         *
-         * This function destroys all property enteries using given container.
+         * This function destroys all property entries using given container.
         * It's automatically called in container's destructor but it may
         * be used in other places too.
         *
@@ -130,9 +130,12 @@
        /** \brief Changing main property container */
        void SetNewMainContainer(wxsPropertyContainer* NewMain);

-        /** \brief Handler for roporting change event */
+        /** \brief Handler for reporting change event */
        void OnChange(wxPropertyGridEvent& event);

+        /** \brief Handler for jumping to event handler */
+        void OnDoubleClick(wxPropertyGridEvent& event);
+
        /** \brief Data of selected property */
        struct SelectionData
        {
@@ -150,7 +153,7 @@
        /** \brief Restoring selected property
         *
         * \param Data structure containing selection data, if NULL,
-         *        selection will be resotred from internal variable
+         *        selection will be restored from internal variable
         */
        void RestoreSelected(const SelectionData* Data=0);

@@ -171,7 +174,7 @@
        WX_DECLARE_HASH_SET(wxsPropertyContainer*,wxPointerHash,wxPointerEqual,wxSetCont);

        wxArrayPGId  PGIDs;                         ///< \brief Array of property identifiers
-        wxArrayProps PGEnteries;                    ///< \brief Array mapping enteries in grid to properties
+        wxArrayProps PGEnteries;                    ///< \brief Array mapping entries in grid to properties
        wxArrayLong  PGIndexes;                     ///< \brief Array of internal property indexes used inside wxsProperty
        wxArrayCont  PGContainers;                  ///< \brief Array of container objects associated with properties
        wxSetCont    PGContainersSet;               ///< \brief Set of used containers, will be used to quickly determine if given container is used in manager
@@ -190,7 +193,7 @@
        friend class wxsPropertyContainer;
};

-/** \brief Macro for easy acces to property grid manager */
+/** \brief Macro for easy access to property grid manager */
#define wxsPGRID() wxsPropertyGridManager::Get()

#endif



The patch is too dirty because I'm not quite familiar with wxsPropertyGridManager and related controls.

The function wxsPropertyGridManager::OnDoubleClick need to be refined to purely handle the "jump" feature. :)

If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

eranon

Quote from: ollydbg on June 30, 2012, 05:09:27 PM
But I'm not a wxsmith guru, so you may find some time to implement this nice feature.

I was on other fields since june and this is the reason why of the delay between your post and my reaction, Ollydbg. I fully agree : it would be nice to have this kind of feature (a way to reach declaration or implementation of an event-handler from the events list).

Maybe there's an offcial place to submit feature ?!
[Independent dev. - wxWidgets 3.0.0 under "Win 7 Pro 64-bit, C::B SVN 9435 & wxSmith, TDM64-GCC 4.7 & MSVC9" + "OS X 10.8, FSF GCC 4.7 & C::B SVN 8909"]

ollydbg

Quote from: eanon on August 11, 2012, 09:49:20 PM
Quote from: ollydbg on June 30, 2012, 05:09:27 PM
But I'm not a wxsmith guru, so you may find some time to implement this nice feature.

I was on other fields since june and this is the reason why of the delay between your post and my reaction, Ollydbg. I fully agree : it would be nice to have this kind of feature (a way to reach declaration or implementation of an event-handler from the events list).

Maybe there's an offcial place to submit feature ?!

You can add a feature request, I have already add one days ago, see:
https://developer.berlios.de/feature/?func=detailfeature&feature_id=5540&group_id=5358
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

eranon

Seen ! So, not necessary to create a double entry :)
[Independent dev. - wxWidgets 3.0.0 under "Win 7 Pro 64-bit, C::B SVN 9435 & wxSmith, TDM64-GCC 4.7 & MSVC9" + "OS X 10.8, FSF GCC 4.7 & C::B SVN 8909"]

ollydbg

FYI: with the patch below, user can double click on the Event ID name (entries in the left column), then the editor will jump to the associated event handler function body.

The method was quite simple, I reuse the OnChange() handler when the user double click on the entry, if the visual string matches the function name already assigned for the EventID, jump to the function body. In other cases, it is a real event handler name change, so it goes to the old routine.


Index: properties/wxspropertygridmanager.cpp
===================================================================
--- properties/wxspropertygridmanager.cpp (revision 8249)
+++ properties/wxspropertygridmanager.cpp (working copy)
@@ -306,4 +306,5 @@

BEGIN_EVENT_TABLE(wxsPropertyGridManager,wxPropertyGridManager)
     EVT_PG_CHANGED(-1,wxsPropertyGridManager::OnChange)
+    EVT_PG_DOUBLE_CLICK(-1,wxsPropertyGridManager::OnChange)
END_EVENT_TABLE()
Index: wxwidgets/wxseventseditor.cpp
===================================================================
--- wxwidgets/wxseventseditor.cpp (revision 8249)
+++ wxwidgets/wxseventseditor.cpp (working copy)
@@ -151,6 +151,15 @@
     }

     wxString Selection = Grid->GetPropertyValueAsString(Id);
+    wxString oldHandlerName = m_Events->GetHandler(Index);
+    if ( (!oldHandlerName.IsEmpty()) && oldHandlerName.IsSameAs(Selection) )
+    {
+        // which means this event is emulated from the double click on the event ID name,
+        // user want to jump to the implementation of this event handler function body,
+        // no need to rebuild the event and notify other part
+        GotoHandler(Index);
+        return;
+     }

     if ( Selection == NoneStr )
     {


Tests and comments are all welcome.
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

eranon

Is it present in the current nightly build, Olly, or should we add-it by ourself in the source for testing ?
[Independent dev. - wxWidgets 3.0.0 under "Win 7 Pro 64-bit, C::B SVN 9435 & wxSmith, TDM64-GCC 4.7 & MSVC9" + "OS X 10.8, FSF GCC 4.7 & C::B SVN 8909"]

ollydbg

Quote from: eanon on August 31, 2012, 03:16:45 PM
Is it present in the current nightly build,
NO.
Quote
Olly, or should we add-it by ourself in the source for testing ?
To test it: Check out the codeblocks' source code, apply the patch, and build the source yourself.

PS: If there were no objections for several days, I will commit it to trunk, and some days later, this feature will appeared in nightly build.
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

eranon

#13
OK, I'll try to test-it tomorrow.

--
EDIT : oops ! tommorow being today since it's already 1:42 AM... So after my personal human nightly sleep, I mean :)

EDIT #2 : It works for me ! Nice feature, Ollydbg. Tested under Win7 with patch added in source code of C::B SVN rev 8328 (against wx 2.8.12 ; this precision because I've seen a wx 2.9 workspace beside, but don't know if it's fully ready for buidling).
[Independent dev. - wxWidgets 3.0.0 under "Win 7 Pro 64-bit, C::B SVN 9435 & wxSmith, TDM64-GCC 4.7 & MSVC9" + "OS X 10.8, FSF GCC 4.7 & C::B SVN 8909"]

ollydbg

Quote from: eanon on September 02, 2012, 01:42:12 AM
OK, I'll try to test-it tomorrow.

--
EDIT : oops ! tommorow being today since it's already 1:42 AM... So after my personal human nightly sleep, I mean :)

EDIT #2 : It works for me ! Nice feature, Ollydbg. Tested under Win7 with patch added in source code of C::B SVN rev 8328 (against wx 2.8.12 ; this precision because I've seen a wx 2.9 workspace beside, but don't know if it's fully ready for buidling).
Thanks for the test.
It is in trunk now. (rev 8336)
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.