Author Topic: Papercuts :)  (Read 16701 times)

Offline Kazade

  • Multiple posting newcomer
  • *
  • Posts: 73
Papercuts :)
« on: June 29, 2009, 11:22:25 am »
Hi all,

Some of you may know that Ubuntu recently started a project called 100 papercuts. The aim of which is to find common, easy to fix, usability bugs that people who frequently use Ubuntu get so used to them they don't notice. Well, what I thought I'd do is take a look around Code::Blocks, and see if I could find little bugs which are easy(ish) to fix. I thought it would be good if you guys could look around and also list them here.

So here we go (these are on Ubuntu)

  • Tip of the day window is not centered on screen at program start. #15940
  • When compiz is enabled the ToDo list window titlebar can appear hidden behind the top panel
  • Copying a line from the build log (right click -> copy selection) results in a second instance of the popup menu after the first. #15939
  • On Linux it is impossible to see long messages in the build log because the scrollbar doesn't extend far enough #15941
  • When viewing the new projects list as large icons, the icons are not aligned.
  • Pressing CTRL+J after the keyword "class", brings up a dialog which is not centered
  • "file path" and "file name" are not capitalized consistently with the rest of the Thread Search settings dialog
  • Delete key does not work in the project tree and in the watch window - Thanks oBFusCATed
  • Can't use "thread search" in "compilergcc.cpp", a message box shows this file can't be opened. - Thanks ollydbg

I don't know if these bugs are on the bug tracker or not yet, a little later I'll update this post with bug numbers and create bugs for any that don't exist (I'm supposed to be working right now :D ). I'll see if I can find more.

Edit: Added some bugs to Berlios
« Last Edit: June 30, 2009, 05:35:29 pm by Kazade »

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 5915
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Re: Papercuts :)
« Reply #1 on: June 29, 2009, 01:03:28 pm »
Support, though I use Windows.
Quote
On Linux it is impossible to see long messages in the build log because the scrollbar doesn't extend far enough

Seems the log width was fixed.

in CompilerGCC::OnAttach() function.
Code
// create warnings/errors log
    wxArrayString titles;
    wxArrayInt widths;
    titles.Add(_("File"));
    titles.Add(_("Line"));
    titles.Add(_("Message"));
    widths.Add(128);
    widths.Add(48);
    widths.Add(640);

    m_pListLog = new CompilerMessages(titles, widths);
    m_pListLog->SetCompilerErrors(&m_Errors);
    m_ListPageIndex = msgMan->SetLog(m_pListLog);
    msgMan->Slot(m_ListPageIndex).title = _("Build messages");

In windows, double click on the stick between two bar's title will automatically expand the log. Not sure it will happen in wxWidgets under Linux. :D

Here is the CompilerMessages declaration.
Code
class CompilerMessages : public ListCtrlLogger, public wxEvtHandler
{
    public:
        CompilerMessages(const wxArrayString& titles, const wxArrayInt& widths);
        virtual ~CompilerMessages();
        virtual void SetCompilerErrors(CompilerErrors* errors){ m_pErrors = errors; }
        virtual void FocusError(int nr);

        virtual wxWindow* CreateControl(wxWindow* parent);
    private:
        void OnClick(wxCommandEvent& event);
        void OnDoubleClick(wxCommandEvent& event);

        CompilerErrors* m_pErrors;

        DECLARE_EVENT_TABLE()
};

« Last Edit: June 29, 2009, 02:15:33 pm by ollydbg »
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.

Offline Kazade

  • Multiple posting newcomer
  • *
  • Posts: 73
Re: Papercuts :)
« Reply #2 on: June 29, 2009, 01:08:05 pm »
Double clicking doesn't work on Linux, which is the real issue. I guess that's probably unfixable by the C::B devs (to do with GTK+ perhaps) but resetting the width of the build log whenever it outputs a new line would work.

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 5915
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Re: Papercuts :)
« Reply #3 on: June 29, 2009, 01:34:48 pm »
Continue with this problem.

Maybe, you could try this:

Quote
wxListCtrl::SetColumnWidth

bool SetColumnWidth(int col, int width)

Sets the column width.

width can be a width in pixels or wxLIST_AUTOSIZE (-1) or wxLIST_AUTOSIZE_USEHEADER (-2). wxLIST_AUTOSIZE will resize the column to the length of its longest item. wxLIST_AUTOSIZE_USEHEADER will resize the column to the length of the header (Win32) or 80 pixels (other platforms).

In small or normal icon view, col must be -1, and the column width is set for all columns.

wxLIST_AUTOSIZE should be used. :D

