/*
* This file is part of Code::Blocks Studio, an open-source cross-platform IDE
* Copyright (C) 2003 Yiannis An. Mandravellos
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Contact e-mail: Yiannis An. Mandravellos <mandrav@codeblocks.org>
* Program URL : http://www.codeblocks.org
*
* $Revision$
* $Id$
* $HeadURL$
*/
#include "sdk_precomp.h"
#ifndef CB_PRECOMP
#include "cbproject.h"
#include <wx/xrc/xmlres.h>
#include <wx/intl.h>
#include <wx/checkbox.h>
#include <wx/textctrl.h>
#include <wx/button.h>
#include <wx/filename.h>
#include <wx/file.h>
#include <wx/checklst.h>
#endif
#include "projectfileoptionsdlg.h"
#include <wx/slider.h>
#include <wx/textfile.h>
BEGIN_EVENT_TABLE(ProjectFileOptionsDlg, wxDialog)
EVT_UPDATE_UI(-1, ProjectFileOptionsDlg::OnUpdateUI)
EVT_BUTTON(XRCID("btnOK"), ProjectFileOptionsDlg::OnOKClick)
END_EVENT_TABLE()
// some help functions and type (copied and adapted from the codestat plug-in)
struct LanguageDef
{
wxArrayString ext;
wxString single_line_comment;
wxString multiple_line_comment[2];
};
void AnalyseLine(const LanguageDef &language, wxString line, bool &comment, bool &code, bool &multi_line_comment)
{
int first_single_line_comment, first_multi_line_comment_begin, first_multi_line_comment_end;
// Delete first and trailing spaces
line = line.Trim(true);
line = line.Trim(false);
if (line.IsEmpty())
return;
// Searching for single and multi-lines comment signs
if (language.single_line_comment.Length() > 0)
first_single_line_comment = line.Find(language.single_line_comment);
else first_single_line_comment = -1;
if (language.multiple_line_comment[0].Length() > 0)
first_multi_line_comment_begin = line.Find(language.multiple_line_comment[0]);
else first_multi_line_comment_begin = -1;
if (language.multiple_line_comment[1].Length() > 0)
first_multi_line_comment_end = line.Find(language.multiple_line_comment[1]);
else first_multi_line_comment_end = -1;
// We are in a multiple line comment => finding the "end of multiple line comment" sign
if (multi_line_comment)
{
comment = true;
if (first_multi_line_comment_end > -1)
{
multi_line_comment = false;
if (first_multi_line_comment_end+language.multiple_line_comment[1].Length() < line.Length())
AnalyseLine(language, line.Mid(first_multi_line_comment_end+language.multiple_line_comment[1].Length()), comment, code, multi_line_comment);
}
}
// We are not in a multiple line comment
else if (!multi_line_comment)
{
// First comment sign found is a single line comment sign
if ( (first_single_line_comment>-1)
&&((first_multi_line_comment_begin==-1)||((first_multi_line_comment_begin>-1)&&(first_single_line_comment<first_multi_line_comment_begin))) )
{
comment = true;
if (first_single_line_comment > 0)
code = true;
}
// First comment sign found is a multi-line comment begin sign
else if (first_multi_line_comment_begin>-1)
{
multi_line_comment = true;
comment = true;
if (first_multi_line_comment_begin > 0)
code = true;
if (first_multi_line_comment_begin+language.multiple_line_comment[0].Length() < line.Length())
AnalyseLine(language, line.Mid(first_multi_line_comment_begin+language.multiple_line_comment[0].Length()), comment, code, multi_line_comment);
}
else
{
code = true;
}
}
}
void CountLines(wxFileName filename, const LanguageDef &language,
long int &code_lines, long int &codecomments_lines,
long int &comment_lines, long int &empty_lines, long int &total_lines)
{
wxTextFile file;
if (file.Open(filename.GetFullPath()))
{
bool multi_line_comment = false;
total_lines += file.GetLineCount();
for (unsigned int i = 0; i < file.GetLineCount(); ++i)
{
wxString line = file[i];
line = line.Trim(true);
line = line.Trim(false);
bool comment = false;
bool code = false;
if (line.IsEmpty())
{
++empty_lines;
}
else
{
AnalyseLine(language, line, comment, code, multi_line_comment);
if (comment&&code) ++codecomments_lines;
else if (comment) ++comment_lines;
else if (code) ++code_lines;
}
} // end for : idx : i
}
}
ProjectFileOptionsDlg::ProjectFileOptionsDlg(wxWindow* parent, ProjectFile* pf)
: m_ProjectFile(pf)
{
wxXmlResource::Get()->LoadDialog(this, parent, _T("dlgProjectFileOptionsWRK"));
if (pf)
{
cbProject* prj = pf->GetParentProject();
wxCheckListBox *list = XRCCTRL(*this, "lstTargets", wxCheckListBox);
for (int i = 0; i < prj->GetBuildTargetsCount(); ++i)
{
wxString targetName = prj->GetBuildTarget(i)->GetTitle();
list->Append(targetName);
if (pf->buildTargets.Index(targetName) != -1)
list->Check(i, true);
}
// count some statistics of the file (only c/c++ files for the moment)
LanguageDef langCPP;
langCPP.ext.Add(_T("c"));
langCPP.ext.Add(_T("cpp"));
langCPP.ext.Add(_T("h"));
langCPP.ext.Add(_T("hpp"));
langCPP.single_line_comment = _T("//");
langCPP.multiple_line_comment[0] = _T("/*");
langCPP.multiple_line_comment[1] = _T("*/");
wxFileName filename = pf->file;
if (filename.FileExists())
{
bool bExtOk = false;
for (int j = 0; j < (int) langCPP.ext.Count(); ++j)
{
if (filename.GetExt() == langCPP.ext[j])
{
bExtOk = true;
break;
}
}
if(bExtOk)
{
long int total_lines = 0;
long int code_lines = 0;
long int empty_lines = 0;
long int comment_lines = 0;
long int codecomments_lines = 0;
CountLines(filename, langCPP, code_lines, codecomments_lines, comment_lines, empty_lines, total_lines);
XRCCTRL(*this, "staticTotalLines", wxStaticText)->SetLabel(wxString::Format(_("%ld"), total_lines));
XRCCTRL(*this, "staticEmptyLines", wxStaticText)->SetLabel(wxString::Format(_("%ld"), empty_lines));
XRCCTRL(*this, "staticActualLines", wxStaticText)->SetLabel(wxString::Format(_("%ld"), code_lines + codecomments_lines));
XRCCTRL(*this, "staticCommentLines", wxStaticText)->SetLabel(wxString::Format(_("%ld"), comment_lines));
}
wxFile file(filename.GetFullPath());
if(file.IsOpened())
{
long Length = static_cast<long>(file.Length());
XRCCTRL(*this, "staticFileSize", wxStaticText)->SetLabel(wxString::Format(_("%ld"), Length));
file.Close();
}
wxDateTime ModTime = filename.GetModificationTime();
XRCCTRL(*this, "staticDateTimeStamp", wxStaticText)->SetLabel(
wxString::Format(_("%ld/%ld/%ld %ld:%ld:%ld"), ModTime.GetDay(),
ModTime.GetMonth() + 1, ModTime.GetYear(), ModTime.GetHour(), // seems I have to add 1 for the month ?
ModTime.GetMinute(), ModTime.GetSecond()));
}
XRCCTRL(*this, "txtCompiler", wxTextCtrl)->SetValue(pf->compilerVar);
XRCCTRL(*this, "chkCompile", wxCheckBox)->SetValue(pf->compile);
XRCCTRL(*this, "chkLink", wxCheckBox)->SetValue(pf->link);
XRCCTRL(*this, "sliderWeight", wxSlider)->SetValue(pf->weight);
XRCCTRL(*this, "txtObjName", wxTextCtrl)->SetValue(pf->GetObjName());
XRCCTRL(*this, "chkBuildStage", wxCheckBox)->SetValue(pf->useCustomBuildCommand);
XRCCTRL(*this, "txtBuildStage", wxTextCtrl)->SetValue(pf->buildCommand);
XRCCTRL(*this, "txtProject", wxTextCtrl)->SetValue(prj?(prj->GetTitle() + _T("\n") + prj->GetFilename()):_T("-"));
XRCCTRL(*this, "txtAbsName", wxTextCtrl)->SetValue(pf->file.GetFullPath());
XRCCTRL(*this, "txtRelName", wxTextCtrl)->SetValue(pf->GetBaseName());
SetTitle(_("Options for ") + wxString(_("\"")) + pf->relativeFilename + wxString(_("\"")));
}
XRCCTRL(*this, "txtObjName", wxTextCtrl)->Enable(false);
// included files not implemented yet -> hide it
XRCCTRL(*this, "staticIncludedFilesLabel", wxTextCtrl)->Hide();
XRCCTRL(*this, "staticIncludedFiles", wxTextCtrl)->Hide();
} // end of constructor
ProjectFileOptionsDlg::~ProjectFileOptionsDlg()
{
}
void ProjectFileOptionsDlg::OnUpdateUI(wxUpdateUIEvent& event)
{
if (m_ProjectFile)
{
bool en = XRCCTRL(*this, "chkBuildStage", wxCheckBox)->GetValue();
XRCCTRL(*this, "txtBuildStage", wxTextCtrl)->Enable(en);
}
else
{
XRCCTRL(*this, "txtCompiler", wxTextCtrl)->Enable(false);
XRCCTRL(*this, "lstTargets", wxCheckListBox)->Enable(false);
XRCCTRL(*this, "chkCompile", wxCheckBox)->Enable(false);
XRCCTRL(*this, "chkLink", wxCheckBox)->Enable(false);
XRCCTRL(*this, "txtObjName", wxTextCtrl)->Enable(false);;
XRCCTRL(*this, "chkBuildStage", wxCheckBox)->Enable(false);
XRCCTRL(*this, "txtBuildStage", wxTextCtrl)->Enable(false);
}
}
void ProjectFileOptionsDlg::OnOKClick(wxCommandEvent& event)
{
m_ProjectFile->buildTargets.Clear();
wxCheckListBox *list = XRCCTRL(*this, "lstTargets", wxCheckListBox);
for (int i = 0; i < list->GetCount(); i++)
{
if (list->IsChecked(i))
m_ProjectFile->AddBuildTarget(list->GetString(i));
}
m_ProjectFile->compile = XRCCTRL(*this, "chkCompile", wxCheckBox)->GetValue();
m_ProjectFile->link = XRCCTRL(*this, "chkLink", wxCheckBox)->GetValue();
m_ProjectFile->weight = XRCCTRL(*this, "sliderWeight", wxSlider)->GetValue();
// m_ProjectFile->SetObjName(XRCCTRL(*this, "txtObjName", wxTextCtrl)->GetValue());
m_ProjectFile->useCustomBuildCommand = XRCCTRL(*this, "chkBuildStage", wxCheckBox)->GetValue();
m_ProjectFile->buildCommand = XRCCTRL(*this, "txtBuildStage", wxTextCtrl)->GetValue();
m_ProjectFile->compilerVar = XRCCTRL(*this, "txtCompiler", wxTextCtrl)->GetValue();
// make sure we have a compiler var, if the file is to be compiled
if (m_ProjectFile->compile && m_ProjectFile->compilerVar.IsEmpty())
m_ProjectFile->compilerVar = _T("CPP");
cbProject* prj = m_ProjectFile->GetParentProject();
prj->SetModified(true);
EndModal(wxID_OK);
}