It was already there, but I'm not sure why this statement was comment out...
Code
void CompilerGCC::LogWarningOrError(CompilerLineType lt, cbProject* prj, const wxString& filename, const wxString& line, const wxString& msg)
{
    // add build message
    wxArrayString errors;
    errors.Add(filename);
    errors.Add(line);
    errors.Add(msg);

    Logger::level lv = Logger::info;
    if (lt == cltError)
        lv = Logger::error;
    else if (lt == cltWarning)
        lv = Logger::warning;

    m_pListLog->Append(errors, lv);
//    m_pListLog->GetListControl()->SetColumnWidth(2, wxLIST_AUTOSIZE);

    // add to error keeping struct
    m_Errors.AddError(lt, prj, filename, line.IsEmpty() ? 0 : atoi(wxSafeConvertWX2MB(line)), msg);
}
« Last Edit: June 29, 2009, 01:44:08 pm by ollydbg »
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.

Offline Kazade

  • Multiple posting newcomer
  • *
  • Posts: 73
Re: Papercuts :)
« Reply #4 on: June 29, 2009, 01:45:10 pm »
wxLIST_AUTOSIZE should be used. :D

Thanks, I've added that suggestion to the bug report I created :D

When/if I have time, I'll try and fix some of these.

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 5915
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Re: Papercuts :)
« Reply #5 on: June 29, 2009, 01:49:20 pm »
wxLIST_AUTOSIZE should be used. :D

Thanks, I've added that suggestion to the bug report I created :D

When/if I have time, I'll try and fix some of these.

Hi, I found another reference "wxHeaderCtrl"
http://docs.wxwidgets.org/trunk/classwx_header_ctrl.html

Quote
# EVT_HEADER_SEPARATOR_DCLICK(id, func):
Separator to the right of the specified column was double clicked (this action is commonly used to resize the column to fit its contents width and the control provides UpdateColumnWidthToFit() method to make implementing this easier).

It seems the header ctrl was part of wxListCtrl :D



Edit
Here is the discussion in our forum

http://forums.codeblocks.org/index.php/topic,8090.0.html
« Last Edit: June 29, 2009, 01:54:16 pm by ollydbg »
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.

Offline Kazade

  • Multiple posting newcomer
  • *
  • Posts: 73
Re: Papercuts :)
« Reply #6 on: June 29, 2009, 06:09:23 pm »
It's interesting that it's been commented out. Does anyone know why?

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 5915
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Re: Papercuts :)
« Reply #7 on: June 29, 2009, 06:19:34 pm »
It's interesting that it's been commented out. Does anyone know why?
My explanation is that if every GCC Error or Warning would cause this function calling , it will slow down it's performance.

MY suggestion is: It will just be called in the *Last* log line output.

Edit:

I'm not sure you can debug codeblocks in Linux, Is it an issue in wxWidgets or codeblocks?

Edit2

Can you try a list control example in Linux?
http://docs.wxwidgets.org/trunk/page_samples.html#page_samples_listctrl


« Last Edit: June 29, 2009, 06:31:03 pm by ollydbg »
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.

Offline Kazade

  • Multiple posting newcomer
  • *
  • Posts: 73
Re: Papercuts :)
« Reply #8 on: June 30, 2009, 10:59:30 am »
OK, I ran the example, and double clicking the separator does nothing. The log output just says:

09:55:15: OnColBeginDrag: column 1 (width = 0 or 37).
09:55:15: OnColDragging: column 1 (width = 0 or 37).
09:55:15: OnColEndDrag: column 1 (width = 0 or 37).

So I guess it's a wxWidgets thing. I think that after compilation completes (and anywhere else that outputs to the log in a batch), setColumnWidth(2, wxLIST_AUTOSIZE) should be called once to resize everything.

Does anyone else know of any other little bugs/annoyances? I thought if we get say 10-15 of them I'd try and get them all fixed.
« Last Edit: June 30, 2009, 11:22:23 am by Kazade »

Offline oBFusCATed

  • Developer
  • Lives here!
  • *****
  • Posts: 13413
    • Travis build status
Re: Papercuts :)
« Reply #9 on: June 30, 2009, 01:42:12 pm »
Delete key does not work in the project tree and in the watch window (I should fix them, but the laziness wins every time I think of doing it :( )
(most of the time I ignore long posts)
[strangers don't send me private messages, I'll ignore them; post a topic in the forum, but first read the rules!]

Offline Kazade

  • Multiple posting newcomer
  • *
  • Posts: 73
Re: Papercuts :)
« Reply #10 on: June 30, 2009, 02:22:37 pm »
Delete key does not work in the project tree and in the watch window (I should fix them, but the laziness wins every time I think of doing it :( )

Cool, added that to the list.

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 5915
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Re: Papercuts :)
« Reply #11 on: June 30, 2009, 04:00:17 pm »
OK, I ran the example, and double clicking the separator does nothing. The log output just says:

09:55:15: OnColBeginDrag: column 1 (width = 0 or 37).
09:55:15: OnColDragging: column 1 (width = 0 or 37).
09:55:15: OnColEndDrag: column 1 (width = 0 or 37).

So I guess it's a wxWidgets thing. I think that after compilation completes (and anywhere else that outputs to the log in a batch), setColumnWidth(2, wxLIST_AUTOSIZE) should be called once to resize everything.

Agree!
Searching the keyword "Build finished" directs me to these code below:

Code
void CompilerGCC::OnJobEnd(size_t procIndex, int exitCode)
{
//    Manager::Get()->GetMessageManager()->Log(m_PageIndex, _T("JobDone: index=%u, exitCode=%d"), procIndex, exitCode));
    m_timerIdleWakeUp.Stop();
    m_Pid[procIndex] = 0;
    m_Processes[procIndex] = 0;
    m_LastExitCode = exitCode;

    if (exitCode == 0 && !m_ProcessOutputFiles[procIndex].IsEmpty())
    {
        #if wxCHECK_VERSION(2, 9, 0)
        wxFFile f(m_ProcessOutputFiles[procIndex].wx_str(), _T("r"));
        #else
        wxFFile f(m_ProcessOutputFiles[procIndex].c_str(), _T("r"));
        #endif
        if (f.IsOpened())
        {
            size_t size = f.Length();
            f.Close();

            float displaySize;
            wxString units;
            if (size < 1024)
            {
                displaySize = (float)size;
                units = _("bytes");
            }
            else if (size < 1048576)
            {
                displaySize = (float)size / 1024.0f;
                units = _("KB");
            }
            else
            {
                displaySize = (float)size / 1048576.0f;
                units = _("MB");
            }
            wxString msg;
            #if wxCHECK_VERSION(2, 9, 0)
            msg.Printf(_("Output size is %.2f %s"), displaySize, units.wx_str());
            #else
            msg.Printf(_("Output size is %.2f %s"), displaySize, units.c_str());
            #endif
            LogMessage(msg, cltNormal);
        }
    }

    if (m_CommandQueue.GetCount() != 0 && exitCode == 0)
    {
        // continue running commands while last exit code was 0.
        DoRunQueue();
    }
    else
    {
        if (exitCode == 0)
        {
            if (IsProcessRunning())
            {
                DoRunQueue();
                return;
            }

            while (1)
            {
                BuildStateManagement();
                if (m_CommandQueue.GetCount())
                {
                    DoRunQueue();
                    return;
                }
                if (m_BuildState == bsNone && m_NextBuildState == bsNone)
                    break;
            }
        }
        m_CommandQueue.Clear();
        ResetBuildState();
        // clear any remaining jobs (e.g. in case of build errors)
        while (!m_BuildJobTargetsList.empty())
            m_BuildJobTargetsList.pop();


        // long int elapsed = wxGetElapsedTime() / 1000;
        wxLongLong localTime = wxGetLocalTimeMillis();
        wxLongLong duration = localTime - m_StartTimer;
        long int elapsed = duration.ToLong();
        elapsed /= 1000;
        int mins = elapsed / 60;
        int secs = (elapsed % 60);
        wxString msg = wxString::Format(_("Process terminated with status %d (%d minutes, %d seconds)"), exitCode, mins, secs);
        LogMessage(msg, exitCode == 0 ? cltWarning : cltError, ltAll, exitCode != 0);
        if (!m_CommandQueue.LastCommandWasRun())
        {
            wxString msg = wxString::Format(_("%d errors, %d warnings"), m_Errors.GetCount(cltError), m_Errors.GetCount(cltWarning));
            LogMessage(msg, exitCode == 0 ? cltWarning : cltError, ltAll, exitCode != 0);
            #if wxCHECK_VERSION(2, 9, 0)
            LogWarningOrError(cltNormal, 0, wxEmptyString, wxEmptyString, wxString::Format(_("=== Build finished: %s ==="), msg.wx_str()));
            #else
            LogWarningOrError(cltNormal, 0, wxEmptyString, wxEmptyString, wxString::Format(_("=== Build finished: %s ==="), msg.c_str()));
            #endif
            SaveBuildLog();
        }
        else
        {
            // last command was "Run"
            // force exit code to zero (0) or else debugger will think build failed if last run returned non-zero...
// TODO (mandrav##): Maybe create and use GetLastRunExitCode()? Is it needed?
            m_LastExitCode = 0;
        }
        Manager::Get()->GetLogManager()->Log(_T(" "), m_PageIndex); // blank line

        NotifyJobDone();

        if (!Manager::IsBatchBuild() && m_Errors.GetCount(cltError))
        {
            if (Manager::Get()->GetConfigManager(_T("message_manager"))->ReadBool(_T("/auto_show_build_errors"), true))
            {
                CodeBlocksLogEvent evtShow(cbEVT_SHOW_LOG_MANAGER);
                Manager::Get()->ProcessEvent(evtShow);
            }
            CodeBlocksLogEvent evtSwitch(cbEVT_SWITCH_TO_LOG_WINDOW, m_pListLog);
            Manager::Get()->ProcessEvent(evtSwitch);

            m_pListLog->FocusError(m_Errors.GetFirstError());
            // Build is not completed, so clear the progress bar
            if (m_Log->progress)
                m_Log->progress->SetValue(0);
        }
        else
        {
            if (m_RunAfterCompile)
            {
                m_RunAfterCompile = false;
                if (Run() == 0)
                    DoRunQueue();
            }
            else if (!Manager::IsBatchBuild())
            {
                // don't close the message manager (if auto-hiding), if warnings are required to keep it open
                if (m_Errors.GetCount(cltWarning) &&
                    Manager::Get()->GetConfigManager(_T("message_manager"))->ReadBool(_T("/auto_show_build_warnings"), true))
                {
                    CodeBlocksLogEvent evtShow(cbEVT_SHOW_LOG_MANAGER);
                    Manager::Get()->ProcessEvent(evtShow);

                    CodeBlocksLogEvent evtSwitch(cbEVT_SWITCH_TO_LOG_WINDOW, m_pListLog);
                    Manager::Get()->ProcessEvent(evtSwitch);
                }
                else // if message manager is auto-hiding, unlock it (i.e. close it)
                {
                    CodeBlocksLogEvent evtShow(cbEVT_HIDE_LOG_MANAGER);
                    Manager::Get()->ProcessEvent(evtShow);
                }
            }
        }

        m_RunAfterCompile = false;

        // no matter what happened with the build, return the focus to the active editor
        cbEditor* ed = Manager::Get()->GetEditorManager()->GetBuiltinEditor(Manager::Get()->GetEditorManager()->GetActiveEditor());
        if (ed)
            ed->GetControl()->SetFocus();
    }
}

So, this is the best time to call auto_size column. :D



Here, another bug:
I can't use "thread search" in "compilergcc.cpp", a message box shows this file can't be opened. When I translate the encoding  from "UTF8 without BOM" to "ANSI" (using NotePad++), then thread search can work now. but this time, Gcc( mingw) will complain "legal character near line 3483

Code
        wxString Quoted = message;
        Quoted.Replace(_T("‘"), _T("\""), true);
        Quoted.Replace(_T("’"), _T("\""), true);
        m_BuildLogContents << Quoted;


Can anyone reproduce this problem?  :D


By the way, is this a filed bug in wxWidgets?

http://trac.wxwidgets.org/ticket/9925

(at least, this bug is not happened in Windows )
« Last Edit: June 30, 2009, 04:08:16 pm by ollydbg »
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.

Offline Kazade

  • Multiple posting newcomer
  • *
  • Posts: 73
Re: Papercuts :)
« Reply #12 on: June 30, 2009, 05:36:43 pm »
Cool OK, we have 9 bugs/issues now. 1 more then I'll call it a day and begin working through them. If anyone else can fix them, or has the time to report them as bugs on Berlios then feel free.

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 5915
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Re: Papercuts :)
« Reply #13 on: July 01, 2009, 12:27:38 pm »
Hi, I have reported this bug on the wxWidgets maillist, and here is an answer from a developer.

Quote
Yes, the generic wxListCtrl version simply doesn't implement this (see
wxListHeaderWindow::OnMouse()). It shouldn't be difficult to add but
personally I'd prefer to replace wxListHeaderWindow with wxHeaderCtrl if we
modify this code at all as it has other advantages.

 Regards,
VZ
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.

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 5915
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Re: Papercuts :)
« Reply #14 on: July 01, 2009, 12:56:19 pm »
Hi, all:

I have fix this problem, see this patch. At least this patch works fin in Windows, Can someone explain under Linux? Thanks!
And any comments?

Code
Index: compilergcc.cpp
===================================================================
--- compilergcc.cpp (revision 5679)
+++ compilergcc.cpp (working copy)
@@ -3715,6 +3715,7 @@
             #else
             LogWarningOrError(cltNormal, 0, wxEmptyString, wxEmptyString, wxString::Format(_("=== Build finished: %s ==="), msg.c_str()));
             #endif
+            m_pListLog->GetListControl()->SetColumnWidth(2, wxLIST_AUTOSIZE);
             SaveBuildLog();
         }
         else
Index: compilermessages.h
===================================================================
--- compilermessages.h (revision 5679)
+++ compilermessages.h (working copy)
@@ -21,6 +21,7 @@
         virtual void FocusError(int nr);
 
         virtual wxWindow* CreateControl(wxWindow* parent);
+        wxListCtrl* GetListControl(){ return control ; }
     private:
         void OnClick(wxCommandEvent& event);
         void OnDoubleClick(wxCommandEvent& event);
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.