diff --git a/CMakeModules/FindBazaar.cmake b/CMakeModules/FindBazaar.cmake index 673cf2b7e4..0e6ee823d5 100644 --- a/CMakeModules/FindBazaar.cmake +++ b/CMakeModules/FindBazaar.cmake @@ -54,15 +54,15 @@ if( Bazaar_EXECUTABLE ) # Fetch the Bazaar executable version. execute_process( COMMAND ${Bazaar_EXECUTABLE} --version - OUTPUT_VARIABLE bzr_version_output + OUTPUT_VARIABLE _bzr_version_output ERROR_VARIABLE _bzr_version_error RESULT_VARIABLE _bzr_version_result OUTPUT_STRIP_TRAILING_WHITESPACE ) if( ${_bzr_version_result} EQUAL 0 ) set( Bazaar_FOUND TRUE ) - string( REGEX REPLACE "^(.*\n)? \(bzr\) ([^\n]+).*" - "\\2" Bazaar_VERSION "${_bzr_version_output}" ) + string( REGEX REPLACE "^[\n]*Bazaar \\(bzr\\) ([0-9.a-z]+).*" + "\\1" Bazaar_VERSION "${_bzr_version_output}" ) message( STATUS "Bazaar version control system version ${Bazaar_VERSION} found." ) endif( ${_bzr_version_result} EQUAL 0 ) diff --git a/Documentation/development/Doxyfile b/Documentation/development/Doxyfile index 2033592411..720c510628 100644 --- a/Documentation/development/Doxyfile +++ b/Documentation/development/Doxyfile @@ -646,7 +646,8 @@ WARN_LOGFILE = # directories like "/usr/src/myproject". Separate the files or directories # with spaces. -INPUT = stable-release-policy.md \ +INPUT = coding-style-policy.md \ + stable-release-policy.md \ road-map.md # This tag can be used to specify the character encoding of the source files diff --git a/Documentation/development/coding-style-policy.md b/Documentation/development/coding-style-policy.md new file mode 100644 index 0000000000..2a54dc1d58 --- /dev/null +++ b/Documentation/development/coding-style-policy.md @@ -0,0 +1,800 @@ +# KiCad C++ Source Code Style Guide # + +Latest Publishing: February 2013 + +First Published: September 2010 + +written by + +Wayne Stambaugh \<\> +and +Dick Hollenbeck \<\> + +[TOC] + +# 1. Introduction # {#intro} +The purpose of this document is to provide a reference guide for KiCad +developers about how source code should be styled and formatted in +KiCad. It is not a comprehensive programming guide because it does not +discuss many things such as software engineering strategies, source +directories, existing classes, or how to internationalize text. The goal +is to make all of the KiCad source conform to this guide. + +## 1.1 Why Coding Style Matters ## {#why} +You may be thinking to yourself that using the style defined in this +document will not make you a good programmer and you would be correct. +Any given coding style is no substitute for experience. However, any +experienced coder will tell that the only thing worse than looking at +code that is not in your preferred coding style, is looking at twenty +different coding styles that are not your preferred coding style. +Consistency makes a) problems easier to spot, and b) looking at code for +long periods of time more tolerable. + +## 1.2 Enforcement ## {#enforcement} +The KiCad coding police are not going to break down your door and beat +you with your keyboard if you don't follow these guidelines (although +there are those who would argue that they should). However, there are +some very sound reasons why you should follow them. If you are +contributing patches, you are much more likely to be taken seriously by +the primary developers if your patches are formatted correctly. Busy +developers don't have the time to go back and reformat your code. If you +have a desire to become a regular KiCad developer with commit access to +the development branch, you're not likely to get a glowing +recommendation by the lead developers if you will not follow these +guidelines. It is just good programming courtesy to follow this policy +because it is respectful of the investment already made by the existing +developers. The other KiCad developers will appreciate your effort. + +**Warning** + +**Do not modify this document without the consent of the project +leader. All changes to this document require approval.** + + +# 2. Naming Conventions # {#naming_conventions} +Before delving into anything as esoteric as indentation and formatting, +naming conventions need to be addressed. This section does not attempt +to define what names you use for your code. Rather, it defines the style +for naming. See the references section for links to some excellent +coding references. When defining multiple word names use the following +conventions for improved readability: + +- Use underscores for all upper and all lower case variables to make + multiple word names more readable. +- Use camel case for mixed case variable names. + +Avoid mixing camel case and underscores. + +**Examples** +~~~~~~~~~~~~~{.cpp} + CamelCaseName // if camelcase, then no underscores + all_lower_case_name + ALL_UPPER_CASE_NAME +~~~~~~~~~~~~~ + +## 2.1 Class, Type Definitions, Name Space, and Macro Names ## {#definitions} +Class, typedef, enum, name space, and macro names should be comprised of +all capital letters. + +**Examples** +~~~~~~~~~~~~~{.cpp} + class SIMPLE + #define LONG_MACRO_WITH_UNDERSCORES + typedef boost::ptr_vector PIN_LIST; + enum KICAD_T {...}; +~~~~~~~~~~~~~ + +## 2.2 Local, Private and Automatic Variables ## {#local_variables} +The first character of automatic, static local, and private variable +names should be lower case. This indicates that the variable will not be +“visible” outside of the function, file, or class where they are +defined, respectively. The limited visibility is being acknowledged with +the lowercase starting letter, where lowercase is considered to be less +boisterous than uppercase. + +**Examples** +~~~~~~~~~~~~~{.cpp} + int i; + double aPrivateVariable; + static char* static_variable = NULL; +~~~~~~~~~~~~~ + +## 2.3 Public and Global Variables ## {#global_variables} +The first character of public and global variable names are to be +uppercase. This indicates that the variable is visible outside the class +or file in which it was defined. (An exception is the use of prefix `g_` +which is also sometimes used to indicate a global variable.) + +**Example** +~~~~~~~~~~~~~{.cpp} + char* GlobalVariable; +~~~~~~~~~~~~~ + +## 2.4 Local, Private and Static Functions ## {#functions} +The first character of local, private, and static functions should be +lower case. This indicates that the function is not visible outside the +class or file where it is defined. + +**Example** +~~~~~~~~~~~~~{.cpp} + bool isModified(); + static int buildList( int* list ); +~~~~~~~~~~~~~ + +## 2.5 Function Arguments ## {#function_arguments} +Function arguments are prefixed with an 'a' to indicate these are +arguments to a function. The 'a' stands for “argument”, and it also +enables clever and concise Doxygen comments. + +**Example** +~~~~~~~~~~~~~{.cpp} + /*/** */* + * Function SetFoo + * takes aFoo and copies it into this instance. + */ + void SetFoo( int aFoo ); +~~~~~~~~~~~~~ + +Notice how the reader can say “a Foo” to himself when reading this. + +## 2.6 Pointers ## {#pointers} +It is not desired to identify a pointer by building a 'p' into the +variable name. The pointer aspect of the variable pertains to type, not +purpose. + +**Example** +~~~~~~~~~~~~~{.cpp} + MODULE* module; +~~~~~~~~~~~~~ + +The purpose of the variable is that it represents a MODULE. Something +like `p_module` would only make that harder to discern. + +## 2.7 Accessing Member Variables and Member Functions ## {#accessing_members} +We do not use “`this->`” to access either member variables or member +functions from within the containing class. We let C++ perform this for +us. + + +# 3. Commenting # {#commenting} +Comments in KiCad typically fall into two categories: in line code +comments and Doxygen comments. In line comments have no set formatting +rules other than they should have the same indent level as the code if +they do not follow a statement. In line comments that follow statements +should not exceed 99 columns unless absolutely necessary. The prevents +word wrapping in an editor when the viewable columns is set to 100. In +line comments can use either the C++ or the C commenting style, but C++ +comments are preferred for single line comments or comments consisting +of only a few lines. + +## 3.1 Blank Lines Above Comments ## {#blank_lines_above_comments} +If a comment is the first thing on a line, then that comment should have +one or more blank lines above them. One blank line is preferred. + +## 3.2 Doxygen ## {#doxygen} +Doxygen is a C++ source code documenting tool used by the project. Descriptive +*.html files can be generated from the source code by installing Doxygen and +building the target named **doxygen-docs**. + + $ cd + $ make doxygen-docs + +The \*.html files will be placed into +\/Documentation/doxygen/html/ + +Doxygen comments are used to build developer documentation from the +source code. They should normally be only placed in header files and not +in \*.cpp files. This eliminates the obligation to keep two comments in +agreement with each other. is if the class, function, or enum, etc. is +only defined in a \*.cpp source file and not present in any header file, +in which case the Doxygen comments should go into the \*.cpp source file. +Again, avoid duplicating the Doxygen comments in both the header and +\*.cpp source files. + +KiCad uses the JAVADOC comment style defined in the [“Documenting the +code”][doccode] section of the Doxygen [manual][manual]. Don't forget +to use the special Doxygen tags: bug, todo, deprecated, etc., so other +developers can quickly get useful information about your code. It is +good practice to actually generate the Doxygen \*.html files by +building target doxygen-docs, and then to review the quality of your +Doxygen comments with a web browser before submitting a patch. + +[doccode]: http://www.stack.nl/~dimitri/doxygen/manual/docblocks.html +[manual]: http://www.stack.nl/~dimitri/doxygen/manual.html + +### 3.2.1 Function Comments ### {#function_comments} +These go into a header file, unless the function is a private (i.e. +static) function known only to a \*.cpp file. The format of a function +comment is chosen to serve a dual purpose role: delineation of the +function declaration within the source code and to create a consistent +leading sentence in the doxygen html output. The chosen format is +“Function \” as shown in the example below. + +**Example** +~~~~~~~~~~~~~{.cpp} + /*/** */* + * Function Print + * formats and writes text to the output stream. + * @param nestLevel is the multiple of spaces to precede the output with. + * @param fmt is a printf() style format string. + * @param ... is a variable list of parameters that will get blended into + * the output under control of the format string. + * @return int - the number of characters output. + * @throw IO_ERROR, if there is a problem outputting, such asisk. + */ + int PRINTF_FUNC Print( int nestLevel, + const char* fmt, ... ) throw( IO_ERROR ); +~~~~~~~~~~~~~ + +The “Function \” text goes on the 2nd line of the comment. The +\@return keyword if present, should show the type of the return value +followed by a hiphen. The \@param keyword names a function parameter +and the text following should flow like a normal English sentence. + +### 3.2.2 Class Comments ### {#class_comments} +A class comment describes a class declaration by giving the purpose and +use of the class. Its format is similar to a function comment. Doxygen +can use the html \ (paragraph designation) to begin a new paragraph +in its output. So if the text of the comment is large, break it put into +multiple paragraphs. + +**Example** +~~~~~~~~~~~~~{.cpp} + /*/** */* + * Class OUTPUTFORMATTER + * is an important interface (abstract) class used to output UTF8 text in + * a convenient way. The primary interface is "printf() - like" but + * with support for indentation control. The destination of the 8 bit + * wide text is up to the implementer. + *

+ * The implementer only has to implement the write() function, but can + * also optionally re-implement GetQuoteChar(). + *

+ * If you want to output a wxString, then use CONV_TO_UTF8() on it + * before passing it as an argument to Print(). + *

+ * Since this is an abstract interface, only classes derived from + * this one may actually be used. + */ + class OUTPUTFORMATTER + { +~~~~~~~~~~~~~ + + +# 4. Formatting # {#formatting} +This section defines the formatting style used in the KiCad source. + +## 4.1 Indentation ## {#indentation} +The indentation level for the KiCad source code is defined as four +spaces. Please do not use tabs. + +### 4.1.1 Defines ### {#defines} +There should be only one space after a \#define statement. + +### 4.1.2 Column Alignment ### {#column_alignment} +Please try to align multiple consecutive similar lines into consistent +columns when possible, such as \#define lines which can be thought of as +containing 4 columns: \#define, symbol, value, and comment. Notice how +all 4 columns are aligned in the example below. + +**Example** +~~~~~~~~~~~~~{.cpp} + #define LN_RED 12 // my favorite + #define LN_GREEN 13 // eco friendly +~~~~~~~~~~~~~ + +Another common case is the declaration of automatic variables. These are +preferably shown in columns of type and variable name. + +## 4.2 Blank Lines ## {#blank_lines} + +### 4.2.1 Function Declarations ### {#function_declarations} +There should be 1 blank line above a function declaration in a class +file if that function declaration is presented with a Javadoc comment. +This is consist with the statement above about blank lines above +comments. + +### 4.2.2 Function Definitions ### {#function_definitions} +Function definitions in *.cpp files will not typically be accompanied by +any comment, since those are normally only in the header file. It is +desirable to set off the function definition within the *.cpp file by +leaving two blank lines above the function definition. + +### 4.2.3 If Statements ### {#if_statements} +There should be one blank line above if statements. + +## 4.3 Line Length ### {#line_length} +The maximum line width is 99 columns. An exception to this is a long +quoted string such as the internationalized text required to satisfy +MSVC++, described below. + +## 4.4 Strings ## {#strings} +The KiCad project team no longer supports compiling with Microsoft +Visual C++. When you need to break long strings into smaller substrings, +please use the C99 compliant method for improved readability. Using +any of previously accepted methods defined below for breaking +long internationalized strings will no longer be accepted. + +**Examples** +~~~~~~~~~~~~~{.cpp} + // This works with C99 compliant compilers is the **only** accepted method: + wxChar* foo = _( “this is a long string broken ” + “into pieces for readability.” ); + + // This works with MSVC, breaks POEdit, and is **not** acceptable: + wxChar* foo = _( “this is a long string broken ” + L“into pieces for readability” ); + + // This works with MSVC, is ugly, and is **not** accepted: + wxChar* foo = _( “this is a long string \ + broken into pieces for readability” ); +~~~~~~~~~~~~~ + +A second acceptable solution is to simply put the text all on one +line, even if it exceeds the 99 character line length limit. However, +the preferred method is to break strings within the 99 character limit +whenever possible to prevent wrapping. + +## 4.5 Trailing Whitespace ## {#trailing_whitespace} +Many programming editors conveniently indent your code for you. Some of +them do it rather poorly and leave trailing whitespace. Thankfully, most +editors come with a remove trailing whitespace macro or at least a +setting to make trailing whitespace visible so you can see it and +manually remove it. Trailing whitespace is known to break some text +parsing tools. It also leads to unnecessary diffs in the version control +system. Please remove trailing whitespace. + +## 4.6 Multiple Statements per Line ## {#multiple_statements_per_line} +It is generally preferred that each statement be placed on its own line. +This is especially true for statements without keywords. + +**Example** +~~~~~~~~~~~~~{.cpp} + x=1; y=2; z=3; // Bad, should be on separate lines. +~~~~~~~~~~~~~ + +## 4.7 Braces ## {#braces} +Braces should be placed on the line proceeding the keyword and indented +to the same level. It is not necessary to use braces if there is only a +single line statement after the keyword. In the case of if..else +if..else, indent all to the same level. + +**Example** +~~~~~~~~~~~~~{.cpp} + void function() + { + if( foo ) + { + statement1; + statement2; + } + else if( bar ) + { + statement3; + statement4; + } + else + statement5; + } +~~~~~~~~~~~~~ + +## 4.8 Parenthesis ## {#parenthesis} +Parenthesis should be placed immediately after function names and +keywords. Spaces should be placed after the opening parenthesis, before +the closing parenthesis, and between the comma and the next argument in +functions. No space is needed if a function has no arguments. + +**Example** +~~~~~~~~~~~~~{.cpp} + void Function( int aArg1, int aArg2 ) + { + while( busy ) + { + if( a || b || c ) + doSomething(); + else + doSomethingElse(); + } + } +~~~~~~~~~~~~~ + +## 4.9 Switch Formatting ## {#switch} +The case statement is to be indented to the same level as the switch. + +**Example** +~~~~~~~~~~~~~{.cpp} + switch( foo ) + { + case 1: + doOne(); + break; + case 2: + doTwo(); + // Fall through. + default: + doDefault(); + } +~~~~~~~~~~~~~ + + +# 5. License Statement # {#license_statement} +There is a the file copyright.h which you can copy into the top of +your new source files and edit the \ field. KiCad depends on +the copyright enforcement capabilities of copyright law, and this +means that source files must be copyrighted and not be released into +the public domain. Each source file has one or more owners. + + +# 6. Header Files # {#header_files} +Project \*.h source files should: + +- contain a license statement +- contain a nested include \#ifndef +- be fully self standing and not depend on other headers that are not + included within it. + +The license statement was described above. + +## 6.1 Nested Include #ifndef ## {#nested_include} +Each header file should include an \#ifndef which is commonly used to +prevent compiler errors in the case where the header file is seen +multiple times in the code stream presented to the compiler. Just +after the license statement, at the top of the file there should be +lines similar to these (but with a filename specific token other than +`RICHIO_H_`): + +~~~~~~~~~~~~~{.cpp} + #ifndef RICHIO_H_ + #define RICHIO_H_ +~~~~~~~~~~~~~ + +And at the very bottom of the header file, use a line like this one: + +~~~~~~~~~~~~~{.cpp} + #endif // RICHIO_H_ +~~~~~~~~~~~~~ + +The \#ifndef wrapper begins after the license statement, and ends at +the very bottom of the file. It is important that it wrap any nested +\#include statements, so that the compiler can skip them if the +\#ifndef evaluates to false, which will reduce compilation time. + +## 6.2 Headers Without Unsatisfied Dependencies ## {#header_depends} +Any header file should include other headers that it depends on. (Note: +KiCad is not at this point now, but this section is a goal of the +project.) + +It should be possible to run the compiler on any header file within the +project, and with proper include paths being passed to the compiler, the +header file should compile without error. + +**Example** + + $ cd /svn/kicad/testing.checkout/include + $ g++ wx-config --cxxflags -I . xnode.h -o /tmp/junk + +Such structuring of the header files removes the need within a client +\*.cpp file to include some project header file before some other project +header file. (A client \*.cpp file is one that intends to **use, not +implement,** the public API exposed within the header file.) + +Client code should not have to piece together things that a header file +wishes to expose. The exposing header file should be viewed as a fully +sufficient **ticket to use** the public API of that header file. + +This is not saying anything about how much to expose, only that that +which is exposed needs to be fully usable merely by including the header +file that exposes it, with no additional includes. + +For situations where there is a class header file and an +implementation \*.cpp file, it is desirable to hide as much of the +private implementation as is practical and any header file that is not +needed as part of the public API can and should be included only in +the implementation \*.cpp file. However, the number one concern of +this section is that client (using) code can use the public API which +is exposed in the header file, merely by including that one header +file. + + +# 7. I Wrote X Lines of Code Before I Read This Document # {#x_lines} +It's OK. We all make mistakes. Fortunately, KiCad provides a +configuration file for the code beautifier uncrustify. Uncrustify won't +fix your naming problems but it does a pretty decent job of formatting +your source code. There are a few places where uncrustify makes some +less than ideal indentation choices. It struggles with the string +declaration macros wxT(“”) and \_(“”) and functions used as arguments to +other functions. After you uncrustify your source code, please review the +indentation for any glaring errors and manually fix them. See the +uncrustify [website][uncrustify] for more information. + +[uncrustify]: http://uncrustify.sourceforge.net/ + + +# 8. Show Me an Example # {#show_me_an_example} +Nothing drives the point home like an example. The source file richio.h +below was taken directly from the KiCad source. + +~~~~~~~~~~~~~{.cpp} + /* + * This program source code file is part of KICAD, a free EDA CAD application. + * + * Copyright (C) 2007-2010 SoftPLC Corporation, Dick Hollenbeck + * Copyright (C) 2007 KiCad Developers, see change_log.txt for contributors. + * + * 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, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + + #ifndef RICHIO_H_ + #define RICHIO_H_ + + + // This file defines 3 classes useful for working with DSN text files and is named + // "richio" after its author, Richard Hollenbeck, aka Dick Hollenbeck. + + + #include + #include + + // I really did not want to be dependent on wxWidgets in richio + // but the errorText needs to be wide char so wxString rules. + #include + #include // FILE + + + + /*/** */* + * Struct IOError + * is a class used to hold an error message and may be used to throw exceptions + * containing meaningful error messages. + */ + struct IOError + { + wxString errorText; + + IOError( const wxChar* aMsg ) : + errorText( aMsg ) + { + } + + IOError( const wxString& aMsg ) : + errorText( aMsg ) + { + } + }; + + + /*/** */* + * Class LINE_READER + * reads single lines of text into its buffer and increments a line number counter. + * It throws an exception if a line is too long. + */ + class LINE_READER + { + protected: + + FILE* fp; + int lineNum; + unsigned maxLineLength; + unsigned length; + char* line; + unsigned capacity; + + public: + + /*/** */* + * Constructor LINE_READER + * takes an open FILE and the size of the desired line buffer. + * @param aFile An open file in "ascii" mode, not binary mode. + * @param aMaxLineLength The number of bytes to use in the line buffer. + */ + LINE_READER( FILE* aFile, unsigned aMaxLineLength ); + + ~LINE_READER() + { + delete[] line; + } + + /* + int CharAt( int aNdx ) + { + if( (unsigned) aNdx < capacity ) + return (char) (unsigned char) line[aNdx]; + return -1; + } + */ + + /*/** */* + * Function ReadLine + * reads a line of text into the buffer and increments the line number + * counter. If the line is larger than the buffer size, then an exception + * is thrown. + * @return int - The number of bytes read, 0 at end of file. + * @throw IOError only when a line is too long. + */ + int ReadLine() throw (IOError); + + operator char* () + { + return line; + } + + int LineNumber() + { + return lineNum; + } + + unsigned Length() + { + return length; + } + }; + + + + /*/** */* + * Class OUTPUTFORMATTER + * is an interface (abstract class) used to output ASCII text in a convenient + * way. The primary interface is printf() like but with support for indentation + * control. The destination of the 8 bit wide text is up to the implementer. + * If you want to output a wxString, then use CONV_TO_UTF8() on it before passing + * it as an argument to Print(). + *

+ * Since this is an abstract interface, only classes derived from this one + * will be the implementations. + */ + class OUTPUTFORMATTER + { + + #if defined(__GNUG__) // The GNU C++ compiler defines this + + // When used on a C++ function, we must account for the "this" pointer, + // so increase the STRING-INDEX and FIRST-TO_CHECK by one. + // See http://docs.freebsd.org/info/gcc/gcc.info.Function_Attributes.html + // Then to get format checking during the compile, compile with -Wall or -Wformat + #define PRINTF_FUNC __attribute__ ((format (printf, 3, 4))) + + #else + #define PRINTF_FUNC // nothing + #endif + + public: + + /*/** */* + * Function Print + * formats and writes text to the output stream. + * + * @param nestLevel The multiple of spaces to preceed the output with. + * @param fmt A printf() style format string. + * @param ... a variable list of parameters that will get blended into + * the output under control of the format string. + * @return int - the number of characters output. + * @throw IOError, if there is a problem outputting, such as a full disk. + */ + virtual int PRINTF_FUNC Print( int nestLevel, const char* fmt, ... ) throw( IOError ) = 0; + + /*/** */* + * Function GetQuoteChar + * performs quote character need determination. + * It returns the quote character as a single character string for a given + * input wrapee string. If the wrappee does not need to be quoted, + * the return value is "" (the null string), such as when there are no + * delimiters in the input wrapee string. If you want the quote_char + * to be assuredly not "", then pass in "(" as the wrappee. + *

+ * Implementations are free to override the default behavior, which is to + * call the static function of the same name. + + * @param wrapee A string that might need wrapping on each end. + * @return const char* - the quote_char as a single character string, or "" + * if the wrapee does not need to be wrapped. + */ + virtual const char* GetQuoteChar( const char* wrapee ) = 0; + + virtual ~OUTPUTFORMATTER() {} + + /*/** */* + * Function GetQuoteChar + * performs quote character need determination according to the Specctra DSN + * specification. + + * @param wrapee A string that might need wrapping on each end. + * @param quote_char A single character C string which provides the current + * quote character, should it be needed by the wrapee. + * + * @return const char* - the quote_char as a single character string, or "" + * if the wrapee does not need to be wrapped. + */ + static const char* GetQuoteChar( const char* wrapee, const char* quote_char ); + }; + + + /*/** */* + * Class STRINGFORMATTER + * implements OUTPUTFORMATTER to a memory buffer. After Print()ing the + * string is available through GetString() + */ + class STRINGFORMATTER : public OUTPUTFORMATTER + { + std::vector buffer; + std::string mystring; + + int sprint( const char* fmt, ... ); + int vprint( const char* fmt, va_list ap ); + + public: + + /*/** */* + * Constructor STRINGFORMATTER + * reserves space in the buffer + */ + STRINGFORMATTER( int aReserve = 300 ) : + buffer( aReserve, '\0' ) + { + } + + + /*/** */* + * Function Clear + * clears the buffer and empties the internal string. + */ + void Clear() + { + mystring.clear(); + } + + /*/** */* + * Function StripUseless + * removes whitespace, '(', and ')' from the mystring. + */ + void StripUseless(); + + + std::string GetString() + { + return mystring; + } + + + //----------------------------------------------------- + int PRINTF_FUNC Print( int nestLevel, const char* fmt, ... ) throw( IOError ); + const char* GetQuoteChar( const char* wrapee ); + //---------------------------------------------------- + }; + + + #endif // RICHIO_H_ +~~~~~~~~~~~~~ + + +# 9. Resources # {#resources} +There are plenty of excellent resources on the Internet on C++ coding +styles and coding do's and don'ts. Here are a few useful ones. In most +cases, the coding styles do not follow the KiCad coding style but there +is plenty of other good information here. Besides, most of them have +some great humor in them enjoyable to read. Who knows, you might even +learn something new. + +- [C++ Coding Standard][cppstandard] +- [Linux Kernel Coding Style][kernel] +- [C++ Operator Overloading Guidelines][overloading] +- [Wikipedia's Programming Style Page][style] + +[cppstandard]:http://www.possibility.com/Cpp/CppCodingStandard.html +[kernel]:http://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/tree/Documentation/CodingStyle +[overloading]:http://www.cs.caltech.edu/courses/cs11/material/cpp/donnie/cpp-ops.html +[style]:http://en.wikipedia.org/wiki/Programming_style diff --git a/Doxyfile b/Doxyfile index d660cdc154..70072d9567 100644 --- a/Doxyfile +++ b/Doxyfile @@ -645,7 +645,8 @@ WARN_LOGFILE = # directories like "/usr/src/myproject". Separate the files or directories # with spaces. -INPUT = Documentation/development/stable-release-policy.md \ +INPUT = Documentation/development/coding-style-policy.md \ + Documentation/development/stable-release-policy.md \ Documentation/development/road-map.md \ kicad \ pcbnew \ diff --git a/common/basicframe.cpp b/common/basicframe.cpp index 258d6ba008..ef6867fb34 100644 --- a/common/basicframe.cpp +++ b/common/basicframe.cpp @@ -1,9 +1,9 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr + * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr * Copyright (C) 2013 Wayne Stambaugh - * Copyright (C) 1992-2013 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -629,6 +629,13 @@ void EDA_BASE_FRAME::CopyVersionInfoToClipboard( wxCommandEvent& event ) tmp << wxT( "OFF\n" ); #endif + tmp << wxT( " KICAD_USE_WEBKIT=" ); +#ifdef KICAD_USE_WEBKIT + tmp << wxT( "ON\n" ); +#else + tmp << wxT( "OFF\n" ); +#endif + wxMessageBox( tmp, _("Version Information (copied to the clipboard)") ); wxTheClipboard->SetData( new wxTextDataObject( tmp ) ); diff --git a/common/build_version.cpp b/common/build_version.cpp index 77f401733d..b9e5868237 100644 --- a/common/build_version.cpp +++ b/common/build_version.cpp @@ -1,8 +1,8 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2014 Jean-Pierre Charras, jp.charras at wanadoo.fr - * Copyright (C) 2014 KiCad Developers, see CHANGELOG.TXT for contributors. + * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr + * Copyright (C) 2015 KiCad Developers, see CHANGELOG.TXT for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -30,7 +30,7 @@ #endif #ifndef KICAD_BUILD_VERSION -# define KICAD_BUILD_VERSION "(2014-jul-16 BZR unknown)" +# define KICAD_BUILD_VERSION "(after 2015-jan-16 BZR unknown)" #endif /** diff --git a/common/common.cpp b/common/common.cpp index e53959b8c7..51d7b96e25 100644 --- a/common/common.cpp +++ b/common/common.cpp @@ -212,29 +212,26 @@ void AddUnitSymbol( wxStaticText& Stext, EDA_UNITS_T aUnit ) } -wxArrayString* wxStringSplit( wxString aString, wxChar aSplitter ) +void wxStringSplit( const wxString& aText, wxArrayString& aStrings, wxChar aSplitter ) { - wxArrayString* list = new wxArrayString(); + wxString tmp; - while( 1 ) + for( unsigned ii = 0; ii < aText.Length(); ii++ ) { - int index = aString.Find( aSplitter ); + if( aText[ii] == aSplitter ) + { + aStrings.Add( tmp ); + tmp.Clear(); + } - if( index == wxNOT_FOUND ) - break; - - wxString tmp; - tmp = aString.Mid( 0, index ); - aString = aString.Mid( index + 1, aString.size() - index ); - list->Add( tmp ); + else + tmp << aText[ii]; } - if( !aString.IsEmpty() ) + if( !tmp.IsEmpty() ) { - list->Add( aString ); + aStrings.Add( tmp ); } - - return list; } diff --git a/common/config_params.cpp b/common/config_params.cpp index 4f5c6b84a3..1882ac1914 100644 --- a/common/config_params.cpp +++ b/common/config_params.cpp @@ -490,6 +490,7 @@ void PARAM_CFG_LIBNAME_LIST::ReadParam( wxConfigBase* aConfig ) const id_lib << indexlib; indexlib++; libname = aConfig->Read( id_lib, wxT( "" ) ); + if( libname.IsEmpty() ) break; // file names are stored using Unix notation diff --git a/common/drawtxt.cpp b/common/drawtxt.cpp index 33c79529b0..ffbe29f268 100644 --- a/common/drawtxt.cpp +++ b/common/drawtxt.cpp @@ -636,6 +636,7 @@ void PLOTTER::Text( const wxPoint& aPos, { // EDA_TEXT needs for calculations of the position of every // line according to orientation and justifications + wxArrayString strings; EDA_TEXT* multilineText = new EDA_TEXT( aText ); multilineText->SetSize( aSize ); multilineText->SetTextPosition( aPos ); @@ -646,15 +647,15 @@ void PLOTTER::Text( const wxPoint& aPos, multilineText->SetMultilineAllowed( aMultilineAllowed ); std::vector positions; - wxArrayString* list = wxStringSplit( aText, '\n' ); - positions.reserve( list->Count() ); + wxStringSplit( aText, strings, '\n' ); + positions.reserve( strings.Count() ); multilineText->GetPositionsOfLinesOfMultilineText( - positions, list->Count() ); + positions, strings.Count() ); - for( unsigned ii = 0; ii < list->Count(); ii++ ) + for( unsigned ii = 0; ii < strings.Count(); ii++ ) { - wxString& txt = list->Item( ii ); + wxString& txt = strings.Item( ii ); DrawGraphicText( NULL, NULL, positions[ii], aColor, txt, aOrient, aSize, aH_justify, aV_justify, @@ -663,8 +664,8 @@ void PLOTTER::Text( const wxPoint& aPos, NULL, this ); } + delete multilineText; - delete list; } else { diff --git a/common/eda_text.cpp b/common/eda_text.cpp index 98131e36fd..c592306cc8 100644 --- a/common/eda_text.cpp +++ b/common/eda_text.cpp @@ -120,23 +120,23 @@ EDA_RECT EDA_TEXT::GetTextBox( int aLine, int aThickness, bool aInvertY ) const { EDA_RECT rect; wxPoint pos; - wxArrayString* list = NULL; + wxArrayString strings; wxString text = GetShownText(); int thickness = ( aThickness < 0 ) ? m_Thickness : aThickness; int linecount = 1; if( m_MultilineAllowed ) { - list = wxStringSplit( text, '\n' ); + wxStringSplit( text, strings, '\n' ); - if ( list->GetCount() ) // GetCount() == 0 for void strings + if ( strings.GetCount() ) // GetCount() == 0 for void strings { - if( aLine >= 0 && (aLine < (int)list->GetCount()) ) - text = list->Item( aLine ); + if( aLine >= 0 && (aLine < (int)strings.GetCount()) ) + text = strings.Item( aLine ); else - text = list->Item( 0 ); + text = strings.Item( 0 ); - linecount = list->GetCount(); + linecount = strings.GetCount(); } } @@ -157,19 +157,17 @@ EDA_RECT EDA_TEXT::GetTextBox( int aLine, int aThickness, bool aInvertY ) const rect.Move( wxPoint( 0, -extra_dy / 2 ) ); // move origin by the half extra interval // for multiline texts and aLine < 0, merge all rectangles - if( m_MultilineAllowed && list && aLine < 0 ) + if( m_MultilineAllowed && aLine < 0 ) { - for( unsigned ii = 1; ii < list->GetCount(); ii++ ) + for( unsigned ii = 1; ii < strings.GetCount(); ii++ ) { - text = list->Item( ii ); + text = strings.Item( ii ); dx = LenSize( text ); textsize.x = std::max( textsize.x, dx ); textsize.y += dy; } } - delete list; - rect.SetSize( textsize ); /* Now, calculate the rect origin, according to text justification @@ -272,19 +270,18 @@ void EDA_TEXT::Draw( EDA_RECT* aClipBox, wxDC* aDC, const wxPoint& aOffset, if( m_MultilineAllowed ) { std::vector positions; - wxArrayString* list = wxStringSplit( GetShownText(), '\n' ); - positions.reserve( list->Count() ); + wxArrayString strings; + wxStringSplit( GetShownText(), strings, '\n' ); + positions.reserve( strings.Count() ); - GetPositionsOfLinesOfMultilineText(positions, list->Count() ); + GetPositionsOfLinesOfMultilineText(positions, strings.Count() ); - for( unsigned ii = 0; ii < list->Count(); ii++ ) + for( unsigned ii = 0; ii < strings.Count(); ii++ ) { - wxString& txt = list->Item( ii ); + wxString& txt = strings.Item( ii ); drawOneLineOfText( aClipBox, aDC, aOffset, aColor, aDrawMode, aFillMode, txt, positions[ii] ); } - - delete (list); } else drawOneLineOfText( aClipBox, aDC, aOffset, aColor, @@ -489,22 +486,21 @@ void EDA_TEXT::TransformTextShapeToSegmentList( std::vector& aCornerBuf if( IsMultilineAllowed() ) { - wxArrayString* list = wxStringSplit( GetShownText(), '\n' ); + wxArrayString strings_list; + wxStringSplit( GetShownText(), strings_list, wxChar('\n') ); std::vector positions; - positions.reserve( list->Count() ); - GetPositionsOfLinesOfMultilineText( positions, list->Count() ); + positions.reserve( strings_list.Count() ); + GetPositionsOfLinesOfMultilineText( positions,strings_list.Count() ); - for( unsigned ii = 0; ii < list->Count(); ii++ ) + for( unsigned ii = 0; ii < strings_list.Count(); ii++ ) { - wxString txt = list->Item( ii ); + wxString txt = strings_list.Item( ii ); DrawGraphicText( NULL, NULL, positions[ii], color, txt, GetOrientation(), size, GetHorizJustify(), GetVertJustify(), GetThickness(), IsItalic(), true, addTextSegmToBuffer ); } - - delete list; } else { diff --git a/common/geometry/shape_collisions.cpp b/common/geometry/shape_collisions.cpp index 806a50244b..c21ecc6054 100644 --- a/common/geometry/shape_collisions.cpp +++ b/common/geometry/shape_collisions.cpp @@ -171,7 +171,7 @@ static inline bool Collide( const SHAPE_CIRCLE& aA, const SHAPE_LINE_CHAIN& aB, static inline bool Collide( const SHAPE_CIRCLE& aA, const SHAPE_SEGMENT& aSeg, int aClearance, bool aNeedMTV, VECTOR2I& aMTV ) { - bool col = aA.Collide( aSeg.GetSeg(), aClearance + aSeg.GetWidth() / 2); + bool col = aA.Collide( aSeg.GetSeg(), aClearance + aSeg.GetWidth() / 2); if( col && aNeedMTV ) { @@ -210,134 +210,134 @@ static inline bool Collide( const SHAPE_RECT& aA, const SHAPE_LINE_CHAIN& aB, in static inline bool Collide( const SHAPE_RECT& aA, const SHAPE_SEGMENT& aSeg, int aClearance, bool aNeedMTV, VECTOR2I& aMTV ) { - return aA.Collide( aSeg.GetSeg(), aClearance + aSeg.GetWidth() / 2 ); + return aA.Collide( aSeg.GetSeg(), aClearance + aSeg.GetWidth() / 2 ); } static inline bool Collide( const SHAPE_SEGMENT& aA, const SHAPE_SEGMENT& aB, int aClearance, bool aNeedMTV, VECTOR2I& aMTV ) { - return aA.Collide( aB.GetSeg(), aClearance + aB.GetWidth() / 2 ); + return aA.Collide( aB.GetSeg(), aClearance + aB.GetWidth() / 2 ); } static inline bool Collide( const SHAPE_LINE_CHAIN& aA, const SHAPE_SEGMENT& aB, int aClearance, bool aNeedMTV, VECTOR2I& aMTV ) { - if( aA.Collide( aB.GetSeg(), aClearance + aB.GetWidth() / 2 ) ) - return true; + if( aA.Collide( aB.GetSeg(), aClearance + aB.GetWidth() / 2 ) ) + return true; - return false; + return false; } -template +template inline bool CollCase( const SHAPE* aA, const SHAPE* aB, int aClearance, bool aNeedMTV, VECTOR2I& aMTV ) { - return Collide (*static_cast( aA ), - *static_cast( aB ), - aClearance, aNeedMTV, aMTV); + return Collide (*static_cast( aA ), + *static_cast( aB ), + aClearance, aNeedMTV, aMTV); } -template +template inline bool CollCaseReversed ( const SHAPE* aA, const SHAPE* aB, int aClearance, bool aNeedMTV, VECTOR2I& aMTV ) { bool rv = Collide (*static_cast( aB ), *static_cast( aA ), aClearance, aNeedMTV, aMTV); - if(rv && aNeedMTV) + if(rv && aNeedMTV) aMTV = -aMTV; return rv; } bool CollideShapes( const SHAPE* aA, const SHAPE* aB, int aClearance, bool aNeedMTV, VECTOR2I& aMTV ) -{ - switch( aA->Type() ) - { - case SH_RECT: - switch( aB->Type() ) - { - case SH_CIRCLE: - return CollCase( aA, aB, aClearance, aNeedMTV, aMTV ); +{ + switch( aA->Type() ) + { + case SH_RECT: + switch( aB->Type() ) + { + case SH_CIRCLE: + return CollCase( aA, aB, aClearance, aNeedMTV, aMTV ); - case SH_LINE_CHAIN: - return CollCase( aA, aB, aClearance, aNeedMTV, aMTV ); + case SH_LINE_CHAIN: + return CollCase( aA, aB, aClearance, aNeedMTV, aMTV ); - case SH_SEGMENT: - return CollCase( aA, aB, aClearance, aNeedMTV, aMTV ); + case SH_SEGMENT: + return CollCase( aA, aB, aClearance, aNeedMTV, aMTV ); - default: - break; - } - - case SH_CIRCLE: - switch( aB->Type() ) - { - case SH_RECT: - return CollCaseReversed( aA, aB, aClearance, aNeedMTV, aMTV ); - - case SH_CIRCLE: - return CollCase( aA, aB, aClearance, aNeedMTV, aMTV ); - - case SH_LINE_CHAIN: - return CollCase( aA, aB, aClearance, aNeedMTV, aMTV ); - - case SH_SEGMENT: - return CollCase( aA, aB, aClearance, aNeedMTV, aMTV ); - default: - break; - } + break; + } - case SH_LINE_CHAIN: - switch( aB->Type() ) - { - case SH_RECT: - return CollCase( aB, aA, aClearance, aNeedMTV, aMTV ); + case SH_CIRCLE: + switch( aB->Type() ) + { + case SH_RECT: + return CollCaseReversed( aA, aB, aClearance, aNeedMTV, aMTV ); - case SH_CIRCLE: - return CollCase( aB, aA, aClearance, aNeedMTV, aMTV ); + case SH_CIRCLE: + return CollCase( aA, aB, aClearance, aNeedMTV, aMTV ); - case SH_LINE_CHAIN: - return CollCase( aA, aB, aClearance, aNeedMTV, aMTV ); + case SH_LINE_CHAIN: + return CollCase( aA, aB, aClearance, aNeedMTV, aMTV ); - case SH_SEGMENT: - return CollCase( aA, aB, aClearance, aNeedMTV, aMTV ); + case SH_SEGMENT: + return CollCase( aA, aB, aClearance, aNeedMTV, aMTV ); - default: - break; - } + default: + break; + } - case SH_SEGMENT: - switch( aB->Type() ) - { - case SH_RECT: - return CollCase( aB, aA, aClearance, aNeedMTV, aMTV ); + case SH_LINE_CHAIN: + switch( aB->Type() ) + { + case SH_RECT: + return CollCase( aB, aA, aClearance, aNeedMTV, aMTV ); - case SH_CIRCLE: + case SH_CIRCLE: + return CollCase( aB, aA, aClearance, aNeedMTV, aMTV ); + + case SH_LINE_CHAIN: + return CollCase( aA, aB, aClearance, aNeedMTV, aMTV ); + + case SH_SEGMENT: + return CollCase( aA, aB, aClearance, aNeedMTV, aMTV ); + + default: + break; + } + + case SH_SEGMENT: + switch( aB->Type() ) + { + case SH_RECT: + return CollCase( aB, aA, aClearance, aNeedMTV, aMTV ); + + case SH_CIRCLE: return CollCaseReversed( aA, aB, aClearance, aNeedMTV, aMTV ); - case SH_LINE_CHAIN: - return CollCase( aB, aA, aClearance, aNeedMTV, aMTV ); + case SH_LINE_CHAIN: + return CollCase( aB, aA, aClearance, aNeedMTV, aMTV ); - case SH_SEGMENT: - return CollCase( aA, aB, aClearance, aNeedMTV, aMTV ); + case SH_SEGMENT: + return CollCase( aA, aB, aClearance, aNeedMTV, aMTV ); - default: - break; - } + default: + break; + } - default: - break; - } + default: + break; + } - bool unsupported_collision = true; + bool unsupported_collision = true; (void) unsupported_collision; // make gcc quiet - assert( unsupported_collision == false ); + assert( unsupported_collision == false ); - return false; + return false; } diff --git a/common/html_messagebox.cpp b/common/html_messagebox.cpp index 56c9116209..17a2c97c72 100644 --- a/common/html_messagebox.cpp +++ b/common/html_messagebox.cpp @@ -51,23 +51,20 @@ void HTML_MESSAGE_BOX::ListClear() void HTML_MESSAGE_BOX::ListSet( const wxString& aList ) { - // wxArrayString* wxStringSplit( wxString txt, wxChar splitter ); - - wxArrayString* strings_list = wxStringSplit( aList, wxChar( '\n' ) ); + wxArrayString strings_list; + wxStringSplit( aList, strings_list, wxChar( '\n' ) ); wxString msg = wxT( "

    " ); - for ( unsigned ii = 0; ii < strings_list->GetCount(); ii++ ) + for ( unsigned ii = 0; ii < strings_list.GetCount(); ii++ ) { msg += wxT( "
  • " ); - msg += strings_list->Item( ii ) + wxT( "
  • " ); + msg += strings_list.Item( ii ) + wxT( "" ); } msg += wxT( "
" ); m_htmlWindow->AppendToPage( msg ); - - delete strings_list; } diff --git a/common/project.cpp b/common/project.cpp index d1b100710f..27f91a8bad 100644 --- a/common/project.cpp +++ b/common/project.cpp @@ -331,8 +331,14 @@ bool PROJECT::ConfigLoad( const SEARCH_STACK& aSList, const wxString& aGroupNam m_pro_date_and_time = timestamp; + // We do not want expansion of env var values when reading our project config file + bool state = cfg.get()->IsExpandingEnvVars(); + cfg.get()->SetExpandEnvVars( false ); + wxConfigLoadParams( cfg.get(), aParams, aGroupName ); + cfg.get()->SetExpandEnvVars( state ); + return true; } diff --git a/cvpcb/CMakeLists.txt b/cvpcb/CMakeLists.txt index 13ee3072f5..7c701b382b 100644 --- a/cvpcb/CMakeLists.txt +++ b/cvpcb/CMakeLists.txt @@ -8,7 +8,7 @@ endif() add_definitions( -DCVPCB ) -if( KICAD_USE_WEBKITT AND BUILD_GITHUB_PLUGIN ) +if( KICAD_USE_WEBKIT AND BUILD_GITHUB_PLUGIN ) set( WEBVIEWER_WXLIB "webviewer" ) add_definitions( -DKICAD_USE_WEBKIT ) endif() @@ -31,6 +31,8 @@ set( CVPCB_DIALOGS dialogs/fp_conflict_assignment_selector.cpp dialogs/dialog_display_options.cpp dialogs/dialog_display_options_base.cpp + dialogs/dialog_config_equfiles_base.cpp + dialogs/dialog_config_equfiles.cpp ../pcbnew/dialogs/dialog_fp_lib_table.cpp ../pcbnew/dialogs/dialog_fp_lib_table_base.cpp ../pcbnew/dialogs/dialog_fp_plugin_options.cpp diff --git a/cvpcb/autosel.cpp b/cvpcb/autosel.cpp index d05c6505c6..a6419aa745 100644 --- a/cvpcb/autosel.cpp +++ b/cvpcb/autosel.cpp @@ -1,7 +1,7 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -25,13 +25,16 @@ * @file autosel.cpp */ -// Routines for automatic selection of modules. +// This file handle automatic selection of footprints, from .equ files which give +// a footprint FPID associated to a component value. +// Thse assiciations have this form: +// 'FT232BL' 'QFP:LQFP-32_7x7mm_Pitch0.8mm' + #include #include #include #include -#include #include #include #include @@ -40,24 +43,10 @@ #include #include #include +#include #define QUOTE '\'' -#define FMT_TITLE_LIB_LOAD_ERROR _( "Library Load Error" ) - - -class FOOTPRINT_ALIAS -{ -public: - int m_Type; - wxString m_Name; - wxString m_FootprintName; - - FOOTPRINT_ALIAS() { m_Type = 0; } -}; - -typedef boost::ptr_vector< FOOTPRINT_ALIAS > FOOTPRINT_ALIAS_LIST; - /* * read the string between quotes and put it in aTarget @@ -82,45 +71,48 @@ wxString GetQuotedText( wxString & text ) } -void CVPCB_MAINFRAME::AssocieModule( wxCommandEvent& event ) +// A sort compare function, used to sort a FOOTPRINT_EQUIVALENCE_LIST by cmp values +// (m_ComponentValue member) +bool sortListbyCmpValue( const FOOTPRINT_EQUIVALENCE& ref, const FOOTPRINT_EQUIVALENCE& test ) { - FOOTPRINT_ALIAS_LIST aliases; - FOOTPRINT_ALIAS* alias; - COMPONENT* component; - wxFileName fn; - wxString msg, tmp; - char Line[1024]; - FILE* file; - size_t ii; + return ref.m_ComponentValue.Cmp( test.m_ComponentValue ) >= 0; +} - SEARCH_STACK& search = Kiface().KifaceSearch(); +// read the .equ files and populate the list of equvalents +int CVPCB_MAINFRAME::buildEquivalenceList( FOOTPRINT_EQUIVALENCE_LIST& aList, wxString * aErrorMessages ) +{ + char Line[1024]; + int error_count = 0; + FILE* file; + wxFileName fn; + wxString tmp, error_msg; - if( m_netlist.IsEmpty() ) - return; + SEARCH_STACK& search = Kiface().KifaceSearch(); - // Find equivalents in all available files. - for( ii = 0; ii < m_AliasLibNames.GetCount(); ii++ ) + // Find equivalences in all available files, and populates the + // equiv_List with all equivalences found in .equ files + for( unsigned ii = 0; ii < m_EquFilesNames.GetCount(); ii++ ) { - fn = m_AliasLibNames[ii]; - - if( !fn.HasExt() ) - { - fn.SetExt( FootprintAliasFileExtension ); - // above fails if filename has more than one point - } - else - { - fn.SetExt( fn.GetExt() + wxT( "." ) + FootprintAliasFileExtension ); - } + fn = wxExpandEnvVars( m_EquFilesNames[ii] ); tmp = search.FindValidPath( fn.GetFullPath() ); if( !tmp ) { - msg.Printf( _( "Footprint alias library file '%s' could not be found in the " - "default search paths." ), - GetChars( fn.GetFullName() ) ); - wxMessageBox( msg, FMT_TITLE_LIB_LOAD_ERROR, wxOK | wxICON_ERROR ); + error_count++; + + if( aErrorMessages ) + { + error_msg.Printf( _( "Equ file '%s' could not be found in the " + "default search paths." ), + GetChars( fn.GetFullName() ) ); + + if( ! aErrorMessages->IsEmpty() ) + *aErrorMessages << wxT("\n\n"); + + *aErrorMessages += error_msg; + } + continue; } @@ -128,8 +120,18 @@ void CVPCB_MAINFRAME::AssocieModule( wxCommandEvent& event ) if( file == NULL ) { - msg.Printf( _( "Error opening alias library '%s'." ), GetChars( tmp ) ); - wxMessageBox( msg, FMT_TITLE_LIB_LOAD_ERROR, wxOK | wxICON_ERROR ); + error_count++; + + if( aErrorMessages ) + { + error_msg.Printf( _( "Error opening equ file '%s'." ), GetChars( tmp ) ); + + if( ! aErrorMessages->IsEmpty() ) + *aErrorMessages << wxT("\n\n"); + + *aErrorMessages += error_msg; + } + continue; } @@ -150,21 +152,46 @@ void CVPCB_MAINFRAME::AssocieModule( wxCommandEvent& event ) value.Replace( wxT( " " ), wxT( "_" ) ); - alias = new FOOTPRINT_ALIAS(); - alias->m_Name = value; - alias->m_FootprintName = footprint; - aliases.push_back( alias ); + FOOTPRINT_EQUIVALENCE* equivItem = new FOOTPRINT_EQUIVALENCE(); + equivItem->m_ComponentValue = value; + equivItem->m_FootprintFPID = footprint; + aList.push_back( equivItem ); } fclose( file ); } - // Display the number of footprint aliases. - msg.Printf( _( "%d footprint aliases found." ), aliases.size() ); + return error_count; +} + + +void CVPCB_MAINFRAME::AutomaticFootprintMatching( wxCommandEvent& event ) +{ + FOOTPRINT_EQUIVALENCE_LIST equiv_List; + COMPONENT* component; + wxString msg, error_msg; + size_t ii; + + if( m_netlist.IsEmpty() ) + return; + + if( buildEquivalenceList( equiv_List, &error_msg ) ) + wxMessageBox( error_msg, _( "Equ files Load Error" ), wxOK | wxICON_WARNING, this ); + + // Sort the association list by component value. + // When sorted, find duplicate definitions (i.e. 2 or more items + // having the same component value) is more easy. + std::sort( equiv_List.begin(), equiv_List.end(), sortListbyCmpValue ); + + // Display the number of footprint/component equivalences. + msg.Printf( _( "%d footprint/cmp equivalences found." ), equiv_List.size() ); SetStatusText( msg, 0 ); + // Now, associe each free component with a footprint, when the association + // is found in list m_skipComponentSelect = true; ii = 0; + error_msg.Empty(); for( unsigned kk = 0; kk < m_netlist.GetCount(); kk++ ) { @@ -173,19 +200,44 @@ void CVPCB_MAINFRAME::AssocieModule( wxCommandEvent& event ) bool found = false; m_compListBox->SetSelection( ii++, true ); - if( !component->GetFPID().empty() ) + if( !component->GetFPID().empty() ) // the component has already a footprint continue; - BOOST_FOREACH( FOOTPRINT_ALIAS& alias, aliases ) + // Here a first attempt is made. We can have multiple equivItem of the same value. + // When happens, using the footprint filter of components can remove the ambiguity by + // filtering equivItem so one can use multiple equiv_List (for polar and + // nonpolar caps for example) + for( unsigned idx = 0; idx < equiv_List.size(); idx++ ) { + FOOTPRINT_EQUIVALENCE& equivItem = equiv_List[idx]; - if( alias.m_Name.CmpNoCase( component->GetValue() ) != 0 ) + if( equivItem.m_ComponentValue.CmpNoCase( component->GetValue() ) != 0 ) continue; - // filter alias so one can use multiple aliases (for polar and - // nonpolar caps for example) - const FOOTPRINT_INFO *module = m_footprints.GetModuleInfo( alias.m_FootprintName ); + const FOOTPRINT_INFO *module = m_footprints.GetModuleInfo( equivItem.m_FootprintFPID ); + bool equ_is_unique = true; + unsigned next = idx+1; + unsigned previous = idx-1; + + if( next < equiv_List.size() && + equivItem.m_ComponentValue == equiv_List[next].m_ComponentValue ) + equ_is_unique = false; + + if( previous >= 0 && + equivItem.m_ComponentValue == equiv_List[previous].m_ComponentValue ) + equ_is_unique = false; + + // If the equivalence is unique, no ambiguity: use the association + if( module && equ_is_unique ) + { + SetNewPkg( equivItem.m_FootprintFPID ); + found = true; + break; + } + + // The equivalence is not unique: use the footprint filter to try to remove + // ambiguity if( module ) { size_t filtercount = component->GetFootprintFilters().GetCount(); @@ -201,31 +253,38 @@ void CVPCB_MAINFRAME::AssocieModule( wxCommandEvent& event ) msg.Printf( _( "Component %s: footprint %s not found in any of the project " "footprint libraries." ), GetChars( component->GetReference() ), - GetChars( alias.m_FootprintName ) ); - wxMessageBox( msg, _( "CvPcb Error" ), wxOK | wxICON_ERROR, this ); + GetChars( equivItem.m_FootprintFPID ) ); + + if( ! error_msg.IsEmpty() ) + error_msg << wxT("\n\n"); + + error_msg += msg; } if( found ) { - SetNewPkg( alias.m_FootprintName ); + SetNewPkg( equivItem.m_FootprintFPID ); break; } - } + if( found ) + continue; + // obviously the last chance: there's only one filter matching one footprint - if( !found && 1 == component->GetFootprintFilters().GetCount() ) + if( 1 == component->GetFootprintFilters().GetCount() ) { // we do not need to analyse wildcards: single footprint do not // contain them and if there are wildcards it just will not match any const FOOTPRINT_INFO* module = m_footprints.GetModuleInfo( component->GetFootprintFilters()[0] ); if( module ) - { SetNewPkg( component->GetFootprintFilters()[0] ); - } } } + if( !error_msg.IsEmpty() ) + wxMessageBox( error_msg, _( "CvPcb Warning" ), wxOK | wxICON_WARNING, this ); + m_skipComponentSelect = false; } diff --git a/cvpcb/autosel.h b/cvpcb/autosel.h new file mode 100644 index 0000000000..30abce0c7c --- /dev/null +++ b/cvpcb/autosel.h @@ -0,0 +1,45 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors. + * + * 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, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef AUTOSEL_H +#define AUTOSEL_H + +// A helper class to handle info read in .equ files, which gives a footprint FPID +// corresponding to a component value. +// Each line is something like: +// 'FT232BL' 'QFP:LQFP-32_7x7mm_Pitch0.8mm' +// + + +class FOOTPRINT_EQUIVALENCE +{ +public: + wxString m_ComponentValue; // The value of a component + wxString m_FootprintFPID; // the footprint FPID corresponding to this value + + FOOTPRINT_EQUIVALENCE() {} +}; + +typedef boost::ptr_vector< FOOTPRINT_EQUIVALENCE > FOOTPRINT_EQUIVALENCE_LIST; + +#endif // ifndef AUTOSEL_H diff --git a/cvpcb/cfg.cpp b/cvpcb/cfg.cpp index 4568b67ad9..3cedd1ecc7 100644 --- a/cvpcb/cfg.cpp +++ b/cvpcb/cfg.cpp @@ -1,7 +1,7 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2007 Jean-Pierre Charras, jean-pierre.charras + * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or @@ -50,7 +50,7 @@ PARAM_CFG_ARRAY& CVPCB_MAINFRAME::GetProjectFileParameters() m_projectFileParams.push_back( new PARAM_CFG_BASE( GROUP_PCB_LIBS, PARAM_COMMAND_ERASE ) ); m_projectFileParams.push_back( new PARAM_CFG_LIBNAME_LIST( - wxT( "EquName" ), &m_AliasLibNames, GROUP_CVP_EQU ) ); + wxT( "EquName" ), &m_EquFilesNames, GROUP_CVP_EQU ) ); m_projectFileParams.push_back( new PARAM_CFG_WXSTRING( wxT( "NetIExt" ), &m_NetlistFileExtension ) ); @@ -64,9 +64,8 @@ void CVPCB_MAINFRAME::LoadProjectFile() PROJECT& prj = Prj(); m_ModuleLibNames.Clear(); - m_AliasLibNames.Clear(); + m_EquFilesNames.Clear(); - // was: Pgm().ReadProjectConfig( fn.GetFullPath(), GROUP, GetProjectFileParameters(), false ); prj.ConfigLoad( Kiface().KifaceSearch(), GROUP_CVP, GetProjectFileParameters() ); if( m_NetlistFileExtension.IsEmpty() ) @@ -77,26 +76,14 @@ void CVPCB_MAINFRAME::LoadProjectFile() void CVPCB_MAINFRAME::SaveProjectFile( wxCommandEvent& aEvent ) { PROJECT& prj = Prj(); - wxFileName fn = prj.AbsolutePath( m_NetlistFileName.GetFullPath() ); - - fn.SetExt( ProjectFileExtension ); - - if( aEvent.GetId() == ID_SAVE_PROJECT_AS || !m_NetlistFileName.IsOk() ) - { - wxFileDialog dlg( this, _( "Save Project File" ), fn.GetPath(), - wxEmptyString, ProjectFileWildcard, wxFD_SAVE ); - - if( dlg.ShowModal() == wxID_CANCEL ) - return; - - fn = dlg.GetPath(); - - if( !fn.HasExt() ) - fn.SetExt( ProjectFileExtension ); - } + SetTitle( wxString::Format( _( "Project file: '%s'" ), GetChars( prj.GetProjectFullName() ) ) ); + wxFileName fn = prj.GetProjectFullName(); if( !IsWritable( fn ) ) + { + wxMessageBox( _( "Project file '%s' is not writable" ), fn.GetFullPath() ); return; + } wxString pro_name = fn.GetFullPath(); diff --git a/cvpcb/cvframe.cpp b/cvpcb/cvframe.cpp index 3774109041..12b1067f7c 100644 --- a/cvpcb/cvframe.cpp +++ b/cvpcb/cvframe.cpp @@ -1,7 +1,7 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2009 Jean-Pierre Charras, jean-pierre.charras + * Copyright (C) 2015 Jean-Pierre Charras, jean-pierre.charras * Copyright (C) 2011 Wayne Stambaugh * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors. * @@ -69,8 +69,8 @@ BEGIN_EVENT_TABLE( CVPCB_MAINFRAME, EDA_BASE_FRAME ) EVT_MENU( wxID_HELP, CVPCB_MAINFRAME::GetKicadHelp ) EVT_MENU( wxID_ABOUT, CVPCB_MAINFRAME::GetKicadAbout ) EVT_MENU( ID_SAVE_PROJECT, CVPCB_MAINFRAME::SaveProjectFile ) - EVT_MENU( ID_SAVE_PROJECT_AS, CVPCB_MAINFRAME::SaveProjectFile ) EVT_MENU( ID_CVPCB_CONFIG_KEEP_OPEN_ON_SAVE, CVPCB_MAINFRAME::OnKeepOpenOnSave ) + EVT_MENU( ID_CVPCB_EQUFILES_LIST_EDIT, CVPCB_MAINFRAME::OnEditEquFilesList ) // Toolbar events EVT_TOOL( ID_CVPCB_QUIT, CVPCB_MAINFRAME::OnQuit ) @@ -80,7 +80,7 @@ BEGIN_EVENT_TABLE( CVPCB_MAINFRAME, EDA_BASE_FRAME ) EVT_TOOL( ID_CVPCB_GOTO_FIRSTNA, CVPCB_MAINFRAME::ToFirstNA ) EVT_TOOL( ID_CVPCB_GOTO_PREVIOUSNA, CVPCB_MAINFRAME::ToPreviousNA ) EVT_TOOL( ID_CVPCB_DEL_ASSOCIATIONS, CVPCB_MAINFRAME::DelAssociations ) - EVT_TOOL( ID_CVPCB_AUTO_ASSOCIE, CVPCB_MAINFRAME::AssocieModule ) + EVT_TOOL( ID_CVPCB_AUTO_ASSOCIE, CVPCB_MAINFRAME::AutomaticFootprintMatching ) EVT_TOOL( ID_PCB_DISPLAY_FOOTPRINT_DOC, CVPCB_MAINFRAME::DisplayDocFile ) EVT_TOOL( ID_CVPCB_FOOTPRINT_DISPLAY_FILTERED_LIST, CVPCB_MAINFRAME::OnSelectFilteringFootprint ) @@ -160,6 +160,7 @@ CVPCB_MAINFRAME::CVPCB_MAINFRAME( KIWAY* aKiway, wxWindow* aParent ) : m_auimgr.SetManagedWindow( this ); + UpdateTitle(); EDA_PANEINFO horiz; horiz.HorizontalToolbarPane(); @@ -369,10 +370,12 @@ void CVPCB_MAINFRAME::ToPreviousNA( wxCommandEvent& event ) void CVPCB_MAINFRAME::SaveQuitCvpcb( wxCommandEvent& aEvent ) { - if( aEvent.GetId() == wxID_SAVEAS ) - m_NetlistFileName.Clear(); + wxString fullFilename; - if( SaveCmpLinkFile( m_NetlistFileName.GetFullPath() ) > 0 ) + if( aEvent.GetId() != wxID_SAVEAS ) + fullFilename = m_NetlistFileName.GetFullPath(); + + if( SaveCmpLinkFile( fullFilename ) > 0 ) { m_modified = false; @@ -684,32 +687,33 @@ void CVPCB_MAINFRAME::DisplayStatus() } msg.Empty(); + wxString filters; if( m_footprintListBox ) { if( m_mainToolBar->GetToolToggled( ID_CVPCB_FOOTPRINT_DISPLAY_FILTERED_LIST ) ) - msg = _( "key words" ); + filters = _( "key words" ); if( m_mainToolBar->GetToolToggled( ID_CVPCB_FOOTPRINT_DISPLAY_PIN_FILTERED_LIST ) ) { - if( !msg.IsEmpty() ) - msg += wxT( ", " ); + if( !filters.IsEmpty() ) + filters += wxT( "+" ); - msg += _( "pin count" ); + filters += _( "pin count" ); } if( m_mainToolBar->GetToolToggled( ID_CVPCB_FOOTPRINT_DISPLAY_BY_LIBRARY_LIST ) ) { - if( !msg.IsEmpty() ) - msg += wxT( ", " ); + if( !filters.IsEmpty() ) + filters += wxT( "+" ); - msg += _( "library" ); + filters += _( "library" ); } - if( msg.IsEmpty() ) + if( filters.IsEmpty() ) msg = _( "No filtering" ); else - msg = _( "Filtered by " ) + msg; + msg.Printf( _( "Filtered by %s" ), GetChars( filters ) ); msg << wxT( ": " ) << m_footprintListBox->GetCount(); @@ -744,18 +748,21 @@ bool CVPCB_MAINFRAME::LoadFootprintFiles() void CVPCB_MAINFRAME::UpdateTitle() { wxString title = wxString::Format( wxT( "Cvpcb %s " ), GetChars( GetBuildVersion() ) ); + PROJECT& prj = Prj(); + wxFileName fn = prj.GetProjectFullName(); - if( m_NetlistFileName.IsOk() && m_NetlistFileName.FileExists() ) + if( fn.IsOk() && !prj.GetProjectFullName().IsEmpty() && fn.FileExists() ) { - title += m_NetlistFileName.GetFullPath(); + title += wxString::Format( _("Project: '%s' (netlist: '%s')"), + GetChars( fn.GetFullPath() ), + GetChars( m_NetlistFileName.GetFullName() ) + ); - if( !m_NetlistFileName.IsFileWritable() ) + if( !fn.IsFileWritable() ) title += _( " [Read Only]" ); } else - { - title += _( "[no file]" ); - } + title += _( "[no project]" ); SetTitle( title ); } diff --git a/cvpcb/cvpcb.cpp b/cvpcb/cvpcb.cpp index 8cca374f1e..953dbabf4f 100644 --- a/cvpcb/cvpcb.cpp +++ b/cvpcb/cvpcb.cpp @@ -51,10 +51,10 @@ COLORS_DESIGN_SETTINGS g_ColorsSettings; // Constant string definitions for CvPcb -const wxString FootprintAliasFileExtension( wxT( "equ" ) ); +const wxString EquFileExtension( wxT( "equ" ) ); // Wildcard for schematic retroannotation (import footprint names in schematic): -const wxString FootprintAliasFileWildcard( _( "KiCad footprint alias files (*.equ)|*.equ" ) ); +const wxString EquFilesWildcard( _( "Component/footprint equ files (*.equ)|*.equ" ) ); #if 0 // add this logic to OpenProjectFiles() diff --git a/cvpcb/cvpcb.h b/cvpcb/cvpcb.h index 588ea045a7..50b7afe2f5 100644 --- a/cvpcb/cvpcb.h +++ b/cvpcb/cvpcb.h @@ -36,8 +36,8 @@ #define LISTB_STYLE ( wxSUNKEN_BORDER | wxLC_NO_HEADER | wxLC_REPORT | wxLC_VIRTUAL | \ wxLC_SINGLE_SEL | wxVSCROLL | wxHSCROLL ) -extern const wxString FootprintAliasFileExtension; -extern const wxString FootprintAliasFileWildcard; +extern const wxString EquFileExtension; +extern const wxString EquFilesWildcard; #endif /* __CVPCB_H__ */ diff --git a/cvpcb/cvpcb_id.h b/cvpcb/cvpcb_id.h index a29031904d..6c7cc6a159 100644 --- a/cvpcb/cvpcb_id.h +++ b/cvpcb/cvpcb_id.h @@ -56,5 +56,6 @@ enum id_cvpcb_frm ID_CVPCB_FOOTPRINT_DISPLAY_BY_LIBRARY_LIST, ID_CVPCB_CONFIG_KEEP_OPEN_ON_SAVE, ID_CVPCB_LIBRARY_LIST, + ID_CVPCB_EQUFILES_LIST_EDIT, ID_CVPCB_LIB_TABLE_EDIT }; diff --git a/cvpcb/cvpcb_mainframe.h b/cvpcb/cvpcb_mainframe.h index 2d42947ed7..8f83042341 100644 --- a/cvpcb/cvpcb_mainframe.h +++ b/cvpcb/cvpcb_mainframe.h @@ -36,6 +36,7 @@ #include #include +#include /* Forward declarations of all top-level window classes. */ @@ -66,7 +67,7 @@ public: wxAuiToolBar* m_mainToolBar; wxFileName m_NetlistFileName; wxArrayString m_ModuleLibNames; - wxArrayString m_AliasLibNames; + wxArrayString m_EquFilesNames; wxString m_NetlistFileExtension; wxString m_DocModulesFileName; FOOTPRINT_LIST m_footprints; @@ -137,10 +138,16 @@ public: /** * Function OnEditLibraryTable - * envokes the footpirnt library table edit dialog. + * envokes the footprint library table edit dialog. */ void OnEditFootprintLibraryTable( wxCommandEvent& aEvent ); + /** + * Function OnEditEquFilesList + * envokes the equ files list edit dialog. + */ + void OnEditEquFilesList( wxCommandEvent& aEvent ); + void OnKeepOpenOnSave( wxCommandEvent& event ); void DisplayModule( wxCommandEvent& event ); @@ -152,7 +159,7 @@ public: * format of a line: * 'cmp_ref' 'footprint_name' */ - void AssocieModule( wxCommandEvent& event ); + void AutomaticFootprintMatching( wxCommandEvent& event ); void DisplayDocFile( wxCommandEvent& event ); @@ -171,6 +178,7 @@ public: * @param aFootprintName = the selected footprint */ void SetNewPkg( const wxString& aFootprintName ); + void BuildCmpListBox(); void BuildFOOTPRINTS_LISTBOX(); void BuildLIBRARY_LISTBOX(); @@ -286,6 +294,17 @@ public: COMPONENT* GetSelectedComponent(); +private: + + /** + * read the .equ files and populate the list of equvalents + * @param aList the list to populate + * @param aErrorMessages is a pointer to a wxString to store error messages + * (can be NULL) + * @return the error count ( 0 = no error) + */ + int buildEquivalenceList( FOOTPRINT_EQUIVALENCE_LIST& aList, wxString * aErrorMessages = NULL ); + DECLARE_EVENT_TABLE() }; diff --git a/cvpcb/dialogs/dialog_config_equfiles.cpp b/cvpcb/dialogs/dialog_config_equfiles.cpp new file mode 100644 index 0000000000..807139bbc4 --- /dev/null +++ b/cvpcb/dialogs/dialog_config_equfiles.cpp @@ -0,0 +1,308 @@ +/** + * @file dialog_config_equfiles.cpp + */ + +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr + * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors. + * + * 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, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include +#include +#include +#include +#include +#include // For PROJECT_VAR_NAME definition +#include // For KISYSMOD definition + +#include +#include + +#include +#include + + +DIALOG_CONFIG_EQUFILES::DIALOG_CONFIG_EQUFILES( CVPCB_MAINFRAME* aParent ) : + DIALOG_CONFIG_EQUFILES_BASE( aParent ) +{ + m_Parent = aParent; + m_Config = Pgm().CommonSettings(); + + PROJECT& prj = Prj(); + SetTitle( wxString::Format( _( "Project file: '%s'" ), GetChars( prj.GetProjectFullName() ) ) ); + + Init( ); + + GetSizer()->SetSizeHints( this ); + Center(); +} + +void CVPCB_MAINFRAME::OnEditEquFilesList( wxCommandEvent& aEvent ) +{ + DIALOG_CONFIG_EQUFILES dlg( this ); + + dlg.ShowModal(); +} + + +void DIALOG_CONFIG_EQUFILES::Init() +{ + m_sdbSizerOK->SetDefault(); + m_ListChanged = false; + m_ListEquiv->InsertItems( m_Parent->m_EquFilesNames, 0 ); + + if( getEnvVarCount() < 2 ) + m_gridEnvVars->AppendRows(2 - getEnvVarCount() ); + + wxString evValue; + int row = 0; + + m_gridEnvVars->SetCellValue( row++, 0, PROJECT_VAR_NAME ); + m_gridEnvVars->SetCellValue( row, 0, FP_LIB_TABLE::GlobalPathEnvVariableName() ); + + for( row = 0; row < getEnvVarCount(); row++ ) + { + if( wxGetEnv( m_gridEnvVars->GetCellValue( row, 0 ), &evValue ) ) + m_gridEnvVars->SetCellValue( row, 1, evValue ); + } + + m_gridEnvVars->AutoSizeColumns(); + +} + +void DIALOG_CONFIG_EQUFILES::OnEditEquFile( wxCommandEvent& event ) +{ + wxString editorname = Pgm().GetEditorName(); + + if( editorname.IsEmpty() ) + { + wxMessageBox( _( "No editor defined in Kicad. Please chose it" ) ); + return; + } + + wxArrayInt selections; + m_ListEquiv->GetSelections( selections ); + + wxString fullFileNames, tmp; + + for( unsigned ii = 0; ii < selections.GetCount(); ii++ ) + { + tmp = m_ListEquiv->GetString( selections[ii] ); + fullFileNames << wxT( " \"" ) << wxExpandEnvVars( tmp ) << wxT( "\"" ); + m_ListChanged = true; + } + + ExecuteFile( this, editorname, fullFileNames ); +} + + +void DIALOG_CONFIG_EQUFILES::OnCancelClick( wxCommandEvent& event ) +{ + EndModal( wxID_CANCEL ); +} + + +void DIALOG_CONFIG_EQUFILES::OnOkClick( wxCommandEvent& event ) +{ + // Save new equ file list if the files list was modified + if( m_ListChanged ) + { + // Recreate equ list + m_Parent->m_EquFilesNames.Clear(); + + for( unsigned ii = 0; ii < m_ListEquiv->GetCount(); ii++ ) + m_Parent->m_EquFilesNames.Add( m_ListEquiv->GetString( ii ) ); + + wxCommandEvent evt( ID_SAVE_PROJECT ); + m_Parent->SaveProjectFile( evt ); + } + + EndModal( wxID_OK ); +} + + +void DIALOG_CONFIG_EQUFILES::OnCloseWindow( wxCloseEvent& event ) +{ + EndModal( wxID_CANCEL ); +} + + +/********************************************************************/ +void DIALOG_CONFIG_EQUFILES::OnButtonMoveUp( wxCommandEvent& event ) +/********************************************************************/ +{ + wxArrayInt selections; + + m_ListEquiv->GetSelections( selections ); + + if ( selections.GetCount() <= 0 ) // No selection. + return; + + if( selections[0] == 0 ) // The first lib is selected. cannot move up it + return; + + wxArrayString libnames = m_ListEquiv->GetStrings(); + + for( size_t ii = 0; ii < selections.GetCount(); ii++ ) + { + int jj = selections[ii]; + EXCHG( libnames[jj], libnames[jj-1] ); + } + + m_ListEquiv->Set( libnames ); + + // Reselect previously selected names + for( size_t ii = 0; ii < selections.GetCount(); ii++ ) + { + int jj = selections[ii]; + m_ListEquiv->SetSelection( jj-1 ); + } + + m_ListChanged = true; +} + + +/*********************************************************************/ +void DIALOG_CONFIG_EQUFILES::OnButtonMoveDown( wxCommandEvent& event ) +/*********************************************************************/ +{ + wxArrayInt selections; + m_ListEquiv->GetSelections( selections ); + + if ( selections.GetCount() <= 0 ) // No selection. + return; + + // The last lib is selected. cannot move down it + if( selections.Last() == int( m_ListEquiv->GetCount()-1 ) ) + return; + + wxArrayString libnames = m_ListEquiv->GetStrings(); + + for( int ii = selections.GetCount()-1; ii >= 0; ii-- ) + { + int jj = selections[ii]; + EXCHG( libnames[jj], libnames[jj+1]); + } + + m_ListEquiv->Set( libnames ); + + // Reselect previously selected names + for( size_t ii = 0; ii < selections.GetCount(); ii++ ) + { + int jj = selections[ii]; + m_ListEquiv->SetSelection(jj+1); + } + + m_ListChanged = true; +} + + +/* Remove a library to the library list. + * The real list (g_LibName_List) is not changed, so the change can be canceled + */ +void DIALOG_CONFIG_EQUFILES::OnRemoveFiles( wxCommandEvent& event ) +{ + wxArrayInt selections; + m_ListEquiv->GetSelections( selections ); + + std::sort( selections.begin(), selections.end() ); + + for( int ii = selections.GetCount()-1; ii >= 0; ii-- ) + { + m_ListEquiv->Delete(selections[ii] ); + m_ListChanged = true; + } +} + + +/* Insert or add a library to the library list: + * The new library is put in list before (insert button) the selection, + * or added (add button) to end of list + */ +void DIALOG_CONFIG_EQUFILES::OnAddFiles( wxCommandEvent& event ) +{ + wxString equFilename, wildcard; + wxFileName fn; + + wildcard = EquFilesWildcard; + wxListBox* list = m_ListEquiv; + + // Get a default path to open the file dialog: + wxString libpath; + wxArrayInt selectedRows = m_gridEnvVars->GetSelectedRows(); + + int row = selectedRows.GetCount() ? selectedRows[0] : + m_gridEnvVars->GetGridCursorRow(); + + libpath = m_gridEnvVars->GetCellValue( wxGridCellCoords( row, 1 ) ); + + wxFileDialog FilesDialog( this, _( "Equ files:" ), libpath, + wxEmptyString, wildcard, + wxFD_DEFAULT_STYLE | wxFD_MULTIPLE ); + + if( FilesDialog.ShowModal() != wxID_OK ) + return; + + wxArrayString Filenames; + FilesDialog.GetPaths( Filenames ); + + for( unsigned jj = 0; jj < Filenames.GetCount(); jj++ ) + { + fn = Filenames[jj]; + equFilename.Empty(); + + if( isPathRelativeAllowed() ) // try to use relative path + { + for( row = 0; row < getEnvVarCount(); row++ ) + { + libpath = m_gridEnvVars->GetCellValue( wxGridCellCoords( row, 1 ) ); + + if( fn.MakeRelativeTo( libpath ) ) + { + equFilename.Printf( wxT("${%s}%c%s"), + GetChars( m_gridEnvVars->GetCellValue( wxGridCellCoords( row, 0 ) ) ), + fn.GetPathSeparator(), + GetChars( fn.GetFullPath() ) ); + break; + } + } + } + + if( equFilename.IsEmpty() ) + equFilename = Filenames[jj]; + + // Add or insert new library name, if not already in list + if( list->FindString( equFilename, fn.IsCaseSensitive() ) == wxNOT_FOUND ) + { + m_ListChanged = true; + equFilename.Replace( wxT("\\"), wxT("/") ); // Use unix separators only. + list->Append( equFilename ); + } + else + { + wxString msg; + msg.Printf( _( "File '%s' already exists in list" ), equFilename.GetData() ); + DisplayError( this, msg ); + } + } +} diff --git a/cvpcb/dialogs/dialog_config_equfiles.h b/cvpcb/dialogs/dialog_config_equfiles.h new file mode 100644 index 0000000000..b0e20691bc --- /dev/null +++ b/cvpcb/dialogs/dialog_config_equfiles.h @@ -0,0 +1,71 @@ +/** + * @file dialog_config_equfiles.h + */ + +/* + * This program source code file is part of KICAD, a free EDA CAD application. + * + * Copyright (C) 2010-2015 Jean-Pierre Charras jp.charras at wanadoo.fr + * Copyright (C) 1992-2015 Kicad Developers, see CHANGELOG.TXT for contributors. + * + * 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, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef _DIALOG_CONFIG_EQUFILES_H_ +#define _DIALOG_CONFIG_EQUFILES_H_ + +#include + +class DIALOG_CONFIG_EQUFILES : public DIALOG_CONFIG_EQUFILES_BASE +{ +private: + CVPCB_MAINFRAME* m_Parent; + wxConfigBase* m_Config; + wxString m_UserLibDirBufferImg; + + bool m_ListChanged; + +private: + void Init(); + + // Virtual event handlers + void OnCloseWindow( wxCloseEvent& event ); + void OnOkClick( wxCommandEvent& event ); + void OnCancelClick( wxCommandEvent& event ); + void OnAddFiles( wxCommandEvent& event ); + void OnEditEquFile( wxCommandEvent& event ); + void OnRemoveFiles( wxCommandEvent& event ); + void OnButtonMoveUp( wxCommandEvent& event ); + void OnButtonMoveDown( wxCommandEvent& event ); + + int getEnvVarCount() // Get the number of rows in env var table + { + return m_gridEnvVars->GetTable()->GetRowsCount(); + } + + bool isPathRelativeAllowed() + { + return m_rbPathOptionChoice->GetSelection() == 1; + } + +public: + DIALOG_CONFIG_EQUFILES( CVPCB_MAINFRAME* parent ); + ~DIALOG_CONFIG_EQUFILES() {}; +}; + +#endif // _DIALOG_CONFIG_EQUFILES_H_ diff --git a/cvpcb/dialogs/dialog_config_equfiles_base.cpp b/cvpcb/dialogs/dialog_config_equfiles_base.cpp new file mode 100644 index 0000000000..e4b8a8cc0c --- /dev/null +++ b/cvpcb/dialogs/dialog_config_equfiles_base.cpp @@ -0,0 +1,151 @@ +/////////////////////////////////////////////////////////////////////////// +// C++ code generated with wxFormBuilder (version Jun 5 2014) +// http://www.wxformbuilder.org/ +// +// PLEASE DO "NOT" EDIT THIS FILE! +/////////////////////////////////////////////////////////////////////////// + +#include "dialog_config_equfiles_base.h" + +/////////////////////////////////////////////////////////////////////////// + +DIALOG_CONFIG_EQUFILES_BASE::DIALOG_CONFIG_EQUFILES_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style ) +{ + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + + wxBoxSizer* bMainSizer; + bMainSizer = new wxBoxSizer( wxVERTICAL ); + + wxStaticBoxSizer* sbEquivChoiceSizer; + sbEquivChoiceSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Footprint/Component equ files (.equ files)") ), wxHORIZONTAL ); + + wxBoxSizer* bSizerFlist; + bSizerFlist = new wxBoxSizer( wxVERTICAL ); + + m_ListEquiv = new wxListBox( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_EXTENDED|wxLB_HSCROLL|wxLB_NEEDED_SB|wxLB_SINGLE ); + m_ListEquiv->SetMinSize( wxSize( 350,-1 ) ); + + bSizerFlist->Add( m_ListEquiv, 1, wxRIGHT|wxLEFT|wxEXPAND, 5 ); + + + sbEquivChoiceSizer->Add( bSizerFlist, 1, wxEXPAND, 5 ); + + wxBoxSizer* bSizerButtons; + bSizerButtons = new wxBoxSizer( wxVERTICAL ); + + m_buttonAddEqu = new wxButton( this, ID_ADD_EQU, _("Add"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizerButtons->Add( m_buttonAddEqu, 0, wxALIGN_CENTER_HORIZONTAL|wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); + + m_buttonRemoveEqu = new wxButton( this, ID_REMOVE_EQU, _("Remove"), wxDefaultPosition, wxDefaultSize, 0 ); + m_buttonRemoveEqu->SetToolTip( _("Unload the selected library") ); + + bSizerButtons->Add( m_buttonRemoveEqu, 0, wxALIGN_CENTER_HORIZONTAL|wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); + + m_buttonMoveUp = new wxButton( this, ID_EQU_UP, _("Move Up"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizerButtons->Add( m_buttonMoveUp, 0, wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); + + m_buttonMoveDown = new wxButton( this, ID_EQU_DOWN, _("Move Down"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizerButtons->Add( m_buttonMoveDown, 0, wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); + + m_buttonEdit = new wxButton( this, wxID_ANY, _("Edit Equ File"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizerButtons->Add( m_buttonEdit, 0, wxALL|wxEXPAND, 5 ); + + + sbEquivChoiceSizer->Add( bSizerButtons, 0, wxALIGN_CENTER_VERTICAL, 5 ); + + + bMainSizer->Add( sbEquivChoiceSizer, 1, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 ); + + wxBoxSizer* bSizerLower; + bSizerLower = new wxBoxSizer( wxHORIZONTAL ); + + wxBoxSizer* bSizerEnvVar; + bSizerEnvVar = new wxBoxSizer( wxVERTICAL ); + + m_staticText2 = new wxStaticText( this, wxID_ANY, _("Available environment variables for relative paths:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText2->Wrap( -1 ); + bSizerEnvVar->Add( m_staticText2, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); + + m_gridEnvVars = new wxGrid( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 ); + + // Grid + m_gridEnvVars->CreateGrid( 2, 2 ); + m_gridEnvVars->EnableEditing( true ); + m_gridEnvVars->EnableGridLines( true ); + m_gridEnvVars->EnableDragGridSize( false ); + m_gridEnvVars->SetMargins( 0, 0 ); + + // Columns + m_gridEnvVars->EnableDragColMove( false ); + m_gridEnvVars->EnableDragColSize( true ); + m_gridEnvVars->SetColLabelSize( 25 ); + m_gridEnvVars->SetColLabelValue( 0, _("Name") ); + m_gridEnvVars->SetColLabelValue( 1, _("Value") ); + m_gridEnvVars->SetColLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE ); + + // Rows + m_gridEnvVars->AutoSizeRows(); + m_gridEnvVars->EnableDragRowSize( true ); + m_gridEnvVars->SetRowLabelSize( 30 ); + m_gridEnvVars->SetRowLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE ); + + // Label Appearance + + // Cell Defaults + m_gridEnvVars->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP ); + bSizerEnvVar->Add( m_gridEnvVars, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); + + + bSizerLower->Add( bSizerEnvVar, 1, wxEXPAND, 5 ); + + wxString m_rbPathOptionChoiceChoices[] = { _("Absolute path"), _("Relative path") }; + int m_rbPathOptionChoiceNChoices = sizeof( m_rbPathOptionChoiceChoices ) / sizeof( wxString ); + m_rbPathOptionChoice = new wxRadioBox( this, wxID_ANY, _("Path option:"), wxDefaultPosition, wxDefaultSize, m_rbPathOptionChoiceNChoices, m_rbPathOptionChoiceChoices, 1, wxRA_SPECIFY_COLS ); + m_rbPathOptionChoice->SetSelection( 1 ); + bSizerLower->Add( m_rbPathOptionChoice, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + + bMainSizer->Add( bSizerLower, 0, wxEXPAND, 5 ); + + m_staticline2 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); + bMainSizer->Add( m_staticline2, 0, wxEXPAND|wxALL, 5 ); + + m_sdbSizer = new wxStdDialogButtonSizer(); + m_sdbSizerOK = new wxButton( this, wxID_OK ); + m_sdbSizer->AddButton( m_sdbSizerOK ); + m_sdbSizerCancel = new wxButton( this, wxID_CANCEL ); + m_sdbSizer->AddButton( m_sdbSizerCancel ); + m_sdbSizer->Realize(); + + bMainSizer->Add( m_sdbSizer, 0, wxALL|wxEXPAND, 5 ); + + + this->SetSizer( bMainSizer ); + this->Layout(); + + this->Centre( wxBOTH ); + + // Connect Events + this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_CONFIG_EQUFILES_BASE::OnCloseWindow ) ); + m_buttonAddEqu->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CONFIG_EQUFILES_BASE::OnAddFiles ), NULL, this ); + m_buttonRemoveEqu->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CONFIG_EQUFILES_BASE::OnRemoveFiles ), NULL, this ); + m_buttonMoveUp->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CONFIG_EQUFILES_BASE::OnButtonMoveUp ), NULL, this ); + m_buttonMoveDown->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CONFIG_EQUFILES_BASE::OnButtonMoveDown ), NULL, this ); + m_buttonEdit->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CONFIG_EQUFILES_BASE::OnEditEquFile ), NULL, this ); + m_sdbSizerCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CONFIG_EQUFILES_BASE::OnCancelClick ), NULL, this ); + m_sdbSizerOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CONFIG_EQUFILES_BASE::OnOkClick ), NULL, this ); +} + +DIALOG_CONFIG_EQUFILES_BASE::~DIALOG_CONFIG_EQUFILES_BASE() +{ + // Disconnect Events + this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_CONFIG_EQUFILES_BASE::OnCloseWindow ) ); + m_buttonAddEqu->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CONFIG_EQUFILES_BASE::OnAddFiles ), NULL, this ); + m_buttonRemoveEqu->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CONFIG_EQUFILES_BASE::OnRemoveFiles ), NULL, this ); + m_buttonMoveUp->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CONFIG_EQUFILES_BASE::OnButtonMoveUp ), NULL, this ); + m_buttonMoveDown->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CONFIG_EQUFILES_BASE::OnButtonMoveDown ), NULL, this ); + m_buttonEdit->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CONFIG_EQUFILES_BASE::OnEditEquFile ), NULL, this ); + m_sdbSizerCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CONFIG_EQUFILES_BASE::OnCancelClick ), NULL, this ); + m_sdbSizerOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CONFIG_EQUFILES_BASE::OnOkClick ), NULL, this ); + +} diff --git a/cvpcb/dialogs/dialog_config_equfiles_base.fbp b/cvpcb/dialogs/dialog_config_equfiles_base.fbp new file mode 100644 index 0000000000..38e625e402 --- /dev/null +++ b/cvpcb/dialogs/dialog_config_equfiles_base.fbp @@ -0,0 +1,1108 @@ + + + + + + C++ + 1 + source_name + 0 + 0 + res + UTF-8 + connect + dialog_config_equfiles_base + 1000 + none + 1 + dialog_cvpcb_config_equfile_base + + . + + 1 + 1 + 1 + 1 + UI + 1 + 0 + + 0 + wxAUI_MGR_DEFAULT + + wxBOTH + + 1 + 1 + impl_virtual + + + + 0 + wxID_ANY + + + DIALOG_CONFIG_EQUFILES_BASE + + 454,338 + wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER + DIALOG_SHIM; dialog_shim.h + + + + + + + + + + + + + + + OnCloseWindow + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bMainSizer + wxVERTICAL + none + + 5 + wxEXPAND|wxTOP|wxRIGHT|wxLEFT + 1 + + wxID_ANY + Footprint/Component equ files (.equ files) + + sbEquivChoiceSizer + wxHORIZONTAL + none + + + 5 + wxEXPAND + 1 + + + bSizerFlist + wxVERTICAL + none + + 5 + wxRIGHT|wxLEFT|wxEXPAND + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + -1,-1 + + 0 + 350,-1 + 1 + m_ListEquiv + 1 + + + protected + 1 + + Resizable + 1 + + wxLB_EXTENDED|wxLB_HSCROLL|wxLB_NEEDED_SB|wxLB_SINGLE + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL + 0 + + + bSizerButtons + wxVERTICAL + none + + 5 + wxALIGN_CENTER_HORIZONTAL|wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + ID_ADD_EQU + Add + + 0 + + + 0 + + 1 + m_buttonAddEqu + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + OnAddFiles + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_HORIZONTAL|wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + ID_REMOVE_EQU + Remove + + 0 + + + 0 + + 1 + m_buttonRemoveEqu + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + Unload the selected library + + wxFILTER_NONE + wxDefaultValidator + + + + + OnRemoveFiles + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxBOTTOM|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + ID_EQU_UP + Move Up + + 0 + + + 0 + + 1 + m_buttonMoveUp + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + OnButtonMoveUp + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxBOTTOM|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + ID_EQU_DOWN + Move Down + + 0 + + + 0 + + 1 + m_buttonMoveDown + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + OnButtonMoveDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Edit Equ File + + 0 + + + 0 + + 1 + m_buttonEdit + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + OnEditEquFile + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 0 + + + bSizerLower + wxHORIZONTAL + none + + 5 + wxEXPAND + 1 + + + bSizerEnvVar + wxVERTICAL + none + + 5 + wxTOP|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Available environment variables for relative paths: + + 0 + + + 0 + + 1 + m_staticText2 + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + 0 + 1 + + + + 1 + + + wxALIGN_LEFT + + wxALIGN_TOP + 0 + 1 + wxALIGN_CENTRE + 25 + "Name" "Value" + wxALIGN_CENTRE + 2 + + + 1 + 0 + Dock + 0 + Left + 0 + 1 + 0 + 1 + 1 + 1 + + 1 + + + 1 + 0 + 0 + wxID_ANY + + + + 0 + 0 + + 0 + + + 0 + + 1 + m_gridEnvVars + 1 + + + protected + 1 + + Resizable + wxALIGN_CENTRE + 30 + + wxALIGN_CENTRE + + 2 + 1 + + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + "Absolute path" "Relative path" + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Path option: + 1 + + 0 + + + 0 + + 1 + m_rbPathOptionChoice + 1 + + + protected + 1 + + Resizable + 1 + 1 + + wxRA_SPECIFY_COLS + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_staticline2 + 1 + + + protected + 1 + + Resizable + 1 + + wxLI_HORIZONTAL + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND + 0 + + 0 + 1 + 0 + 0 + 0 + 1 + 0 + 0 + + m_sdbSizer + protected + + OnCancelClick + + + + OnOkClick + + + + + + + + diff --git a/cvpcb/dialogs/dialog_config_equfiles_base.h b/cvpcb/dialogs/dialog_config_equfiles_base.h new file mode 100644 index 0000000000..2220da5987 --- /dev/null +++ b/cvpcb/dialogs/dialog_config_equfiles_base.h @@ -0,0 +1,82 @@ +/////////////////////////////////////////////////////////////////////////// +// C++ code generated with wxFormBuilder (version Jun 5 2014) +// http://www.wxformbuilder.org/ +// +// PLEASE DO "NOT" EDIT THIS FILE! +/////////////////////////////////////////////////////////////////////////// + +#ifndef __DIALOG_CONFIG_EQUFILES_BASE_H__ +#define __DIALOG_CONFIG_EQUFILES_BASE_H__ + +#include +#include +#include +class DIALOG_SHIM; + +#include "dialog_shim.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +/// Class DIALOG_CONFIG_EQUFILES_BASE +/////////////////////////////////////////////////////////////////////////////// +class DIALOG_CONFIG_EQUFILES_BASE : public DIALOG_SHIM +{ + private: + + protected: + enum + { + ID_ADD_EQU = 1000, + ID_REMOVE_EQU, + ID_EQU_UP, + ID_EQU_DOWN + }; + + wxListBox* m_ListEquiv; + wxButton* m_buttonAddEqu; + wxButton* m_buttonRemoveEqu; + wxButton* m_buttonMoveUp; + wxButton* m_buttonMoveDown; + wxButton* m_buttonEdit; + wxStaticText* m_staticText2; + wxGrid* m_gridEnvVars; + wxRadioBox* m_rbPathOptionChoice; + wxStaticLine* m_staticline2; + wxStdDialogButtonSizer* m_sdbSizer; + wxButton* m_sdbSizerOK; + wxButton* m_sdbSizerCancel; + + // Virtual event handlers, overide them in your derived class + virtual void OnCloseWindow( wxCloseEvent& event ) { event.Skip(); } + virtual void OnAddFiles( wxCommandEvent& event ) { event.Skip(); } + virtual void OnRemoveFiles( wxCommandEvent& event ) { event.Skip(); } + virtual void OnButtonMoveUp( wxCommandEvent& event ) { event.Skip(); } + virtual void OnButtonMoveDown( wxCommandEvent& event ) { event.Skip(); } + virtual void OnEditEquFile( wxCommandEvent& event ) { event.Skip(); } + virtual void OnCancelClick( wxCommandEvent& event ) { event.Skip(); } + virtual void OnOkClick( wxCommandEvent& event ) { event.Skip(); } + + + public: + + DIALOG_CONFIG_EQUFILES_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 454,338 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); + ~DIALOG_CONFIG_EQUFILES_BASE(); + +}; + +#endif //__DIALOG_CONFIG_EQUFILES_BASE_H__ diff --git a/cvpcb/dialogs/dialog_cvpcb_config.cpp.notused b/cvpcb/dialogs/dialog_cvpcb_config.cpp.notused deleted file mode 100644 index b0836502f4..0000000000 --- a/cvpcb/dialogs/dialog_cvpcb_config.cpp.notused +++ /dev/null @@ -1,494 +0,0 @@ -/** - * @file dialog_cvpcb_config.cpp - */ - -/* - * This program source code file is part of KiCad, a free EDA CAD application. - * - * Copyright (C) 2012 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com - * Copyright (C) 2012 Wayne Stambaugh - * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors. - * - * 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, you may find one here: - * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - * or you may search the http://www.gnu.org website for the version 2 license, - * or you may write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - - -DIALOG_CVPCB_CONFIG::DIALOG_CVPCB_CONFIG( CVPCB_MAINFRAME* aParent ) : - DIALOG_CVPCB_CONFIG_FBP( aParent ) -{ - wxString title; - wxFileName fn = aParent->m_NetlistFileName; - - fn.SetExt( ProjectFileExtension ); - - m_Parent = aParent; - m_Config = Pgm().CommonSettings(); - - Init( ); - title.Format( _( "Project file: '%s'" ), GetChars( fn.GetFullPath() ) ); - SetTitle( title ); - - if( GetSizer() ) - { - GetSizer()->SetSizeHints( this ); - } - - m_sdbSizer2OK->SetDefault(); -} - - -void DIALOG_CVPCB_CONFIG::Init() -{ - wxString msg; - - SetFocus(); - - m_LibListChanged = false; - m_LibPathChanged = false; - m_UserLibDirBufferImg = m_Parent->m_UserLibraryPath; - - m_ListLibr->InsertItems( m_Parent->m_ModuleLibNames, 0 ); - m_ListEquiv->InsertItems( m_Parent->m_AliasLibNames, 0 ); - - m_TextHelpModulesFileName->SetValue( m_Parent->m_DocModulesFileName ); - - // Load user libs paths: - wxStringTokenizer Token( m_UserLibDirBufferImg, wxT( ";\n\r" ) ); - - while( Token.HasMoreTokens() ) - { - wxString path = Token.GetNextToken(); - - if( wxFileName::DirExists( path ) ) - m_listUserPaths->Append( path ); - } - - // Display actual libraries paths: - wxPathList libpaths = Pgm().GetLibraryPathList(); - - for( unsigned ii = 0; ii < libpaths.GetCount(); ii++ ) - { - m_DefaultLibraryPathslistBox->Append( libpaths[ii] ); - } - - // select the first path after the current path project - if( libpaths.GetCount() > 1 ) - m_DefaultLibraryPathslistBox->Select( 1 ); -} - - -void DIALOG_CVPCB_CONFIG::OnCancelClick( wxCommandEvent& event ) -{ - // Recreate the user lib path - if( m_LibPathChanged ) - { - for( unsigned ii = 0; ii < m_ListLibr->GetCount(); ii++ ) - Pgm().RemoveLibraryPath( m_listUserPaths->GetString( ii ) ); - - Pgm().InsertLibraryPath( m_Parent->m_UserLibraryPath, 1 ); - } - - EndModal( wxID_CANCEL ); -} - - -void DIALOG_CVPCB_CONFIG::OnOkClick( wxCommandEvent& event ) -{ - m_Parent->m_DocModulesFileName = m_TextHelpModulesFileName->GetValue(); - - // Recreate the user lib path - if( m_LibPathChanged ) - { - m_Parent->m_UserLibraryPath.Empty(); - - for( unsigned ii = 0; ii < m_listUserPaths->GetCount(); ii++ ) - { - if( ii > 0 ) - m_Parent->m_UserLibraryPath << wxT( ";" ); - - m_Parent->m_UserLibraryPath << m_listUserPaths->GetString( ii ); - } - } - - // Set new active library list if the lib list of if default path list was modified - if( m_LibListChanged || m_LibPathChanged ) - { - // Recreate lib list - m_Parent->m_ModuleLibNames.Clear(); - - for( unsigned ii = 0; ii < m_ListLibr->GetCount(); ii++ ) - m_Parent->m_ModuleLibNames.Add( m_ListLibr->GetString( ii ) ); - - // Recreate equ list - m_Parent->m_AliasLibNames.Clear(); - - for( unsigned ii = 0; ii < m_ListEquiv->GetCount(); ii++ ) - m_Parent->m_AliasLibNames.Add( m_ListEquiv->GetString( ii ) ); - - m_Parent->LoadFootprintFiles(); - m_Parent->BuildFOOTPRINTS_LISTBOX(); - m_Parent->BuildLIBRARY_LISTBOX(); - } - - wxCommandEvent evt( ID_SAVE_PROJECT ); - m_Parent->SaveProjectFile( evt ); - EndModal( wxID_OK ); -} - - -void DIALOG_CVPCB_CONFIG::OnCloseWindow( wxCloseEvent& event ) -{ - EndModal( 0 ); -} - - -/********************************************************************/ -void DIALOG_CVPCB_CONFIG::OnButtonUpClick( wxCommandEvent& event ) -/********************************************************************/ -{ - wxListBox * list = m_ListLibr; - - if( (event.GetId() == ID_EQU_UP) || (event.GetId() == ID_EQU_DOWN) ) - { - list = m_ListEquiv; - } - - wxArrayInt selections; - - list->GetSelections( selections ); - - if ( selections.GetCount() <= 0 ) // No selection. - return; - - if( selections[0] == 0 ) // The first lib is selected. cannot move up it - return; - - wxArrayString libnames = list->GetStrings(); - - for( size_t ii = 0; ii < selections.GetCount(); ii++ ) - { - int jj = selections[ii]; - EXCHG( libnames[jj], libnames[jj-1] ); - } - - list->Set( libnames ); - - // Reselect previously selected names - for( size_t ii = 0; ii < selections.GetCount(); ii++ ) - { - int jj = selections[ii]; - list->SetSelection( jj-1 ); - } - - m_LibListChanged = true; -} - - -/*********************************************************************/ -void DIALOG_CVPCB_CONFIG::OnButtonDownClick( wxCommandEvent& event ) -/*********************************************************************/ -{ - wxListBox * list = m_ListLibr; - - if( (event.GetId() == ID_EQU_UP) || (event.GetId() == ID_EQU_DOWN) ) - { - list = m_ListEquiv; - } - - wxArrayInt selections; - - list->GetSelections( selections ); - - if ( selections.GetCount() <= 0 ) // No selection. - return; - - // The last lib is selected. cannot move down it - if( selections.Last() == (int)(list->GetCount()-1) ) - return; - - wxArrayString libnames = list->GetStrings(); - - for( int ii = selections.GetCount()-1; ii >= 0; ii-- ) - { - int jj = selections[ii]; - EXCHG( libnames[jj], libnames[jj+1]); - } - - list->Set( libnames ); - - // Reselect previously selected names - for( size_t ii = 0; ii < selections.GetCount(); ii++ ) - { - int jj = selections[ii]; - list->SetSelection(jj+1); - } - - m_LibListChanged = true; -} - - -/* Remove a library to the library list. - * The real list (g_LibName_List) is not changed, so the change can be canceled - */ -void DIALOG_CVPCB_CONFIG::OnRemoveLibClick( wxCommandEvent& event ) -{ - wxListBox * list = m_ListEquiv; - - if( event.GetId() == ID_REMOVE_LIB ) - list = m_ListLibr; - - wxArrayInt selections; - - list->GetSelections( selections ); - - for( int ii = selections.GetCount()-1; ii >= 0; ii-- ) - { - list->Delete(selections[ii] ); - m_LibListChanged = true; - } -} - - -/* Insert or add a library to the library list: - * The new library is put in list before (insert button) the selection, - * or added (add button) to end of list - * The real list (g_LibName_List) is not changed, so the change can be canceled - */ -void DIALOG_CVPCB_CONFIG::OnAddOrInsertLibClick( wxCommandEvent& event ) -{ - int ii; - wxString libfilename, wildcard; - wxFileName fn; - - bool insert = false; - - if( (event.GetId() == ID_INSERT_EQU) || (event.GetId() == ID_INSERT_LIB) ) - insert = true; - - wildcard = FootprintAliasFileWildcard; - - wxListBox* list = m_ListEquiv; - - if( (event.GetId() == ID_ADD_LIB) || (event.GetId() == ID_INSERT_LIB) ) - { - list = m_ListLibr; - wildcard = LegacyFootprintLibPathWildcard; - } - - wxArrayInt selections; - list->GetSelections(selections); - - ii = selections.GetCount(); - - if( ii > 0 ) - ii = selections[0]; - else - ii = 0; - - wxString libpath; - libpath = m_DefaultLibraryPathslistBox->GetStringSelection(); - - if( libpath.IsEmpty() ) - libpath = Pgm().LastVisitedLibraryPath(); - - wxFileDialog FilesDialog( this, _( "Footprint library files:" ), libpath, - wxEmptyString, wildcard, - wxFD_DEFAULT_STYLE | wxFD_MULTIPLE ); - - if( FilesDialog.ShowModal() != wxID_OK ) - return; - - wxArrayString Filenames; - FilesDialog.GetPaths( Filenames ); - - for( unsigned jj = 0; jj < Filenames.GetCount(); jj++ ) - { - fn = Filenames[jj]; - - if( jj == 0 ) - Pgm().SaveLastVisitedLibraryPath( fn.GetPath() ); - - /* If the library path is already in the library search paths - * list, just add the library name to the list. Otherwise, add - * the library name with the full or relative path. - * the relative path, when possible is preferable, - * because it preserve use of default libraries paths, when the path - * is a sub path of these default paths - */ - libfilename = Pgm().FilenameWithRelativePathInSearchList( fn.GetFullPath() ); - - // Remove extension: - fn = libfilename; - fn.SetExt( wxEmptyString ); - libfilename = fn.GetFullPath(); - - // Add or insert new library name, if not already in list - if( list->FindString( libfilename, fn.IsCaseSensitive() ) == wxNOT_FOUND ) - { - m_LibListChanged = true; - - if( ! insert ) - list->Append( libfilename ); - else - list->Insert( libfilename, ii++ ); - } - else - { - wxString msg = wxT( "<" ) + libfilename + wxT( "> : " ) + - _( "Library already in use" ); - DisplayError( this, msg ); - } - } -} - - -void DIALOG_CVPCB_CONFIG::OnAddOrInsertPath( wxCommandEvent& event ) -{ - wxString path = Pgm().LastVisitedLibraryPath(); - - bool select = EDA_DirectorySelector( _( "Default Path for Libraries" ), - path, - wxDD_DEFAULT_STYLE, - this, - wxDefaultPosition ); - - if( !select ) - return; - - if( !wxFileName::DirExists( path ) ) // Should not occurs - return; - - // Add or insert path if not already in list - if( m_listUserPaths->FindString( path ) == wxNOT_FOUND ) - { - int ipos = m_listUserPaths->GetCount(); - - if( event.GetId() == ID_INSERT_PATH ) - { - if( ipos ) - ipos--; - - int jj = m_listUserPaths->GetSelection(); - - if( jj >= 0 ) - ipos = jj; - } - - // Ask the user if this is a relative path - int diag = wxMessageBox( _( "Use a relative path?" ), - _( "Path type" ), - wxYES_NO | wxICON_QUESTION, this ); - - if( diag == wxYES ) - { // Make it relative - wxFileName fn = path; - fn.MakeRelativeTo( wxT( "." ) ); - path = fn.GetPathWithSep() + fn.GetFullName(); - } - - m_listUserPaths->Insert( path, ipos ); - m_LibPathChanged = true; - Pgm().InsertLibraryPath( path, ipos + 1 ); - - // Display actual libraries paths: - wxPathList libpaths = Pgm().GetLibraryPathList(); - m_DefaultLibraryPathslistBox->Clear(); - - for( unsigned ii = 0; ii < libpaths.GetCount(); ii++ ) - { - m_DefaultLibraryPathslistBox->Append( libpaths[ii] ); - } - } - else - { - DisplayError( this, _( "Path already in use" ) ); - } - - Pgm().SaveLastVisitedLibraryPath( path ); -} - - -void DIALOG_CVPCB_CONFIG::OnRemoveUserPath( wxCommandEvent& event ) -{ - int ii = m_listUserPaths->GetSelection(); - - if( ii < 0 ) - ii = m_listUserPaths->GetCount() - 1; - - if( ii >= 0 ) - { - Pgm().RemoveLibraryPath( m_listUserPaths->GetStringSelection() ); - m_listUserPaths->Delete( ii ); - m_LibPathChanged = true; - } - - // Display actual libraries paths: - wxPathList libpaths = Pgm().GetLibraryPathList(); - m_DefaultLibraryPathslistBox->Clear(); - - for( unsigned ii = 0; ii < libpaths.GetCount(); ii++ ) - { - m_DefaultLibraryPathslistBox->Append( libpaths[ii] ); - } -} - - -void DIALOG_CVPCB_CONFIG::OnBrowseModDocFile( wxCommandEvent& event ) -{ - wxString FullFileName; - wxString docpath, filename; - - docpath = Pgm().LastVisitedLibraryPath( wxT( "doc" ) ); - - wxFileDialog FilesDialog( this, _( "Footprint document file:" ), docpath, - wxEmptyString, PdfFileWildcard, - wxFD_DEFAULT_STYLE | wxFD_FILE_MUST_EXIST ); - - if( FilesDialog.ShowModal() != wxID_OK ) - return; - - FullFileName = FilesDialog.GetPath(); - - /* If the path is already in the library search paths - * list, just add the library name to the list. Otherwise, add - * the library name with the full or relative path. - * the relative path, when possible is preferable, - * because it preserve use of default libraries paths, when the path is - * a sub path of these default paths - */ - wxFileName fn = FullFileName; - Pgm().SaveLastVisitedLibraryPath( fn.GetPath() ); - - filename = Pgm().FilenameWithRelativePathInSearchList( FullFileName ); - m_TextHelpModulesFileName->SetValue( filename ); -} diff --git a/cvpcb/dialogs/dialog_cvpcb_config.h.notused b/cvpcb/dialogs/dialog_cvpcb_config.h.notused deleted file mode 100644 index fa9b51794c..0000000000 --- a/cvpcb/dialogs/dialog_cvpcb_config.h.notused +++ /dev/null @@ -1,46 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// - -// Name: dialog_display_options.h -// Author: jean-pierre Charras -// Licence: GPL -///////////////////////////////////////////////////////////////////////////// - -#ifndef _DIALOG_CVPCB_CONFIG_H_ -#define _DIALOG_CVPCB_CONFIG_H_ - -#include - -class DIALOG_CVPCB_CONFIG : public DIALOG_CVPCB_CONFIG_FBP -{ -private: - CVPCB_MAINFRAME* m_Parent; - wxConfigBase* m_Config; - wxString m_UserLibDirBufferImg; - - bool m_LibListChanged; - bool m_LibPathChanged; - -private: - void Init(); - - // Virtual event handlers - void OnCloseWindow( wxCloseEvent& event ); - void OnOkClick( wxCommandEvent& event ); - void OnCancelClick( wxCommandEvent& event ); - void OnAddOrInsertLibClick( wxCommandEvent& event ); - void OnRemoveLibClick( wxCommandEvent& event ); - void OnBrowseModDocFile( wxCommandEvent& event ); - void OnAddOrInsertPath( wxCommandEvent& event ); - void OnRemoveUserPath( wxCommandEvent& event ); - void OnButtonUpClick( wxCommandEvent& event ); - void OnButtonDownClick( wxCommandEvent& event ); - - -public: - DIALOG_CVPCB_CONFIG( CVPCB_MAINFRAME* parent ); - ~DIALOG_CVPCB_CONFIG() {}; -}; - -#endif - -// _DIALOG_CVPCB_CONFIG_H_ diff --git a/cvpcb/dialogs/dialog_cvpcb_config_fbp.cpp.notused b/cvpcb/dialogs/dialog_cvpcb_config_fbp.cpp.notused deleted file mode 100644 index e9f5f62483..0000000000 --- a/cvpcb/dialogs/dialog_cvpcb_config_fbp.cpp.notused +++ /dev/null @@ -1,213 +0,0 @@ -/////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Apr 10 2012) -// http://www.wxformbuilder.org/ -// -// PLEASE DO "NOT" EDIT THIS FILE! -/////////////////////////////////////////////////////////////////////////// - -#include "dialog_cvpcb_config_fbp.h" - -/////////////////////////////////////////////////////////////////////////// - -DIALOG_CVPCB_CONFIG_FBP::DIALOG_CVPCB_CONFIG_FBP( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style ) -{ - this->SetSizeHints( wxDefaultSize, wxDefaultSize ); - - wxBoxSizer* bMainSizer; - bMainSizer = new wxBoxSizer( wxVERTICAL ); - - wxStaticBoxSizer* sbLibsChoiceSizer; - sbLibsChoiceSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Footprint library files") ), wxHORIZONTAL ); - - m_ListLibr = new wxListBox( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_EXTENDED|wxLB_HSCROLL|wxLB_NEEDED_SB|wxLB_SINGLE ); - m_ListLibr->SetToolTip( _("List of active library files.\nOnly library files in this list are loaded by Pcbnew.\nThe order of this list is important:\nPcbnew searchs for a given footprint using this list order priority.") ); - m_ListLibr->SetMinSize( wxSize( 450,90 ) ); - - sbLibsChoiceSizer->Add( m_ListLibr, 1, wxEXPAND|wxRIGHT|wxLEFT, 5 ); - - wxBoxSizer* bSizerLibButtons; - bSizerLibButtons = new wxBoxSizer( wxVERTICAL ); - - m_buttonAddLib = new wxButton( this, ID_ADD_LIB, _("Add"), wxDefaultPosition, wxDefaultSize, 0 ); - m_buttonAddLib->SetToolTip( _("Add a new library after the selected library, and load it") ); - - bSizerLibButtons->Add( m_buttonAddLib, 0, wxALIGN_CENTER_HORIZONTAL|wxLEFT|wxRIGHT, 5 ); - - m_buttonInsLib = new wxButton( this, ID_INSERT_LIB, _("Insert"), wxDefaultPosition, wxDefaultSize, 0 ); - m_buttonInsLib->SetToolTip( _("Add a new library before the selected library, and load it") ); - - bSizerLibButtons->Add( m_buttonInsLib, 0, wxALIGN_CENTER_HORIZONTAL|wxLEFT|wxRIGHT, 5 ); - - m_buttonRemoveLib = new wxButton( this, ID_REMOVE_LIB, _("Remove"), wxDefaultPosition, wxDefaultSize, 0 ); - m_buttonRemoveLib->SetToolTip( _("Unload the selected library") ); - - bSizerLibButtons->Add( m_buttonRemoveLib, 0, wxALIGN_CENTER_HORIZONTAL|wxLEFT|wxRIGHT, 5 ); - - m_buttonLibUp = new wxButton( this, ID_LIB_UP, _("Up"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizerLibButtons->Add( m_buttonLibUp, 0, wxRIGHT|wxLEFT, 5 ); - - m_buttonLibDown = new wxButton( this, ID_LIB_DOWN, _("Down"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizerLibButtons->Add( m_buttonLibDown, 0, wxRIGHT|wxLEFT, 5 ); - - - sbLibsChoiceSizer->Add( bSizerLibButtons, 0, wxALIGN_CENTER_VERTICAL, 5 ); - - - bMainSizer->Add( sbLibsChoiceSizer, 1, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 ); - - wxStaticBoxSizer* sbEquivChoiceSizer; - sbEquivChoiceSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Footprint alias files") ), wxHORIZONTAL ); - - m_ListEquiv = new wxListBox( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_EXTENDED|wxLB_HSCROLL|wxLB_NEEDED_SB|wxLB_SINGLE ); - m_ListEquiv->SetToolTip( _("List of active library files.\nOnly library files in this list are loaded by Pcbnew.\nThe order of this list is important:\nPcbnew searchs for a given footprint using this list order priority.") ); - m_ListEquiv->SetMinSize( wxSize( 400,-1 ) ); - - sbEquivChoiceSizer->Add( m_ListEquiv, 1, wxEXPAND|wxRIGHT|wxLEFT, 5 ); - - wxBoxSizer* bSizerEquButtons; - bSizerEquButtons = new wxBoxSizer( wxVERTICAL ); - - m_buttonAddEqu = new wxButton( this, ID_ADD_EQU, _("Add"), wxDefaultPosition, wxDefaultSize, 0 ); - m_buttonAddEqu->SetToolTip( _("Add a new library after the selected library, and load it") ); - - bSizerEquButtons->Add( m_buttonAddEqu, 0, wxALIGN_CENTER_HORIZONTAL|wxRIGHT|wxLEFT, 5 ); - - m_buttonInsEqu = new wxButton( this, ID_INSERT_EQU, _("Insert"), wxDefaultPosition, wxDefaultSize, 0 ); - m_buttonInsEqu->SetToolTip( _("Add a new library before the selected library, and load it") ); - - bSizerEquButtons->Add( m_buttonInsEqu, 0, wxALIGN_CENTER_HORIZONTAL|wxLEFT|wxRIGHT, 5 ); - - m_buttonRemoveEqu = new wxButton( this, ID_REMOVE_EQU, _("Remove"), wxDefaultPosition, wxDefaultSize, 0 ); - m_buttonRemoveEqu->SetToolTip( _("Unload the selected library") ); - - bSizerEquButtons->Add( m_buttonRemoveEqu, 0, wxALIGN_CENTER_HORIZONTAL|wxRIGHT|wxLEFT, 5 ); - - m_buttonEquUp = new wxButton( this, ID_EQU_UP, _("Up"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizerEquButtons->Add( m_buttonEquUp, 0, wxRIGHT|wxLEFT, 5 ); - - m_buttonEquDown = new wxButton( this, ID_EQU_DOWN, _("Down"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizerEquButtons->Add( m_buttonEquDown, 0, wxRIGHT|wxLEFT, 5 ); - - - sbEquivChoiceSizer->Add( bSizerEquButtons, 0, wxALIGN_CENTER_VERTICAL, 5 ); - - - bMainSizer->Add( sbEquivChoiceSizer, 1, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 ); - - wxStaticBoxSizer* sbModulesDocSizer; - sbModulesDocSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Footprint documentation file") ), wxHORIZONTAL ); - - m_TextHelpModulesFileName = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - sbModulesDocSizer->Add( m_TextHelpModulesFileName, 1, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - - m_buttonModDoc = new wxButton( this, ID_BROWSE_MOD_DOC, _("Browse"), wxDefaultPosition, wxDefaultSize, 0 ); - sbModulesDocSizer->Add( m_buttonModDoc, 0, wxRIGHT|wxLEFT, 5 ); - - - bMainSizer->Add( sbModulesDocSizer, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 ); - - wxStaticBoxSizer* sbSizer4; - sbSizer4 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("User defined search paths") ), wxHORIZONTAL ); - - wxBoxSizer* bUserListSizer; - bUserListSizer = new wxBoxSizer( wxVERTICAL ); - - m_listUserPaths = new wxListBox( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_NEEDED_SB ); - m_listUserPaths->SetToolTip( _("Additional paths used in this project. The priority is higher than default KiCad paths.") ); - m_listUserPaths->SetMinSize( wxSize( -1,70 ) ); - - bUserListSizer->Add( m_listUserPaths, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxRIGHT|wxLEFT, 5 ); - - - sbSizer4->Add( bUserListSizer, 1, wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 5 ); - - wxBoxSizer* bUserPathsButtonsSizer; - bUserPathsButtonsSizer = new wxBoxSizer( wxVERTICAL ); - - m_buttonAddPath = new wxButton( this, ID_LIB_PATH_SEL, _("Add"), wxDefaultPosition, wxDefaultSize, 0 ); - bUserPathsButtonsSizer->Add( m_buttonAddPath, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - - m_buttonInsPath = new wxButton( this, ID_INSERT_PATH, _("Insert"), wxDefaultPosition, wxDefaultSize, 0 ); - bUserPathsButtonsSizer->Add( m_buttonInsPath, 0, wxRIGHT|wxLEFT, 5 ); - - m_buttonRemovePath = new wxButton( this, ID_REMOVE_PATH, _("Remove"), wxDefaultPosition, wxDefaultSize, 0 ); - bUserPathsButtonsSizer->Add( m_buttonRemovePath, 0, wxRIGHT|wxLEFT, 5 ); - - - sbSizer4->Add( bUserPathsButtonsSizer, 0, wxALIGN_CENTER_VERTICAL, 5 ); - - - bMainSizer->Add( sbSizer4, 1, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 ); - - wxStaticBoxSizer* sbSizer6; - sbSizer6 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Current search path list") ), wxHORIZONTAL ); - - m_DefaultLibraryPathslistBox = new wxListBox( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_NEEDED_SB ); - m_DefaultLibraryPathslistBox->SetToolTip( _("System and user paths used to search and load library files and component doc files.\nSorted by decreasing priority order.") ); - m_DefaultLibraryPathslistBox->SetMinSize( wxSize( -1,70 ) ); - - sbSizer6->Add( m_DefaultLibraryPathslistBox, 1, wxEXPAND|wxRIGHT|wxLEFT, 5 ); - - - bMainSizer->Add( sbSizer6, 1, wxALL|wxEXPAND, 5 ); - - m_staticline2 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); - bMainSizer->Add( m_staticline2, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 ); - - m_sdbSizer2 = new wxStdDialogButtonSizer(); - m_sdbSizer2OK = new wxButton( this, wxID_OK ); - m_sdbSizer2->AddButton( m_sdbSizer2OK ); - m_sdbSizer2Cancel = new wxButton( this, wxID_CANCEL ); - m_sdbSizer2->AddButton( m_sdbSizer2Cancel ); - m_sdbSizer2->Realize(); - - bMainSizer->Add( m_sdbSizer2, 0, wxALL|wxEXPAND, 5 ); - - - this->SetSizer( bMainSizer ); - this->Layout(); - - this->Centre( wxBOTH ); - - // Connect Events - this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_CVPCB_CONFIG_FBP::OnCloseWindow ) ); - m_buttonAddLib->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CVPCB_CONFIG_FBP::OnAddOrInsertLibClick ), NULL, this ); - m_buttonInsLib->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CVPCB_CONFIG_FBP::OnAddOrInsertLibClick ), NULL, this ); - m_buttonRemoveLib->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CVPCB_CONFIG_FBP::OnRemoveLibClick ), NULL, this ); - m_buttonLibUp->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CVPCB_CONFIG_FBP::OnButtonUpClick ), NULL, this ); - m_buttonLibDown->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CVPCB_CONFIG_FBP::OnButtonDownClick ), NULL, this ); - m_buttonAddEqu->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CVPCB_CONFIG_FBP::OnAddOrInsertLibClick ), NULL, this ); - m_buttonInsEqu->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CVPCB_CONFIG_FBP::OnAddOrInsertLibClick ), NULL, this ); - m_buttonRemoveEqu->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CVPCB_CONFIG_FBP::OnRemoveLibClick ), NULL, this ); - m_buttonEquUp->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CVPCB_CONFIG_FBP::OnButtonUpClick ), NULL, this ); - m_buttonEquDown->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CVPCB_CONFIG_FBP::OnButtonDownClick ), NULL, this ); - m_buttonModDoc->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CVPCB_CONFIG_FBP::OnBrowseModDocFile ), NULL, this ); - m_buttonAddPath->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CVPCB_CONFIG_FBP::OnAddOrInsertPath ), NULL, this ); - m_buttonInsPath->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CVPCB_CONFIG_FBP::OnAddOrInsertPath ), NULL, this ); - m_buttonRemovePath->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CVPCB_CONFIG_FBP::OnRemoveUserPath ), NULL, this ); - m_sdbSizer2Cancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CVPCB_CONFIG_FBP::OnCancelClick ), NULL, this ); - m_sdbSizer2OK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CVPCB_CONFIG_FBP::OnOkClick ), NULL, this ); -} - -DIALOG_CVPCB_CONFIG_FBP::~DIALOG_CVPCB_CONFIG_FBP() -{ - // Disconnect Events - this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_CVPCB_CONFIG_FBP::OnCloseWindow ) ); - m_buttonAddLib->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CVPCB_CONFIG_FBP::OnAddOrInsertLibClick ), NULL, this ); - m_buttonInsLib->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CVPCB_CONFIG_FBP::OnAddOrInsertLibClick ), NULL, this ); - m_buttonRemoveLib->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CVPCB_CONFIG_FBP::OnRemoveLibClick ), NULL, this ); - m_buttonLibUp->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CVPCB_CONFIG_FBP::OnButtonUpClick ), NULL, this ); - m_buttonLibDown->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CVPCB_CONFIG_FBP::OnButtonDownClick ), NULL, this ); - m_buttonAddEqu->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CVPCB_CONFIG_FBP::OnAddOrInsertLibClick ), NULL, this ); - m_buttonInsEqu->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CVPCB_CONFIG_FBP::OnAddOrInsertLibClick ), NULL, this ); - m_buttonRemoveEqu->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CVPCB_CONFIG_FBP::OnRemoveLibClick ), NULL, this ); - m_buttonEquUp->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CVPCB_CONFIG_FBP::OnButtonUpClick ), NULL, this ); - m_buttonEquDown->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CVPCB_CONFIG_FBP::OnButtonDownClick ), NULL, this ); - m_buttonModDoc->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CVPCB_CONFIG_FBP::OnBrowseModDocFile ), NULL, this ); - m_buttonAddPath->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CVPCB_CONFIG_FBP::OnAddOrInsertPath ), NULL, this ); - m_buttonInsPath->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CVPCB_CONFIG_FBP::OnAddOrInsertPath ), NULL, this ); - m_buttonRemovePath->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CVPCB_CONFIG_FBP::OnRemoveUserPath ), NULL, this ); - m_sdbSizer2Cancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CVPCB_CONFIG_FBP::OnCancelClick ), NULL, this ); - m_sdbSizer2OK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CVPCB_CONFIG_FBP::OnOkClick ), NULL, this ); - -} diff --git a/cvpcb/dialogs/dialog_cvpcb_config_fbp.fbp.notused b/cvpcb/dialogs/dialog_cvpcb_config_fbp.fbp.notused deleted file mode 100644 index ac7554f5c0..0000000000 --- a/cvpcb/dialogs/dialog_cvpcb_config_fbp.fbp.notused +++ /dev/null @@ -1,1993 +0,0 @@ - - - - - - C++ - 1 - source_name - 0 - 0 - res - UTF-8 - connect - dialog_cvpcb_config_fbp - 1000 - none - 1 - dialog_cvpcb_config_fbp - - . - - 1 - 1 - 1 - 1 - 0 - - 0 - wxAUI_MGR_DEFAULT - - wxBOTH - - 1 - 1 - impl_virtual - - - - 0 - wxID_ANY - - - DIALOG_CVPCB_CONFIG_FBP - - 570,625 - wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER - DIALOG_SHIM; dialog_shim.h - - - - - - - - - - - - - - - OnCloseWindow - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bMainSizer - wxVERTICAL - none - - 5 - wxEXPAND|wxTOP|wxRIGHT|wxLEFT - 1 - - wxID_ANY - Footprint library files - - sbLibsChoiceSizer - wxHORIZONTAL - none - - - 5 - wxEXPAND|wxRIGHT|wxLEFT - 1 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - - 0 - -1,-1 - - 0 - 450,90 - 1 - m_ListLibr - 1 - - - protected - 1 - - Resizable - 1 - - wxLB_EXTENDED|wxLB_HSCROLL|wxLB_NEEDED_SB|wxLB_SINGLE - - 0 - List of active library files. Only library files in this list are loaded by Pcbnew. The order of this list is important: Pcbnew searchs for a given footprint using this list order priority. - - wxFILTER_NONE - wxDefaultValidator - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_VERTICAL - 0 - - - bSizerLibButtons - wxVERTICAL - none - - 5 - wxALIGN_CENTER_HORIZONTAL|wxLEFT|wxRIGHT - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - ID_ADD_LIB - Add - - 0 - - - 0 - - 1 - m_buttonAddLib - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - Add a new library after the selected library, and load it - - wxFILTER_NONE - wxDefaultValidator - - - - - OnAddOrInsertLibClick - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_HORIZONTAL|wxLEFT|wxRIGHT - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - ID_INSERT_LIB - Insert - - 0 - - - 0 - - 1 - m_buttonInsLib - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - Add a new library before the selected library, and load it - - wxFILTER_NONE - wxDefaultValidator - - - - - OnAddOrInsertLibClick - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_HORIZONTAL|wxLEFT|wxRIGHT - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - ID_REMOVE_LIB - Remove - - 0 - - - 0 - - 1 - m_buttonRemoveLib - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - Unload the selected library - - wxFILTER_NONE - wxDefaultValidator - - - - - OnRemoveLibClick - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxRIGHT|wxLEFT - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - ID_LIB_UP - Up - - 0 - - - 0 - - 1 - m_buttonLibUp - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - wxFILTER_NONE - wxDefaultValidator - - - - - OnButtonUpClick - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxRIGHT|wxLEFT - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - ID_LIB_DOWN - Down - - 0 - - - 0 - - 1 - m_buttonLibDown - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - wxFILTER_NONE - wxDefaultValidator - - - - - OnButtonDownClick - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxEXPAND|wxTOP|wxRIGHT|wxLEFT - 1 - - wxID_ANY - Footprint alias files - - sbEquivChoiceSizer - wxHORIZONTAL - none - - - 5 - wxEXPAND|wxRIGHT|wxLEFT - 1 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - - 0 - -1,-1 - - 0 - 400,-1 - 1 - m_ListEquiv - 1 - - - protected - 1 - - Resizable - 1 - - wxLB_EXTENDED|wxLB_HSCROLL|wxLB_NEEDED_SB|wxLB_SINGLE - - 0 - List of active library files. Only library files in this list are loaded by Pcbnew. The order of this list is important: Pcbnew searchs for a given footprint using this list order priority. - - wxFILTER_NONE - wxDefaultValidator - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_VERTICAL - 0 - - - bSizerEquButtons - wxVERTICAL - none - - 5 - wxALIGN_CENTER_HORIZONTAL|wxRIGHT|wxLEFT - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - ID_ADD_EQU - Add - - 0 - - - 0 - - 1 - m_buttonAddEqu - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - Add a new library after the selected library, and load it - - wxFILTER_NONE - wxDefaultValidator - - - - - OnAddOrInsertLibClick - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_HORIZONTAL|wxLEFT|wxRIGHT - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - ID_INSERT_EQU - Insert - - 0 - - - 0 - - 1 - m_buttonInsEqu - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - Add a new library before the selected library, and load it - - wxFILTER_NONE - wxDefaultValidator - - - - - OnAddOrInsertLibClick - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_HORIZONTAL|wxRIGHT|wxLEFT - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - ID_REMOVE_EQU - Remove - - 0 - - - 0 - - 1 - m_buttonRemoveEqu - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - Unload the selected library - - wxFILTER_NONE - wxDefaultValidator - - - - - OnRemoveLibClick - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxRIGHT|wxLEFT - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - ID_EQU_UP - Up - - 0 - - - 0 - - 1 - m_buttonEquUp - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - wxFILTER_NONE - wxDefaultValidator - - - - - OnButtonUpClick - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxRIGHT|wxLEFT - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - ID_EQU_DOWN - Down - - 0 - - - 0 - - 1 - m_buttonEquDown - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - wxFILTER_NONE - wxDefaultValidator - - - - - OnButtonDownClick - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxEXPAND|wxTOP|wxRIGHT|wxLEFT - 0 - - wxID_ANY - Footprint documentation file - - sbModulesDocSizer - wxHORIZONTAL - none - - - 5 - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT - 1 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - - 0 - - 0 - - 0 - - 1 - m_TextHelpModulesFileName - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - wxFILTER_NONE - wxDefaultValidator - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxRIGHT|wxLEFT - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - ID_BROWSE_MOD_DOC - Browse - - 0 - - - 0 - - 1 - m_buttonModDoc - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - wxFILTER_NONE - wxDefaultValidator - - - - - OnBrowseModDocFile - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxEXPAND|wxTOP|wxRIGHT|wxLEFT - 1 - - wxID_ANY - User defined search paths - - sbSizer4 - wxHORIZONTAL - none - - - 5 - wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND - 1 - - - bUserListSizer - wxVERTICAL - none - - 5 - wxALIGN_CENTER_VERTICAL|wxEXPAND|wxRIGHT|wxLEFT - 1 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - - 0 - -1,-1 - - 0 - -1,70 - 1 - m_listUserPaths - 1 - - - protected - 1 - - Resizable - 1 - - wxLB_NEEDED_SB - - 0 - Additional paths used in this project. The priority is higher than default KiCad paths. - - wxFILTER_NONE - wxDefaultValidator - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_VERTICAL - 0 - - - bUserPathsButtonsSizer - wxVERTICAL - none - - 5 - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - ID_LIB_PATH_SEL - Add - - 0 - - - 0 - - 1 - m_buttonAddPath - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - wxFILTER_NONE - wxDefaultValidator - - - - - OnAddOrInsertPath - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxRIGHT|wxLEFT - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - ID_INSERT_PATH - Insert - - 0 - - - 0 - - 1 - m_buttonInsPath - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - wxFILTER_NONE - wxDefaultValidator - - - - - OnAddOrInsertPath - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxRIGHT|wxLEFT - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - ID_REMOVE_PATH - Remove - - 0 - - - 0 - - 1 - m_buttonRemovePath - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - wxFILTER_NONE - wxDefaultValidator - - - - - OnRemoveUserPath - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxEXPAND - 1 - - wxID_ANY - Current search path list - - sbSizer6 - wxHORIZONTAL - none - - - 5 - wxEXPAND|wxRIGHT|wxLEFT - 1 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - - 0 - - - 0 - -1,70 - 1 - m_DefaultLibraryPathslistBox - 1 - - - protected - 1 - - Resizable - 1 - - wxLB_NEEDED_SB - - 0 - System and user paths used to search and load library files and component doc files. Sorted by decreasing priority order. - - wxFILTER_NONE - wxDefaultValidator - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxEXPAND|wxRIGHT|wxLEFT - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - - 0 - - - 0 - - 1 - m_staticline2 - 1 - - - protected - 1 - - Resizable - 1 - - wxLI_HORIZONTAL - - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxEXPAND - 0 - - 0 - 1 - 0 - 0 - 0 - 1 - 0 - 0 - - m_sdbSizer2 - protected - - OnCancelClick - - - - OnOkClick - - - - - - - - diff --git a/cvpcb/menubar.cpp b/cvpcb/menubar.cpp index 66b6b9a16c..6354e548d1 100644 --- a/cvpcb/menubar.cpp +++ b/cvpcb/menubar.cpp @@ -95,11 +95,11 @@ void CVPCB_MAINFRAME::ReCreateMenuBar() // Save the .cmp file AddMenuItem( filesMenu, wxID_SAVE, - _( "&Save\tCtrl+S" ), SAVE_HLP_MSG, KiBitmap( save_xpm ) ); + _( "&Save Cmp File\tCtrl+S" ), SAVE_HLP_MSG, KiBitmap( save_xpm ) ); // Save as the .cmp file AddMenuItem( filesMenu, wxID_SAVEAS, - _( "Save &As...\tCtrl+Shift+S" ), SAVE_AS_HLP_MSG, KiBitmap( save_xpm ) ); + _( "Save Cmp File &As...\tCtrl+Shift+S" ), SAVE_AS_HLP_MSG, KiBitmap( save_xpm ) ); // Separator filesMenu->AppendSeparator(); @@ -116,6 +116,12 @@ void CVPCB_MAINFRAME::ReCreateMenuBar() _( "Edit Li&brary Table" ), _( "Setup footprint libraries" ), KiBitmap( library_table_xpm ) ); + AddMenuItem( preferencesMenu, ID_CVPCB_EQUFILES_LIST_EDIT, + _( "Edit &Equ Files List" ), + _( "Setup equ files list (.equ files)\n" + "They are files which give the footprint name from the component value"), + KiBitmap( library_table_xpm ) ); + // Language submenu Pgm().AddMenuLanguageList( preferencesMenu ); @@ -134,11 +140,6 @@ void CVPCB_MAINFRAME::ReCreateMenuBar() _( "Save changes to the project configuration file" ), KiBitmap( save_setup_xpm ) ); - AddMenuItem( preferencesMenu, ID_SAVE_PROJECT_AS, - _( "&Save Project File As" ), - _( "Save changes to a new project configuration file" ), - KiBitmap( save_setup_xpm ) ); - // Menu Help: wxMenu* helpMenu = new wxMenu; diff --git a/cvpcb/readwrite_dlgs.cpp b/cvpcb/readwrite_dlgs.cpp index f1a9472271..8f0bc7dca8 100644 --- a/cvpcb/readwrite_dlgs.cpp +++ b/cvpcb/readwrite_dlgs.cpp @@ -5,7 +5,7 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras + * Copyright (C) 2015 Jean-Pierre Charras, jean-pierre.charras * Copyright (C) 2011 Wayne Stambaugh * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors. * @@ -385,8 +385,9 @@ int CVPCB_MAINFRAME::SaveCmpLinkFile( const wxString& aFullFileName ) } else { - wxFileDialog dlg( this, _( "Save Component Footprint Link File" ), wxEmptyString, - _( "Unnamed file" ), ComponentFileWildcard, wxFD_SAVE ); + wxFileDialog dlg( this, _( "Save Component Footprint Link File" ), + Prj().GetProjectPath(), + wxT( "noname" ), ComponentFileWildcard, wxFD_SAVE ); if( dlg.ShowModal() == wxID_CANCEL ) return -1; @@ -395,47 +396,13 @@ int CVPCB_MAINFRAME::SaveCmpLinkFile( const wxString& aFullFileName ) if( !fn.HasExt() ) fn.SetExt( ComponentFileExtension ); - -#if 0 // RHH 6-Jul-14: We did not auto generate the - // footprint table. And the dialog which does suppport editing does the saving. - // Besides, this is not the place to do this, it belies the name of this - // function. - - // Save the project specific footprint library table. - if( !Prj().PcbFootprintLibs()->IsEmpty( false ) ) - { - wxString fp_lib_tbl = Prj().FootprintLibTblName(); - - if( wxFileName::FileExists( fp_lib_tbl ) - && IsOK( this, _( "A footprint library table already exists in this path.\n\nDo " - "you want to overwrite it?" ) ) ) - { - try - { - Prj().PcbFootprintLibs()->Save( fp_lib_tbl ); - } - catch( const IO_ERROR& ioe ) - { - wxString msg = wxString::Format( _( - "An error occurred attempting to save the " - "footprint library table '%s'\n\n%s" ), - GetChars( fp_lib_tbl ), - GetChars( ioe.errorText ) - ); - DisplayError( this, msg ); - } - } - } -#endif - } - if( !IsWritable( fn.GetFullPath() ) ) - return 0; - - if( WriteComponentLinkFile( fn.GetFullPath() ) == 0 ) + if( !IsWritable( fn.GetFullPath() ) || WriteComponentLinkFile( fn.GetFullPath() ) == 0 ) { - DisplayError( this, _( "Unable to create component footprint link file (.cmp)" ) ); + DisplayError( this, + wxString::Format( _( "Unable to create component footprint link file '%s'" ), + fn.GetFullPath() ) ); return 0; } diff --git a/cvpcb/tool_cvpcb.cpp b/cvpcb/tool_cvpcb.cpp index 061601f7a8..e1a8f34ad9 100644 --- a/cvpcb/tool_cvpcb.cpp +++ b/cvpcb/tool_cvpcb.cpp @@ -69,10 +69,6 @@ void CVPCB_MAINFRAME::ReCreateHToolbar() KiBitmap( show_footprint_xpm ), _( "View selected footprint" ) ); - m_mainToolBar->AddTool( ID_CVPCB_AUTO_ASSOCIE, wxEmptyString, - KiBitmap( auto_associe_xpm ), - _( "Perform automatic footprint association" ) ); - m_mainToolBar->AddSeparator(); m_mainToolBar->AddTool( ID_CVPCB_GOTO_PREVIOUSNA, wxEmptyString, KiBitmap( left_xpm ), @@ -83,6 +79,10 @@ void CVPCB_MAINFRAME::ReCreateHToolbar() _( "Select next unlinked component" ) ); m_mainToolBar->AddSeparator(); + m_mainToolBar->AddTool( ID_CVPCB_AUTO_ASSOCIE, wxEmptyString, + KiBitmap( auto_associe_xpm ), + _( "Perform automatic footprint association" ) ); + m_mainToolBar->AddTool( ID_CVPCB_DEL_ASSOCIATIONS, wxEmptyString, KiBitmap( delete_association_xpm ), _( "Delete all associations (links)" ) ); @@ -92,7 +92,6 @@ void CVPCB_MAINFRAME::ReCreateHToolbar() KiBitmap( datasheet_xpm ), _( "Display footprint documentation" ) ); - m_mainToolBar->AddSeparator(); m_mainToolBar->AddSeparator(); m_mainToolBar->AddTool( ID_CVPCB_FOOTPRINT_DISPLAY_FILTERED_LIST, KiBitmap( module_filtered_list_xpm ), diff --git a/eeschema/cross-probing.cpp b/eeschema/cross-probing.cpp index 59697b5760..570226661c 100644 --- a/eeschema/cross-probing.cpp +++ b/eeschema/cross-probing.cpp @@ -62,6 +62,7 @@ void SCH_EDIT_FRAME::ExecuteRemoteCommand( const char* cmdline ) char line[1024]; strncpy( line, cmdline, sizeof(line) - 1 ); + line[ sizeof(line) - 1 ] = '\0'; char* idcmd = strtok( line, " \n\r" ); char* text = strtok( NULL, "\"\n\r" ); diff --git a/eeschema/dialogs/dialog_netlist.cpp b/eeschema/dialogs/dialog_netlist.cpp index 7528c0f942..a47f7f0df9 100644 --- a/eeschema/dialogs/dialog_netlist.cpp +++ b/eeschema/dialogs/dialog_netlist.cpp @@ -1,9 +1,9 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2013 Jean-Pierre Charras, jp.charras@wanadoo.fr - * Copyright (C) 2013 Wayne Stambaugh - * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2013-2015 Jean-Pierre Charras, jp.charras@wanadoo.fr + * Copyright (C) 2013-2015 Wayne Stambaugh + * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -342,6 +342,7 @@ NETLIST_DIALOG::NETLIST_DIALOG( SCH_EDIT_FRAME* parent ) : // Add custom panels: InstallCustomPages(); + SetDefaultItem( m_buttonNetlist ); GetSizer()->SetSizeHints( this ); Centre(); diff --git a/eeschema/libedit.cpp b/eeschema/libedit.cpp index f9ed0078dd..f474736d52 100644 --- a/eeschema/libedit.cpp +++ b/eeschema/libedit.cpp @@ -335,7 +335,7 @@ bool LIB_EDIT_FRAME::SaveActiveLibrary( bool newFile ) default_path = search->LastVisitedPath(); wxFileDialog dlg( this, _( "Part Library Name:" ), default_path, - wxEmptyString, SchematicLibraryFileExtension, + wxEmptyString, SchematicLibraryFileWildcard, wxFD_SAVE | wxFD_OVERWRITE_PROMPT ); if( dlg.ShowModal() == wxID_CANCEL ) diff --git a/eeschema/sch_text.cpp b/eeschema/sch_text.cpp index 139520ff93..3b1921dfb1 100644 --- a/eeschema/sch_text.cpp +++ b/eeschema/sch_text.cpp @@ -668,19 +668,18 @@ void SCH_TEXT::Plot( PLOTTER* aPlotter ) if( m_MultilineAllowed ) { std::vector positions; - wxArrayString* list = wxStringSplit( GetShownText(), '\n' ); - positions.reserve( list->Count() ); + wxArrayString strings_list; + wxStringSplit( GetShownText(), strings_list, '\n' ); + positions.reserve( strings_list.Count() ); - GetPositionsOfLinesOfMultilineText(positions, list->Count() ); + GetPositionsOfLinesOfMultilineText(positions, strings_list.Count() ); - for( unsigned ii = 0; ii < list->Count(); ii++ ) + for( unsigned ii = 0; ii < strings_list.Count(); ii++ ) { - wxString& txt = list->Item( ii ); + wxString& txt = strings_list.Item( ii ); aPlotter->Text( positions[ii], color, txt, m_Orient, m_Size, m_HJustify, m_VJustify, thickness, m_Italic, m_Bold ); } - - delete (list); } else { diff --git a/include/common.h b/include/common.h index 68cef30edb..ed663942e9 100644 --- a/include/common.h +++ b/include/common.h @@ -339,11 +339,11 @@ double RoundTo0( double x, double precision ); /** * Function wxStringSplit * splits \a aString to a string list separated at \a aSplitter. - * @return the list - * @param aString is the text to split + * @param aText is the text to split + * @param aStrings will contain the splitted lines * @param aSplitter is the 'split' character */ -wxArrayString* wxStringSplit( wxString aString, wxChar aSplitter ); +void wxStringSplit( const wxString& aText, wxArrayString& aStrings, wxChar aSplitter ); /** * Function GetRunningMicroSecs diff --git a/include/config_params.h b/include/config_params.h index f7ae973c6c..16cd089bab 100644 --- a/include/config_params.h +++ b/include/config_params.h @@ -47,7 +47,7 @@ #define GROUP_SCH_LIBS wxT( "/eeschema/libraries" ) /// library list section #define GROUP_CVP wxT("/cvpcb") -#define GROUP_CVP_EQU wxT("/cvpcb/libraries") +#define GROUP_CVP_EQU wxT("/cvpcb/equfiles") #define CONFIG_VERSION 1 diff --git a/pcb_calculator/dialogs/pcb_calculator_frame_base.cpp b/pcb_calculator/dialogs/pcb_calculator_frame_base.cpp index 412753b4a2..0c0496cfa6 100644 --- a/pcb_calculator/dialogs/pcb_calculator_frame_base.cpp +++ b/pcb_calculator/dialogs/pcb_calculator_frame_base.cpp @@ -247,7 +247,7 @@ PCB_CALCULATOR_FRAME_BASE::PCB_CALCULATOR_FRAME_BASE( wxWindow* parent, wxWindow m_panelRegulators->SetSizer( bSizerMainReg ); m_panelRegulators->Layout(); bSizerMainReg->Fit( m_panelRegulators ); - m_Notebook->AddPage( m_panelRegulators, _("Regulators"), true ); + m_Notebook->AddPage( m_panelRegulators, _("Regulators"), false ); m_panelTrackWidth = new wxPanel( m_Notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); wxBoxSizer* bSizerTrackWidth; bSizerTrackWidth = new wxBoxSizer( wxHORIZONTAL ); @@ -593,7 +593,7 @@ PCB_CALCULATOR_FRAME_BASE::PCB_CALCULATOR_FRAME_BASE( wxWindow* parent, wxWindow wxBoxSizer* bLeftSizer; bLeftSizer = new wxBoxSizer( wxVERTICAL ); - wxString m_TranslineSelectionChoices[] = { _("Microstrip Line"), _("Coplanar wave guide"), _("Grounded Coplanar wave guide"), _("Rectangular Waveguide"), _("Coaxial Line"), _("Coupled Microstrip Line"), _("Stripline"), _("Twisted Pair") }; + wxString m_TranslineSelectionChoices[] = { _("Microstrip Line"), _("Coplanar wave guide"), _("Coplanar wave guide with ground plane"), _("Rectangular Waveguide"), _("Coaxial Line"), _("Coupled Microstrip Line"), _("Stripline"), _("Twisted Pair") }; int m_TranslineSelectionNChoices = sizeof( m_TranslineSelectionChoices ) / sizeof( wxString ); m_TranslineSelection = new wxRadioBox( m_panelTransline, wxID_ANY, _("Transmission Line Type:"), wxDefaultPosition, wxDefaultSize, m_TranslineSelectionNChoices, m_TranslineSelectionChoices, 1, wxRA_SPECIFY_COLS ); m_TranslineSelection->SetSelection( 0 ); @@ -998,7 +998,7 @@ PCB_CALCULATOR_FRAME_BASE::PCB_CALCULATOR_FRAME_BASE( wxWindow* parent, wxWindow m_panelTransline->SetSizer( bSizeTransline ); m_panelTransline->Layout(); bSizeTransline->Fit( m_panelTransline ); - m_Notebook->AddPage( m_panelTransline, _("TransLine"), false ); + m_Notebook->AddPage( m_panelTransline, _("TransLine"), true ); m_panelAttenuators = new wxPanel( m_Notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); wxStaticBoxSizer* sbSizerAtt; sbSizerAtt = new wxStaticBoxSizer( new wxStaticBox( m_panelAttenuators, wxID_ANY, _("label") ), wxHORIZONTAL ); diff --git a/pcb_calculator/dialogs/pcb_calculator_frame_base.fbp b/pcb_calculator/dialogs/pcb_calculator_frame_base.fbp index 3b8123ad68..2ccc08de96 100644 --- a/pcb_calculator/dialogs/pcb_calculator_frame_base.fbp +++ b/pcb_calculator/dialogs/pcb_calculator_frame_base.fbp @@ -270,7 +270,7 @@ Regulators - 1 + 0 1 1 @@ -8181,7 +8181,7 @@ TransLine - 0 + 1 1 1 @@ -8288,7 +8288,7 @@ 1 0 - "Microstrip Line" "Coplanar wave guide" "Grounded Coplanar wave guide" "Rectangular Waveguide" "Coaxial Line" "Coupled Microstrip Line" "Stripline" "Twisted Pair" + "Microstrip Line" "Coplanar wave guide" "Coplanar wave guide with ground plane" "Rectangular Waveguide" "Coaxial Line" "Coupled Microstrip Line" "Stripline" "Twisted Pair" 1 1 diff --git a/pcbnew/board_items_to_polygon_shape_transform.cpp b/pcbnew/board_items_to_polygon_shape_transform.cpp index 67446d245c..74e290a505 100644 --- a/pcbnew/board_items_to_polygon_shape_transform.cpp +++ b/pcbnew/board_items_to_polygon_shape_transform.cpp @@ -403,22 +403,21 @@ void TEXTE_PCB::TransformShapeWithClearanceToPolygonSet( if( IsMultilineAllowed() ) { - wxArrayString* list = wxStringSplit( GetShownText(), '\n' ); + wxArrayString strings_list; + wxStringSplit( GetShownText(), strings_list, '\n' ); std::vector positions; - positions.reserve( list->Count() ); - GetPositionsOfLinesOfMultilineText( positions, list->Count() ); + positions.reserve( strings_list.Count() ); + GetPositionsOfLinesOfMultilineText( positions, strings_list.Count() ); - for( unsigned ii = 0; ii < list->Count(); ii++ ) + for( unsigned ii = 0; ii < strings_list.Count(); ii++ ) { - wxString txt = list->Item( ii ); + wxString txt = strings_list.Item( ii ); DrawGraphicText( NULL, NULL, positions[ii], color, txt, GetOrientation(), size, GetHorizJustify(), GetVertJustify(), GetThickness(), IsItalic(), true, addTextSegmToPoly ); } - - delete list; } else { diff --git a/pcbnew/dialogs/dialog_export_idf.cpp b/pcbnew/dialogs/dialog_export_idf.cpp index 9e3d14d8c0..b2631f677d 100644 --- a/pcbnew/dialogs/dialog_export_idf.cpp +++ b/pcbnew/dialogs/dialog_export_idf.cpp @@ -5,7 +5,7 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2013 Cirilo Bernardo + * Copyright (C) 2013-2015 Cirilo Bernardo * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -46,15 +46,6 @@ private: wxConfigBase* m_config; bool m_idfThouOpt; // remember last preference for units in THOU - void OnCancelClick( wxCommandEvent& event ) - { - EndModal( wxID_CANCEL ); - } - void OnOkClick( wxCommandEvent& event ) - { - EndModal( wxID_OK ); - } - public: DIALOG_EXPORT_IDF3( PCB_EDIT_FRAME* parent ) : DIALOG_EXPORT_IDF3_BASE( parent ) @@ -66,6 +57,11 @@ public: m_config->Read( OPTKEY_IDF_THOU, &m_idfThouOpt ); m_rbUnitSelection->SetSelection( m_idfThouOpt ? 1 : 0 ); + wxWindow* button = FindWindowByLabel( wxT( "OK" ) ); + + if( button ) + SetDefaultItem( button ); + GetSizer()->SetSizeHints( this ); Centre(); } @@ -112,9 +108,9 @@ void PCB_EDIT_FRAME::ExportToIDF3( wxCommandEvent& event ) wxString fullFilename = dlg.FilePicker()->GetPath(); - if ( !Export_IDF3( GetBoard(), fullFilename, thou ) ) + if( !Export_IDF3( GetBoard(), fullFilename, thou ) ) { - wxString msg = _("Unable to create ") + fullFilename; + wxString msg = _( "Unable to create " ) + fullFilename; wxMessageBox( msg ); return; } diff --git a/pcbnew/dialogs/dialog_export_idf_base.cpp b/pcbnew/dialogs/dialog_export_idf_base.cpp index 9282b37c21..ba8cbcab95 100644 --- a/pcbnew/dialogs/dialog_export_idf_base.cpp +++ b/pcbnew/dialogs/dialog_export_idf_base.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Nov 6 2013) +// C++ code generated with wxFormBuilder (version Jun 5 2014) // http://www.wxformbuilder.org/ // // PLEASE DO "NOT" EDIT THIS FILE! @@ -16,20 +16,22 @@ DIALOG_EXPORT_IDF3_BASE::DIALOG_EXPORT_IDF3_BASE( wxWindow* parent, wxWindowID i wxBoxSizer* bSizerIDFFile; bSizerIDFFile = new wxBoxSizer( wxVERTICAL ); - bSizerIDFFile->SetMinSize( wxSize( 500,-1 ) ); - m_txtBrdFile = new wxStaticText( this, wxID_ANY, _("IDF board file"), wxDefaultPosition, wxDefaultSize, 0 ); + m_txtBrdFile = new wxStaticText( this, wxID_ANY, _("File name:"), wxDefaultPosition, wxDefaultSize, 0 ); m_txtBrdFile->Wrap( -1 ); - bSizerIDFFile->Add( m_txtBrdFile, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); + bSizerIDFFile->Add( m_txtBrdFile, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxTOP, 5 ); m_filePickerIDF = new wxFilePickerCtrl( this, wxID_ANY, wxEmptyString, _("Select an IDF export filename"), wxT("*.emn"), wxDefaultPosition, wxSize( 450,-1 ), wxFLP_OVERWRITE_PROMPT|wxFLP_SAVE|wxFLP_USE_TEXTCTRL ); bSizerIDFFile->Add( m_filePickerIDF, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); wxString m_rbUnitSelectionChoices[] = { _("Millimeters"), _("Mils") }; int m_rbUnitSelectionNChoices = sizeof( m_rbUnitSelectionChoices ) / sizeof( wxString ); - m_rbUnitSelection = new wxRadioBox( this, wxID_ANY, _("IDF File Units"), wxDefaultPosition, wxDefaultSize, m_rbUnitSelectionNChoices, m_rbUnitSelectionChoices, 1, wxRA_SPECIFY_COLS ); + m_rbUnitSelection = new wxRadioBox( this, wxID_ANY, _("Units"), wxDefaultPosition, wxDefaultSize, m_rbUnitSelectionNChoices, m_rbUnitSelectionChoices, 1, wxRA_SPECIFY_COLS ); m_rbUnitSelection->SetSelection( 0 ); bSizerIDFFile->Add( m_rbUnitSelection, 0, wxALL, 5 ); + + bSizerIDFFile->Add( 0, 0, 1, 0, 5 ); + m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); bSizerIDFFile->Add( m_staticline1, 0, wxEXPAND | wxALL, 5 ); @@ -40,11 +42,12 @@ DIALOG_EXPORT_IDF3_BASE::DIALOG_EXPORT_IDF3_BASE( wxWindow* parent, wxWindowID i m_sdbSizer1->AddButton( m_sdbSizer1Cancel ); m_sdbSizer1->Realize(); - bSizerIDFFile->Add( m_sdbSizer1, 0, wxALIGN_RIGHT, 5 ); + bSizerIDFFile->Add( m_sdbSizer1, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 ); this->SetSizer( bSizerIDFFile ); this->Layout(); + bSizerIDFFile->Fit( this ); this->Centre( wxBOTH ); } diff --git a/pcbnew/dialogs/dialog_export_idf_base.fbp b/pcbnew/dialogs/dialog_export_idf_base.fbp index 964a8cc5e3..434d92339d 100644 --- a/pcbnew/dialogs/dialog_export_idf_base.fbp +++ b/pcbnew/dialogs/dialog_export_idf_base.fbp @@ -1,6 +1,6 @@ - + C++ @@ -44,7 +44,7 @@ DIALOG_EXPORT_IDF3_BASE - 424,191 + -1,-1 wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER DIALOG_SHIM; dialog_shim.h Export IDFv3 @@ -89,13 +89,13 @@ - 500,-1 + -1,-1 bSizerIDFFile wxVERTICAL none 5 - wxTOP|wxRIGHT|wxLEFT + wxBOTTOM|wxLEFT|wxRIGHT|wxTOP 0 1 @@ -125,7 +125,7 @@ 0 0 wxID_ANY - IDF board file + File name: 0 @@ -298,7 +298,7 @@ 0 0 wxID_ANY - IDF File Units + Units 1 0 @@ -355,6 +355,16 @@ + + 5 + + 1 + + 0 + protected + 0 + + 5 wxEXPAND | wxALL @@ -438,7 +448,7 @@ 5 - wxALIGN_RIGHT + wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT 0 0 diff --git a/pcbnew/dialogs/dialog_export_idf_base.h b/pcbnew/dialogs/dialog_export_idf_base.h index 722bfcad31..8a67803936 100644 --- a/pcbnew/dialogs/dialog_export_idf_base.h +++ b/pcbnew/dialogs/dialog_export_idf_base.h @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Nov 6 2013) +// C++ code generated with wxFormBuilder (version Jun 5 2014) // http://www.wxformbuilder.org/ // // PLEASE DO "NOT" EDIT THIS FILE! @@ -47,7 +47,7 @@ class DIALOG_EXPORT_IDF3_BASE : public DIALOG_SHIM public: - DIALOG_EXPORT_IDF3_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Export IDFv3"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 424,191 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); + DIALOG_EXPORT_IDF3_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Export IDFv3"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); ~DIALOG_EXPORT_IDF3_BASE(); }; diff --git a/pcbnew/dialogs/wizard_add_fplib.cpp b/pcbnew/dialogs/wizard_add_fplib.cpp index edbaaa5d57..04d15ff6c7 100644 --- a/pcbnew/dialogs/wizard_add_fplib.cpp +++ b/pcbnew/dialogs/wizard_add_fplib.cpp @@ -5,8 +5,8 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2014 Jean-Pierre Charras, jp.charras at wanadoo.fr - * Copyright (C) 1992-2014 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr + * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -49,10 +49,13 @@ #include #include +#include + #include #include #include #include // For PROJECT_VAR_NAME definition +#include // For KISYSMOD definition #include #include #include @@ -88,6 +91,9 @@ WIZARD_FPLIB_TABLE::WIZARD_FPLIB_TABLE( wxWindow* aParent, wxArrayString& aEnvVa m_buttonAddEV->Show( false ); m_buttonRemoveEV->Show( false ); +#ifndef BUILD_GITHUB_PLUGIN + m_buttonGithubLibList->Show( false ); +#endif // Gives a minimal size to the dialog, which allows displaying any page wxSize minsize; @@ -130,14 +136,18 @@ void WIZARD_FPLIB_TABLE::initDlg( wxArrayString& aEnvVariableList ) wxString msg; wxConfigBase* cfg = Pgm().CommonSettings(); - cfg->Read( KICAD_FPLIBS_URL_KEY, &msg ); cfg->Read( WIZARD_LAST_PLUGIN_KEY, &m_last_plugin_choice ); cfg->Read( WIZARD_LAST_PATHOPTION_KEY, &m_last_defaultpath_choice ); + cfg->Read( KICAD_FPLIBS_URL_KEY, &msg ); - if( msg.IsEmpty() ) - m_textCtrlGithubURL->SetValue( wxT( "http://github.com/KiCad/" ) ); - else - m_textCtrlGithubURL->SetValue( msg ); + if( msg.IsEmpty() ) // Give our current KiCad github URL + msg = wxT( "http://github.com/KiCad" ); + + // Be sure there is no trailing '/' at the end of the repo name + if( msg.EndsWith( wxT("/" ) ) ) + msg.RemoveLast(); + + m_textCtrlGithubURL->SetValue( msg ); // KIGITHUB is frequently used (examples in docs, and other place) // So add it if it not yet in list, but if it is defined as env var @@ -211,7 +221,7 @@ bool WIZARD_FPLIB_TABLE::ValidateOptions() // Warn the user when this is the case wxString msg; - if( GetSelectedEnvVarValue().IsEmpty() ) + if( getSelectedEnvVarValue().IsEmpty() ) { // PROJECT_PATH option cannot be used with empty local path if( m_rbPathManagement->GetSelection() == PROJECT_PATH ) @@ -225,7 +235,7 @@ bool WIZARD_FPLIB_TABLE::ValidateOptions() { wxMessageBox( wxString::Format( _("The default path defined by env var \"%s\" is empty.\nCannot use it"), - GetChars( GetSelectedEnvVar() ) ) ); + GetChars( getSelectedEnvVar() ) ) ); return false; } } @@ -234,7 +244,7 @@ bool WIZARD_FPLIB_TABLE::ValidateOptions() if( IsGithubPlugin() ) { // Github plugin cannot be used with local path; Need absolute path or valid URL - if( !GetSelectedEnvVarValue().Lower().StartsWith( "http" ) ) + if( !getSelectedEnvVarValue().Lower().StartsWith( "http" ) ) { msg = _("Github Plugin uses a valid Internet URL starting by http.\n" "Cannot be used as URL"); @@ -244,7 +254,7 @@ bool WIZARD_FPLIB_TABLE::ValidateOptions() } else { - if( GetSelectedEnvVarValue().Lower().StartsWith( "http" ) ) + if( getSelectedEnvVarValue().Lower().StartsWith( "http" ) ) { msg = _("This default path looks strange.\n" "Cannot be used for a file path"); @@ -267,6 +277,10 @@ void WIZARD_FPLIB_TABLE::OnPluginSelection( wxCommandEvent& event ) void WIZARD_FPLIB_TABLE::updateFromPlugingChoice() { + #ifdef BUILD_GITHUB_PLUGIN + m_buttonGithubLibList->Show( IsGithubPlugin() || IsKicadPlugin() ); + #endif + // update dialog options and widgets depending on a plugin choice // Project path has no sense for GITHUB_PLUGIN bool enablePrjPathOpt = not IsGithubPlugin(); @@ -293,7 +307,7 @@ void WIZARD_FPLIB_TABLE::updateFromPlugingChoice() { if( first_github_envvar < 0 ) force_absolute_path = true; - else if( !GetSelectedEnvVarValue().StartsWith( "http" ) ) + else if( !getSelectedEnvVarValue().StartsWith( "http" ) ) m_gridEnvironmentVariablesList->SelectRow( first_github_envvar ); } @@ -378,7 +392,7 @@ void WIZARD_FPLIB_TABLE::OnSelectEnvVarCell( wxGridEvent& event ) m_gridEnvironmentVariablesList->SelectRow( event.GetRow() ); } -wxString WIZARD_FPLIB_TABLE::GetSelectedEnvVar() +wxString WIZARD_FPLIB_TABLE::getSelectedEnvVar() { wxString envVar; wxArrayInt selectedRows = m_gridEnvironmentVariablesList->GetSelectedRows(); @@ -405,7 +419,7 @@ wxString WIZARD_FPLIB_TABLE::GetSelectedEnvVar() } -wxString WIZARD_FPLIB_TABLE::GetSelectedEnvVarValue() +wxString WIZARD_FPLIB_TABLE::getSelectedEnvVarValue() { wxString envVarValue; wxArrayInt selectedRows = m_gridEnvironmentVariablesList->GetSelectedRows(); @@ -454,7 +468,7 @@ void WIZARD_FPLIB_TABLE::OnPageChanging( wxWizardEvent& event ) if( ( m_rbPathManagement->GetSelection() != ABSOLUTE_PATH ) && ( IsGithubPlugin() ) ) { - wxURI uri( GetSelectedEnvVarValue() ); + wxURI uri( getSelectedEnvVarValue() ); // We cannot use wxURL to test the validity of the url, because // wxURL does not know https protocol we are using, and aways returns @@ -465,7 +479,7 @@ void WIZARD_FPLIB_TABLE::OnPageChanging( wxWizardEvent& event ) { wxMessageBox( wxString::Format( _("The URL defined by env var \"%s\" is an incorrect URL.\nCannot use it"), - GetChars( GetSelectedEnvVar() ) ) ); + GetChars( getSelectedEnvVar() ) ) ); event.Veto(); } } @@ -484,10 +498,12 @@ bool WIZARD_FPLIB_TABLE::setSecondPage() { case 0: // Kicad lib type m_currLibDescr = new LIB_DESCR_KICAD; + m_buttonGithubLibList->SetLabel( _("Download Github Libs") ); break; case 1: // Github lib type m_currLibDescr = new LIB_DESCR_GITHUB; + m_buttonGithubLibList->SetLabel( _("Github Libs List") ); break; case 2: // Legacy lib type @@ -503,6 +519,17 @@ bool WIZARD_FPLIB_TABLE::setSecondPage() break; } + if( IsGithubPlugin() ) + { +#ifdef KICAD_USE_WEBKIT + m_buttonAddLib->SetLabel( _("Add Libs with WebViewer") ); +#else + m_buttonAddLib->SetLabel( _("Add FP Library entry") ); +#endif + } + else + m_buttonAddLib->SetLabel( _("Add FP Libraries") ); + return m_currLibDescr!= NULL; } @@ -515,15 +542,15 @@ bool WIZARD_FPLIB_TABLE::setLastPage() // Init prms for the last wizard page { case ENV_VAR_PATH: // Choice = path relative env var case PROJECT_PATH: // Choice = path relative to the project - m_currLibDescr->m_EnvVarName = GetSelectedEnvVar(); - m_currLibDescr->m_DefaultPath = GetSelectedEnvVarValue(); + m_currLibDescr->m_EnvVarName = getSelectedEnvVar(); + m_currLibDescr->m_DefaultPath = getSelectedEnvVarValue(); m_currLibDescr->m_IsAbsolutePath = false; m_textOption->SetLabel( wxString::Format( wxT("%s (%s)"), m_rbPathManagement->GetStringSelection().GetData(), - GetSelectedEnvVar().GetData() ) ); + getSelectedEnvVar().GetData() ) ); - m_textPath->SetLabel( GetSelectedEnvVarValue() ); + m_textPath->SetLabel( getSelectedEnvVarValue() ); break; case ABSOLUTE_PATH: // Choice = absolute path @@ -548,7 +575,7 @@ void WIZARD_FPLIB_TABLE::OnAddFpLibs( wxCommandEvent& event ) if( m_currLibDescr->m_IsFile ) selectLibsFiles(); else if( m_currLibDescr->m_IsGitHub ) - selectLibsGithub(); + selectLibsGithubWithWebViewer(); else selectLibsFolders(); @@ -708,7 +735,7 @@ extern int RunWebViewer( wxWindow * aParent, const wxString& aUrlOnStart, wxArrayString* aUrlListSelection = NULL ); #endif -void WIZARD_FPLIB_TABLE::selectLibsGithub() // select a set of library on Github +void WIZARD_FPLIB_TABLE::selectLibsGithubWithWebViewer() // select a set of library on Github { // A string array to store the URLs selected from the web viewer: wxArrayString urls; @@ -722,16 +749,25 @@ void WIZARD_FPLIB_TABLE::selectLibsGithub() // select a set of library on Git #ifdef KICAD_USE_WEBKIT RunWebViewer( this, defaultURL, &urls ); #else - urls.Add( defaultURL + wxT("newlibname.pretty") ); + // If the Web Viewer is not available, just add a template + // to the fp lib table. + // The user have to edit it + urls.Add( defaultURL + wxT("/newlibname.pretty") ); #endif + installGithubLibsFromList( urls ); +} +void WIZARD_FPLIB_TABLE::installGithubLibsFromList( wxArrayString& aUrlList ) +{ + // add the libs found in aUrlList, after calculating a nickname and + // replacing the path by an env variable, if needed // Create the nickname: currently make it from the url wxArrayString filepaths; wxArrayString nicknames; - for( unsigned ii = 0; ii < urls.GetCount(); ii++ ) + for( unsigned ii = 0; ii < aUrlList.GetCount(); ii++ ) { - wxString urlstring( urls[ii] ); + wxString urlstring( aUrlList[ii] ); wxURI uri( urlstring ); @@ -746,19 +782,19 @@ void WIZARD_FPLIB_TABLE::selectLibsGithub() // select a set of library on Git if( m_currLibDescr->m_IsAbsolutePath || m_currLibDescr->m_DefaultPath.IsEmpty() ) { - filepaths.Add( urls[ii] ); // use the full URL + filepaths.Add( aUrlList[ii] ); // use the full URL } else { wxString shortURI; - if( urls[ii].Lower().StartsWith( + if( aUrlList[ii].Lower().StartsWith( m_currLibDescr->m_DefaultPath.Lower(), &shortURI ) ) { shortURI.Prepend( wxT("${") + m_currLibDescr->m_EnvVarName + wxT("}") ); filepaths.Add( shortURI ); } else // keep the full URL - filepaths.Add( urls[ii] ); // use the full URL + filepaths.Add( aUrlList[ii] ); // use the full URL } } @@ -784,3 +820,142 @@ void WIZARD_FPLIB_TABLE::OnRemoveFpLibs( wxCommandEvent& event ) m_gridFpListLibs->SelectRow( m_gridFpListLibs->GetGridCursorRow() ); } + +#ifdef BUILD_GITHUB_PLUGIN +#include <../github/github_getliblist.h> + +void WIZARD_FPLIB_TABLE::OnGithubLibsList( wxCommandEvent& event ) +{ + wxArrayString liblist; + getLibsListGithub( liblist ); + + if( liblist.GetCount() == 0 ) // No lib selected + return; + + if( IsKicadPlugin() ) + { + wxString msg; + + if( !downloadGithubLibsFromList( liblist, &msg ) ) + { + wxMessageBox( msg ); + return; + } + } + else + installGithubLibsFromList( liblist ); +} + +void WIZARD_FPLIB_TABLE::getLibsListGithub( wxArrayString& aList ) +{ + wxBeginBusyCursor(); + + // Be sure there is no trailing '/' at the end of the repo name + wxString git_url = m_textCtrlGithubURL->GetValue(); + if( git_url.EndsWith( wxT("/" ) ) ) + { + git_url.RemoveLast(); + m_textCtrlGithubURL->SetValue( git_url ); + } + + GITHUB_GETLIBLIST getter( git_url ); + + wxArrayString fullList; + getter.GetLibraryList( fullList ); + + wxEndBusyCursor(); + + wxArrayInt choices; + wxString msg( _( "Urls detected as footprint .pretty libraries.\n" + "Selected urls will be added to the current footprint library list" ) ); + + if( wxGetSelectedChoices( choices, msg, + _( "Footprint libraries" ), fullList, this ) <= 0 ) + return; + + // Add selected url in list + for( unsigned ii = 0; ii < choices.GetCount(); ii++ ) + { + wxString& url = fullList[choices[ii]]; + aList.Add( url ); + } +} + + +// Download the .pretty libraries found in aUrlLis and store them on disk +// in a master folder +bool WIZARD_FPLIB_TABLE::downloadGithubLibsFromList( wxArrayString& aUrlList, + wxString * aErrorMessage ) +{ + wxString masterFolder; + wxString default_path; + wxGetEnv( FP_LIB_TABLE::GlobalPathEnvVariableName(), &default_path ); + + masterFolder = wxDirSelector( _("Output Folder" ), + default_path, 0, wxDefaultPosition, this ); + + if( masterFolder.IsEmpty() ) // Aborted by user + { + if( aErrorMessage ) + *aErrorMessage = _( "Aborted" ); + + return false; + } + + if( !wxDirExists( masterFolder ) ) + { + if( aErrorMessage ) + aErrorMessage->Printf( _( "Folder '%s' does not exists" ), + GetChars( masterFolder ) ); + + return false; + } + + // Display a progress bar to show the downlaod state + wxProgressDialog pdlg( _("Download libraries"), wxEmptyString, aUrlList.GetCount() ); + + // Download libs: + for( unsigned ii = 0; ii < aUrlList.GetCount(); ii++ ) + { + wxString& libsrc_name = aUrlList[ii]; + wxString libdst_name; + + // Extract the lib name from the full URL: + wxURI url( libsrc_name ); + wxFileName fn( url.GetPath() ); + // Set our local path + fn.SetPath( masterFolder ); + libdst_name = fn.GetFullPath(); + + if( !wxDirExists( libdst_name ) ) + wxMkdir( libdst_name ); + + pdlg.Update( ii, libsrc_name); + + try + { + PLUGIN::RELEASER src( IO_MGR::PluginFind( IO_MGR::GITHUB ) ); + PLUGIN::RELEASER dst( IO_MGR::PluginFind( IO_MGR::KICAD ) ); + + wxArrayString footprints = src->FootprintEnumerate( libsrc_name ); + + for( unsigned i = 0; i < footprints.size(); ++i ) + { + std::auto_ptr m( src->FootprintLoad( libsrc_name, footprints[i] ) ); + dst->FootprintSave( libdst_name, m.get() ); + // m is deleted here by auto_ptr. + } + } + catch( const IO_ERROR& ioe ) + { + if( aErrorMessage ) + aErrorMessage->Printf( _("Error:\n'%s'\nwhile downloading library:\n'%s'"), + GetChars( ioe.errorText ), GetChars( libsrc_name ) ); + return false; + } + } + + return true; +} +#endif + diff --git a/pcbnew/dialogs/wizard_add_fplib.h b/pcbnew/dialogs/wizard_add_fplib.h index 0d9223967d..f7ad445dce 100644 --- a/pcbnew/dialogs/wizard_add_fplib.h +++ b/pcbnew/dialogs/wizard_add_fplib.h @@ -112,13 +112,38 @@ public: private: void initDlg( wxArrayString& aEnvVariableList ); - wxString GetSelectedEnvVar(); // return the selected env variable - wxString GetSelectedEnvVarValue(); // return the selected env variable value + wxString getSelectedEnvVar(); // return the selected env variable + wxString getSelectedEnvVarValue(); // return the selected env variable value bool setSecondPage(); // Init prms for the second wizard page bool setLastPage(); // Init prms for the last wizard page void selectLibsFiles(); // select a set of library files void selectLibsFolders(); // select a set of library folders - void selectLibsGithub(); // select a set of library on Github + + /** select a set of library on Github, using the Web viewer to explore + * the repos + */ + void selectLibsGithubWithWebViewer(); + + /** Get the list of .pretty libraries on Github, + * without using the viewer, from the lib list extracted from the KiCad repos + */ + void getLibsListGithub( wxArrayString& aList ); + + /** Helper function. + * add the .pretty libraries found in aUrlList, after calculating a nickname and + * replacing the path by an env variable, if allowed and possible + */ + void installGithubLibsFromList( wxArrayString& aUrlList ); + + /** + * Download the .pretty libraries found in aUrlLis and store them on disk + * in a master folder + * @return true if OK, false on error + * @param aUrlList is the list of Github .pretty libs to download + * @param aErrorMessage is a wxString pointer to store error messages if any. + */ + bool downloadGithubLibsFromList( wxArrayString& aUrlList, wxString * aErrorMessage = NULL ); + void updateFromPlugingChoice(); // update dialog options and widgets // depending on the plugin choice int GetEnvVarCount() // Get the number of rows in env var table @@ -136,6 +161,12 @@ private: return m_rbFpLibFormat->GetSelection() == GITHUB_PLUGIN; } + + bool IsKicadPlugin() // Helper funct, return true if + { // the Kicad plugin is the choice + return m_rbFpLibFormat->GetSelection() == KICAD_PLUGIN; + } + int HasGithubEnvVarCompatible(); // Return the first index to one env var // which defines a url compatible github // or -1 if not found @@ -156,6 +187,9 @@ private: void OnPathManagementSelection( wxCommandEvent& event ); void OnSelectEnvVarCell( wxGridEvent& event ); void OnPluginSelection( wxCommandEvent& event ); +#ifdef BUILD_GITHUB_PLUGIN + void OnGithubLibsList( wxCommandEvent& event ); +#endif bool ValidateOptions(); }; diff --git a/pcbnew/dialogs/wizard_add_fplib_base.cpp b/pcbnew/dialogs/wizard_add_fplib_base.cpp index 9789aeffdd..4253ee3ad4 100644 --- a/pcbnew/dialogs/wizard_add_fplib_base.cpp +++ b/pcbnew/dialogs/wizard_add_fplib_base.cpp @@ -200,6 +200,9 @@ WIZARD_FPLIB_TABLE_BASE::WIZARD_FPLIB_TABLE_BASE( wxWindow* parent, wxWindowID i wxBoxSizer* bSizer5; bSizer5 = new wxBoxSizer( wxHORIZONTAL ); + m_buttonGithubLibList = new wxButton( m_wizPage3, wxID_ANY, _("Github Libs List"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer5->Add( m_buttonGithubLibList, 0, wxALL, 5 ); + m_buttonAddLib = new wxButton( m_wizPage3, wxID_ANY, _("Add FP Libraries"), wxDefaultPosition, wxDefaultSize, 0 ); bSizer5->Add( m_buttonAddLib, 0, wxALL, 5 ); @@ -231,6 +234,7 @@ WIZARD_FPLIB_TABLE_BASE::WIZARD_FPLIB_TABLE_BASE( wxWindow* parent, wxWindowID i m_gridEnvironmentVariablesList->Connect( wxEVT_GRID_SELECT_CELL, wxGridEventHandler( WIZARD_FPLIB_TABLE_BASE::OnSelectEnvVarCell ), NULL, this ); m_buttonAddEV->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( WIZARD_FPLIB_TABLE_BASE::OnAddEVariable ), NULL, this ); m_buttonRemoveEV->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( WIZARD_FPLIB_TABLE_BASE::OnRemoveEVariable ), NULL, this ); + m_buttonGithubLibList->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( WIZARD_FPLIB_TABLE_BASE::OnGithubLibsList ), NULL, this ); m_buttonAddLib->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( WIZARD_FPLIB_TABLE_BASE::OnAddFpLibs ), NULL, this ); m_buttonRemoveLib->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( WIZARD_FPLIB_TABLE_BASE::OnRemoveFpLibs ), NULL, this ); } @@ -246,6 +250,7 @@ WIZARD_FPLIB_TABLE_BASE::~WIZARD_FPLIB_TABLE_BASE() m_gridEnvironmentVariablesList->Disconnect( wxEVT_GRID_SELECT_CELL, wxGridEventHandler( WIZARD_FPLIB_TABLE_BASE::OnSelectEnvVarCell ), NULL, this ); m_buttonAddEV->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( WIZARD_FPLIB_TABLE_BASE::OnAddEVariable ), NULL, this ); m_buttonRemoveEV->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( WIZARD_FPLIB_TABLE_BASE::OnRemoveEVariable ), NULL, this ); + m_buttonGithubLibList->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( WIZARD_FPLIB_TABLE_BASE::OnGithubLibsList ), NULL, this ); m_buttonAddLib->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( WIZARD_FPLIB_TABLE_BASE::OnAddFpLibs ), NULL, this ); m_buttonRemoveLib->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( WIZARD_FPLIB_TABLE_BASE::OnRemoveFpLibs ), NULL, this ); diff --git a/pcbnew/dialogs/wizard_add_fplib_base.fbp b/pcbnew/dialogs/wizard_add_fplib_base.fbp index afa601bc52..d8f2961131 100644 --- a/pcbnew/dialogs/wizard_add_fplib_base.fbp +++ b/pcbnew/dialogs/wizard_add_fplib_base.fbp @@ -1942,6 +1942,94 @@ bSizer5 wxHORIZONTAL none + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Github Libs List + + 0 + + + 0 + + 1 + m_buttonGithubLibList + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + OnGithubLibsList + + + + + + + + + + + + + + + + + + + + + + + + + 5 wxALL diff --git a/pcbnew/dialogs/wizard_add_fplib_base.h b/pcbnew/dialogs/wizard_add_fplib_base.h index 884ee29215..9edfa11a0f 100644 --- a/pcbnew/dialogs/wizard_add_fplib_base.h +++ b/pcbnew/dialogs/wizard_add_fplib_base.h @@ -61,6 +61,7 @@ class WIZARD_FPLIB_TABLE_BASE : public wxWizard wxStaticText* m_textPath; wxStaticText* m_staticText2; wxGrid* m_gridFpListLibs; + wxButton* m_buttonGithubLibList; wxButton* m_buttonAddLib; wxButton* m_buttonRemoveLib; @@ -73,6 +74,7 @@ class WIZARD_FPLIB_TABLE_BASE : public wxWizard virtual void OnSelectEnvVarCell( wxGridEvent& event ) { event.Skip(); } virtual void OnAddEVariable( wxCommandEvent& event ) { event.Skip(); } virtual void OnRemoveEVariable( wxCommandEvent& event ) { event.Skip(); } + virtual void OnGithubLibsList( wxCommandEvent& event ) { event.Skip(); } virtual void OnAddFpLibs( wxCommandEvent& event ) { event.Skip(); } virtual void OnRemoveFpLibs( wxCommandEvent& event ) { event.Skip(); } diff --git a/pcbnew/exporters/export_idf.cpp b/pcbnew/exporters/export_idf.cpp index 27149a4a8d..049aaed7db 100644 --- a/pcbnew/exporters/export_idf.cpp +++ b/pcbnew/exporters/export_idf.cpp @@ -378,7 +378,7 @@ static void idf_export_module( BOARD* aPcb, MODULE* aModule, IDF3_COMP_OUTLINE* outline; - outline = aIDFBoard.GetComponentOutline( modfile->GetShape3DName() ); + outline = aIDFBoard.GetComponentOutline( modfile->GetShape3DFullFilename() ); if( !outline ) throw( std::runtime_error( aIDFBoard.GetError() ) ); diff --git a/pcbnew/exporters/export_vrml.cpp b/pcbnew/exporters/export_vrml.cpp index d3186cbab1..2674a3cd2a 100644 --- a/pcbnew/exporters/export_vrml.cpp +++ b/pcbnew/exporters/export_vrml.cpp @@ -635,14 +635,15 @@ static void export_vrml_pcbtext( MODEL_VRML& aModel, TEXTE_PCB* text ) if( text->IsMultilineAllowed() ) { - wxArrayString* list = wxStringSplit( text->GetShownText(), '\n' ); + wxArrayString strings_list; + wxStringSplit( text->GetShownText(), strings_list, '\n' ); std::vector positions; - positions.reserve( list->Count() ); - text->GetPositionsOfLinesOfMultilineText( positions, list->Count() ); + positions.reserve( strings_list.Count() ); + text->GetPositionsOfLinesOfMultilineText( positions, strings_list.Count() ); - for( unsigned ii = 0; ii < list->Count(); ii++ ) + for( unsigned ii = 0; ii < strings_list.Count(); ii++ ) { - wxString txt = list->Item( ii ); + wxString& txt = strings_list.Item( ii ); DrawGraphicText( NULL, NULL, positions[ii], color, txt, text->GetOrientation(), size, text->GetHorizJustify(), text->GetVertJustify(), @@ -650,8 +651,6 @@ static void export_vrml_pcbtext( MODEL_VRML& aModel, TEXTE_PCB* text ) true, vrml_text_callback ); } - - delete (list); } else { diff --git a/pcbnew/github/CMakeLists.txt b/pcbnew/github/CMakeLists.txt index 48596231ae..8231c30e7e 100644 --- a/pcbnew/github/CMakeLists.txt +++ b/pcbnew/github/CMakeLists.txt @@ -51,7 +51,7 @@ set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-sign-compare -Wno-reorder -Wno-unused-variable -Wno-unused-function -Wno-strict-aliasing" ) set( GITHUB_PLUGIN_SRCS - github_plugin.cpp + github_plugin.cpp github_getliblist.cpp ) add_library( github_plugin STATIC ${GITHUB_PLUGIN_SRCS} ) diff --git a/pcbnew/github/github_getliblist.cpp b/pcbnew/github/github_getliblist.cpp new file mode 100644 index 0000000000..c892287e43 --- /dev/null +++ b/pcbnew/github/github_getliblist.cpp @@ -0,0 +1,196 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2015 Jean-Pierre Charras jp.charras at wanadoo.fr + * Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck + * Copyright (C) 2015 KiCad Developers, see CHANGELOG.TXT for contributors. + * + * 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, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + + +/* + * While creating a wizard to edit the fp lib tables, and mainly the web viewer + * which can read the list of pretty library on a github repos, I was told there is + * this URL to retrieve info from any particular repo: + * + * https://api.github.com/orgs/KiCad/repos + * or + * https://api.github.com/users/KiCad/repos + * + * This gets just information on the repo in JSON format. + * + * I used avhttp, already used in the pcbnew Github plugin to download + * the json file. + * + * JP Charras. + */ + + +#if 0 +/* + * FIX ME + * I do not include avhttp.hpp here, because it is already included in + * github_plugin.cpp + * and if it is also included in this file, the link fails (double definiton of modules) + * therefore, the GITHUB_GETLIBLIST method which uses avhttp to download dats from gitub + * is in github_plugin.cpp + */ + +#ifndef WIN32_LEAN_AND_MEAN +// when WIN32_LEAN_AND_MEAN is defined, some useless includes in +// are skipped, and this avoid some compil issues +#define WIN32_LEAN_AND_MEAN +#endif + +#ifdef WIN32 +// defines needed by avhttp +// Minimal Windows version is XP: Google for _WIN32_WINNT + #define _WIN32_WINNT 0x0501 + #define WINVER 0x0501 +#endif + +#include +#include + +#endif + +#include + +#include +#include +#include + + +GITHUB_GETLIBLIST::GITHUB_GETLIBLIST( const wxString& aRepoURL ) +{ + m_repoURL = aRepoURL; +} + + +bool GITHUB_GETLIBLIST::GetLibraryList( wxArrayString& aList ) +{ + std::string fullURLCommand; + int page = 1; + int itemCountMax = 99; // Do not use a valu > 100, it does not work + + // Github max items returned is 100 per page + + if( !repoURL2listURL( m_repoURL, &fullURLCommand, itemCountMax, page ) ) + { + wxString msg = wxString::Format( _( "malformed URL:\n'%s'" ), GetChars( m_repoURL ) ); + wxMessageBox( msg ); + return false; + } + + // The URL lib names are relative to the server name. + // so add the server name to them. + wxURI repo( m_repoURL ); + wxString urlPrefix = wxT( "https://" ) + repo.GetServer() + wxT( "/" );; + + wxString errorMsg; + const char sep = ','; // Separator fields, in json returned file + wxString tmp; + int items_count_per_page = 0; + + while( 1 ) + { + bool success = remote_get_json( &fullURLCommand, &errorMsg ); + + if( !success ) + { + wxMessageBox( errorMsg ); + return false; + } + + for( unsigned ii = 0; ii < m_json_image.size(); ii++ ) + { + if( m_json_image[ii] == sep || ii == m_json_image.size() - 1 ) + { + if( tmp.StartsWith( wxT( "\"full_name\"" ) ) ) + { + #define QUOTE '\"' + // Remove useless quotes: + if( tmp[tmp.Length() - 1] == QUOTE ) + tmp.RemoveLast(); + + if( tmp.EndsWith( wxT( ".pretty" ) ) ) + { + aList.Add( tmp.AfterLast( ':' ) ); + int idx = aList.GetCount() - 1; + + if( aList[idx][0] == QUOTE ) + aList[idx].Remove( 0, 1 ); + + aList[idx].Prepend( urlPrefix ); + } + + items_count_per_page++; + } + + tmp.Clear(); + } + else + tmp << m_json_image[ii]; + } + + if( items_count_per_page >= itemCountMax ) + { + page++; + repoURL2listURL( m_repoURL, &fullURLCommand, itemCountMax, page ); + items_count_per_page = 0; + m_json_image.clear(); + } + else + break; + } + + aList.Sort(); + return true; +} + + +bool GITHUB_GETLIBLIST::repoURL2listURL( const wxString& aRepoURL, + std::string* aFullURLCommand, + int aItemCountMax, int aPage ) +{ + // aListURL is e.g. "https://api.github.com/orgs/KiCad/repos" + // or "https://api.github.com/users/KiCad/repos" + // aRepoURL is e.g. "https://github.com/KiCad" + // Github has a default pagination set to 30 items. + // but allows up to 100 items max if we add the "?per_page=100" option + + wxURI repo( aRepoURL ); + + if( repo.HasServer() && repo.HasPath() ) + { + // goal: "https://api.github.com/orgs/KiCad" + wxString target_url( wxT( "https://api.github.com/orgs" ) ); + target_url += repo.GetPath(); + target_url += wxT( "/repos" ); + + // Github has a default pagination set to 30 items. + // but allows up to 100 items max. Use this limit + target_url += wxString::Format( "?per_page=%d&page=%d", aItemCountMax, aPage ); + + *aFullURLCommand = target_url.utf8_str(); + return true; + } + + return false; +} diff --git a/pcbnew/github/github_getliblist.h b/pcbnew/github/github_getliblist.h new file mode 100644 index 0000000000..17daa53396 --- /dev/null +++ b/pcbnew/github/github_getliblist.h @@ -0,0 +1,83 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2015 Jean-Pierre Charras jp.charras at wanadoo.fr + * Copyright (C) 2015 KiCad Developers, see CHANGELOG.TXT for contributors. + * + * 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, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef GITHUB_GETLIBLIST_H_ +#define GITHUB_GETLIBLIST_H_ + + +/** + * Class GITHUB_GETLIBLIST + * implements a portion of pcbnew's PLUGIN interface to provide read only access + * to a github repo to extract pretty footprints library list, in json format. + * + * this plugin simply reads in a zip file of the repo and unzips it from RAM as + * needed. Therefore this "Github" plugin is read only for accessing remote + * at https://api.github.com/orgs/KiCad/repos + */ +class GITHUB_GETLIBLIST +{ +public: + // --------------------------------------------------------------- + bool GetLibraryList( wxArrayString& aList ); + + // -------------------------------------------------------------- + + GITHUB_GETLIBLIST( const wxString& aRepoURL ); + ~GITHUB_GETLIBLIST() {} + +protected: + + /** + * Function repoURL2listURL + * translates a repo URL to the URL name which gives the state of repos URL + * as commonly seen on github.com + * + * @param aRepoURL points to the base of the repo. + * @param aFullURLCommand is URL the full URL command (URL+options). + * @param aItemCountMax is the max item count in apage, + * and is 100 for github repo. + * @param aPage is the page number, if there are more than one page in repo. + * @return bool - true if @a aRepoULR was parseable, else false + */ + bool repoURL2listURL( const wxString& aRepoURL, std::string* aFullURLCommand, + int aItemCountMax, int aPage = 1 ); + + /** + * Function remote_get_json + * Download a json text from a github repo. The text image + * is received into the m_input_stream. + * @param aFullURLCommand the full command, i.e. the url with options like + * "https://api.github.com/users/KiCad/repos?per_page=100?page=1" + * @param aMsgError a pointer to a wxString which can store an error message + * @return true if OK, false if error (which an error message in *aMsgError + */ + bool remote_get_json( std::string* aFullURLCommand, wxString* aMsgError ); + + wxString m_github_path; ///< Something like https://api.github.com/orgs/KiCad + std::string m_json_image; ///< image of the text file in its entirety. + wxString m_repoURL; // the URL of the Github repo +}; + + +#endif // GITHUB_GETLIBLIST_H_ diff --git a/pcbnew/github/github_plugin.cpp b/pcbnew/github/github_plugin.cpp index 4b2f6946eb..4f86c13d5a 100644 --- a/pcbnew/github/github_plugin.cpp +++ b/pcbnew/github/github_plugin.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck - * Copyright (C) 2013 KiCad Developers, see CHANGELOG.TXT for contributors. + * Copyright (C) 2015 KiCad Developers, see CHANGELOG.TXT for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -101,6 +101,7 @@ Vary: Accept-Encoding #include #include #include // ExpandSubstitutions() +#include using namespace std; @@ -549,6 +550,57 @@ void GITHUB_PLUGIN::remote_get_zip( const wxString& aRepoURL ) throw( IO_ERROR ) } } +// This GITHUB_GETLIBLIST method should not be here, but in github_getliblist.cpp! +// However it is here just because we need to include to compile it. +// and if we include avhttp in 2 .cpp files, the link fails becuse it detects duplicate +// avhttp functions. +// So until it is fixed, this code is here. +bool GITHUB_GETLIBLIST::remote_get_json( std::string* aFullURLCommand, wxString* aMsgError ) +{ + boost::asio::io_service io; + avhttp::http_stream h( io ); + avhttp::request_opts options; + + options.insert( "Accept", "application/json" ); + options.insert( "User-Agent", "http://kicad-pcb.org" ); // THAT WOULD BE ME. + h.request_options( options ); + + try + { + std::ostringstream os; + + h.open( *aFullURLCommand ); // only one file, therefore do it synchronously. + os << &h; + + // Keep json text file image in RAM. + m_json_image = os.str(); + + // 4 lines, using SSL, top that. + } + catch( boost::system::system_error& e ) + { + // https "GET" has faild, report this to API caller. + static const char errorcmd[] = "https GET command failed"; // Do not translate this message + + UTF8 fmt( _( "%s\nCannot get/download json data from: '%s'\nReason: '%s'" ) ); + + std::string msg = StrPrintf( fmt.c_str(), + errorcmd, + // Report secret list_url to user. The secret + // list_url may go bad at some point in future if github changes + // their server architecture. Then fix repoURL_zipURL() to reflect + // new architecture. + aFullURLCommand->c_str(), e.what() ); + + if( aMsgError ) + { + *aMsgError = msg; + return false; + } + } + + return true; +} #if 0 && defined(STANDALONE) diff --git a/pcbnew/plot_brditems_plotter.cpp b/pcbnew/plot_brditems_plotter.cpp index eeb2d1ebbd..7dd42a2f06 100644 --- a/pcbnew/plot_brditems_plotter.cpp +++ b/pcbnew/plot_brditems_plotter.cpp @@ -469,20 +469,19 @@ void BRDITEMS_PLOTTER::PlotTextePcb( TEXTE_PCB* pt_texte ) if( pt_texte->IsMultilineAllowed() ) { std::vector positions; - wxArrayString* list = wxStringSplit( shownText, '\n' ); - positions.reserve( list->Count() ); + wxArrayString strings_list; + wxStringSplit( shownText, strings_list, '\n' ); + positions.reserve( strings_list.Count() ); - pt_texte->GetPositionsOfLinesOfMultilineText( positions, list->Count() ); + pt_texte->GetPositionsOfLinesOfMultilineText( positions, strings_list.Count() ); - for( unsigned ii = 0; ii < list->Count(); ii++ ) + for( unsigned ii = 0; ii < strings_list.Count(); ii++ ) { - wxString& txt = list->Item( ii ); + wxString& txt = strings_list.Item( ii ); m_plotter->Text( positions[ii], UNSPECIFIED_COLOR, txt, orient, size, pt_texte->GetHorizJustify(), pt_texte->GetVertJustify(), thickness, pt_texte->IsItalic(), allow_bold ); } - - delete list; } else { diff --git a/pcbnew/tools/edit_constraints.cpp b/pcbnew/tools/edit_constraints.cpp index f0edf9bc8b..f50dc0e596 100644 --- a/pcbnew/tools/edit_constraints.cpp +++ b/pcbnew/tools/edit_constraints.cpp @@ -98,8 +98,8 @@ EC_CONVERGING::EC_CONVERGING( EDIT_LINE& aLine, EDIT_POINTS& aPoints ) : EDIT_POINT& end = aLine.GetEnd(); // Previous and next points, to make constraining lines (adjacent to the dragged line) - EDIT_POINT& prevOrigin = *aPoints.Previous( origin ); - EDIT_POINT& nextEnd = *aPoints.Next( end ); + EDIT_POINT& prevOrigin = *aPoints.Previous( origin, false ); + EDIT_POINT& nextEnd = *aPoints.Next( end, false ); // Constraints for segments adjacent to the dragged one m_originSideConstraint = new EC_LINE( origin, prevOrigin ); @@ -147,8 +147,8 @@ void EC_CONVERGING::Apply( EDIT_LINE& aHandle ) m_originSideConstraint->Apply(); m_endSideConstraint->Apply(); - EDIT_POINT& prevOrigin = *m_editPoints.Previous( origin ); - EDIT_POINT& nextEnd = *m_editPoints.Next( end ); + EDIT_POINT& prevOrigin = *m_editPoints.Previous( origin, false ); + EDIT_POINT& nextEnd = *m_editPoints.Next( end, false ); // Two segments adjacent to the dragged segment SEG originSide = SEG( origin.GetPosition(), prevOrigin.GetPosition() ); diff --git a/pcbnew/tools/edit_points.cpp b/pcbnew/tools/edit_points.cpp index 1c24722862..9b6e7625b1 100644 --- a/pcbnew/tools/edit_points.cpp +++ b/pcbnew/tools/edit_points.cpp @@ -60,22 +60,86 @@ EDIT_POINT* EDIT_POINTS::FindPoint( const VECTOR2I& aLocation ) std::deque::iterator lit, litEnd; for( lit = m_lines.begin(), litEnd = m_lines.end(); lit != litEnd; ++lit ) { - EDIT_LINE& point = *lit; + EDIT_LINE& line = *lit; - if( point.WithinPoint( aLocation, size ) ) - return &point; + if( line.WithinPoint( aLocation, size ) ) + return &line; } return NULL; } -EDIT_POINT* EDIT_POINTS::Previous( const EDIT_POINT& aPoint ) +int EDIT_POINTS::GetContourStartIdx( int aPointIdx ) const +{ + int lastIdx = 0; + + BOOST_FOREACH( int idx, m_contours ) + { + if( idx >= aPointIdx ) + return lastIdx; + + lastIdx = idx + 1; + } + + return lastIdx; +} + + +int EDIT_POINTS::GetContourEndIdx( int aPointIdx ) const +{ + BOOST_FOREACH( int idx, m_contours ) + { + if( idx >= aPointIdx ) + return idx; + } + + return m_points.size() - 1; +} + + +bool EDIT_POINTS::IsContourStart( int aPointIdx ) const +{ + BOOST_FOREACH( int idx, m_contours ) + { + if( idx + 1 == aPointIdx ) + return true; + + // the list is sorted, so we cannot expect it any further + if( idx > aPointIdx ) + break; + } + + return ( aPointIdx == 0 ); +} + + +bool EDIT_POINTS::IsContourEnd( int aPointIdx ) const +{ + BOOST_FOREACH( int idx, m_contours ) + { + if( idx == aPointIdx ) + return true; + + // the list is sorted, so we cannot expect it any further + if( idx > aPointIdx ) + break; + } + + // the end of the list surely is the end of a contour + return ( aPointIdx == (int) m_points.size() - 1 ); +} + + +EDIT_POINT* EDIT_POINTS::Previous( const EDIT_POINT& aPoint, bool aTraverseContours ) { for( unsigned int i = 0; i < m_points.size(); ++i ) { if( m_points[i] == aPoint ) { + if( !aTraverseContours && IsContourStart( i ) ) + return &m_points[GetContourEndIdx( i )]; + if( i == 0 ) return &m_points[m_points.size() - 1]; else @@ -104,12 +168,15 @@ EDIT_LINE* EDIT_POINTS::Previous( const EDIT_LINE& aLine ) } -EDIT_POINT* EDIT_POINTS::Next( const EDIT_POINT& aPoint ) +EDIT_POINT* EDIT_POINTS::Next( const EDIT_POINT& aPoint, bool aTraverseContours ) { for( unsigned int i = 0; i < m_points.size(); ++i ) { if( m_points[i] == aPoint ) { + if( !aTraverseContours && IsContourEnd( i ) ) + return &m_points[GetContourStartIdx( i )]; + if( i == m_points.size() - 1 ) return &m_points[0]; else @@ -152,7 +219,9 @@ void EDIT_POINTS::ViewDraw( int aLayer, KIGFX::GAL* aGal ) const aGal->DrawRectangle( point.GetPosition() - size / 2, point.GetPosition() + size / 2 ); BOOST_FOREACH( const EDIT_LINE& line, m_lines ) + { aGal->DrawCircle( line.GetPosition(), size / 2 ); + } aGal->PopDepth(); } diff --git a/pcbnew/tools/edit_points.h b/pcbnew/tools/edit_points.h index b06ec30975..99b0efcc36 100644 --- a/pcbnew/tools/edit_points.h +++ b/pcbnew/tools/edit_points.h @@ -243,7 +243,6 @@ public: return m_constraint.get(); } - /** * Function GetOrigin() * @@ -371,16 +370,65 @@ public: m_lines.push_back( EDIT_LINE( aOrigin, aEnd ) ); } + /** + * Function AddBreak() + * + * Adds a break, indicating the end of a contour. + */ + void AddBreak() + { + assert( m_points.size() > 0 ); + m_contours.push_back( m_points.size() - 1 ); + } + + /** + * Function GetContourStartIdx() + * + * Returns index of the contour origin for a point with given index. + * @param aPointIdx is the index of point for which the contour origin is searched. + * @return Index of the contour origin point. + */ + int GetContourStartIdx( int aPointIdx ) const; + + /** + * Function GetContourEndIdx() + * + * Returns index of the contour finish for a point with given index. + * @param aPointIdx is the index of point for which the contour finish is searched. + * @return Index of the contour finish point. + */ + int GetContourEndIdx( int aPointIdx ) const; + + /** + * Function IsContourStart() + * + * Checks is a point with given index is a contour origin. + * @param aPointIdx is the index of the point to be checked. + * @return True if the point is an origin of a contour. + */ + bool IsContourStart( int aPointIdx ) const; + + /** + * Function IsContourEnd() + * + * Checks is a point with given index is a contour finish. + * @param aPointIdx is the index of the point to be checked. + * @return True if the point is a finish of a contour. + */ + bool IsContourEnd( int aPointIdx ) const; + /** * Function Previous() * * Returns the point that is after the given point in the list. * @param aPoint is the point that is supposed to be preceding the searched point. + * @param aTraverseContours decides if in case of breaks should we return to the origin + * of contour or continue with the next contour. * @return The point following aPoint in the list. If aPoint is the first in * the list, the last from the list will be returned. If there are no points at all, NULL * is returned. */ - EDIT_POINT* Previous( const EDIT_POINT& aPoint ); + EDIT_POINT* Previous( const EDIT_POINT& aPoint, bool aTraverseContours = true ); EDIT_LINE* Previous( const EDIT_LINE& aLine ); @@ -389,11 +437,13 @@ public: * * Returns the point that is before the given point in the list. * @param aPoint is the point that is supposed to be following the searched point. + * @param aTraverseContours decides if in case of breaks should we return to the origin + * of contour or continue with the next contour. * @return The point preceding aPoint in the list. If aPoint is the last in * the list, the first point from the list will be returned. If there are no points at all, * NULL is returned. */ - EDIT_POINT* Next( const EDIT_POINT& aPoint ); + EDIT_POINT* Next( const EDIT_POINT& aPoint, bool aTraverseContours = true ); EDIT_LINE* Next( const EDIT_LINE& aLine ); @@ -461,6 +511,7 @@ private: EDA_ITEM* m_parent; ///< Parent of the EDIT_POINTs std::deque m_points; ///< EDIT_POINTs for modifying m_parent std::deque m_lines; ///< EDIT_LINEs for modifying m_parent + std::list m_contours; ///< Indices of end contour points }; #endif /* EDIT_POINTS_H_ */ diff --git a/pcbnew/tools/point_editor.cpp b/pcbnew/tools/point_editor.cpp index 023e491fc1..1d8d62d57f 100644 --- a/pcbnew/tools/point_editor.cpp +++ b/pcbnew/tools/point_editor.cpp @@ -119,20 +119,35 @@ public: int cornersCount = outline->GetCornersCount(); for( int i = 0; i < cornersCount; ++i ) + { points->AddPoint( outline->GetPos( i ) ); + if( outline->IsEndContour( i ) ) + points->AddBreak(); + } + // Lines have to be added after creating edit points, // as they use EDIT_POINT references for( int i = 0; i < cornersCount - 1; ++i ) { - points->AddLine( points->Point( i ), points->Point( i + 1 ) ); - points->Line( i ).SetConstraint( - new EC_SNAPLINE( points->Line( i ), + if( points->IsContourEnd( i ) ) + { + points->AddLine( points->Point( i ), + points->Point( points->GetContourStartIdx( i ) ) ); + } + else + { + points->AddLine( points->Point( i ), points->Point( i + 1 ) ); + } + + points->Line( i ).SetConstraint( new EC_SNAPLINE( points->Line( i ), boost::bind( &KIGFX::GAL::GetGridPoint, aGal, _1 ) ) ); } // The last missing line, connecting the last and the first polygon point - points->AddLine( points->Point( cornersCount - 1 ), points->Point( 0 ) ); + points->AddLine( points->Point( cornersCount - 1 ), + points->Point( points->GetContourStartIdx( cornersCount - 1 ) ) ); + points->Line( points->LinesSize() - 1 ).SetConstraint( new EC_SNAPLINE( points->Line( points->LinesSize() - 1 ), boost::bind( &KIGFX::GAL::GetGridPoint, aGal, _1 ) ) ); diff --git a/template/kicad.pro b/template/kicad.pro index f5795a5b16..7619361c14 100644 --- a/template/kicad.pro +++ b/template/kicad.pro @@ -1,15 +1,10 @@ -update=30/03/2013 13:45:59 +update=11/01/2015 18:31:38 version=1 -last_client=pcbnew +last_client=kicad [general] version=1 RootSch= BoardNm= -[cvpcb] -version=1 -NetIExt=net -[cvpcb/libraries] -EquName1=devcms [eeschema] version=1 LibDir= @@ -68,3 +63,6 @@ SolderMaskMinWidth=0.000000000000 DrawSegmentWidth=0.200000000000 BoardOutlineThickness=0.100000000000 ModuleOutlineThickness=0.150000000000 +[cvpcb] +version=1 +NetIExt=net diff --git a/utils/idftools/idf_outlines.cpp b/utils/idftools/idf_outlines.cpp index 614480b0b1..bd1e2a3a44 100644 --- a/utils/idftools/idf_outlines.cpp +++ b/utils/idftools/idf_outlines.cpp @@ -200,6 +200,9 @@ void BOARD_OUTLINE::readOutlines( std::ifstream& aBoardFile, IDF3::IDF_VERSION a // rewind to the start of the last line; the routine invoking // this is responsible for checking that the current '.END_ ...' // matches the section header. + if(aBoardFile.eof()) + aBoardFile.clear(); + aBoardFile.seekg( pos ); if( outlines.size() > 0 ) @@ -2998,6 +3001,9 @@ void IDF3_COMP_OUTLINE::readProperties( std::ifstream& aLibFile ) if( token.size() >= 5 && CompareToken( ".END_", token.substr( 0, 5 ) ) ) { + if(aLibFile.eof()) + aLibFile.clear(); + aLibFile.seekg( pos ); return; } diff --git a/utils/idftools/idf_parser.cpp b/utils/idftools/idf_parser.cpp index 866c417d52..cd662b12fc 100644 --- a/utils/idftools/idf_parser.cpp +++ b/utils/idftools/idf_parser.cpp @@ -2306,7 +2306,7 @@ void IDF3_BOARD::readBoardFile( const std::string& aFileName, bool aNoSubstitute try { - brd.open( aFileName.c_str(), std::ios_base::in ); + brd.open( aFileName.c_str(), std::ios_base::in | std::ios_base::binary ); if( !brd.is_open() ) { @@ -2682,7 +2682,7 @@ void IDF3_BOARD::readLibFile( const std::string& aFileName ) try { - lib.open( aFileName.c_str(), std::ios_base::in ); + lib.open( aFileName.c_str(), std::ios_base::in | std::ios_base::binary ); IDF3::FILE_STATE state = IDF3::FILE_START; @@ -3883,7 +3883,7 @@ IDF3_COMP_OUTLINE* IDF3_BOARD::GetComponentOutline( wxString aFullFileName ) try { - model.open( fname.c_str(), std::ios_base::in ); + model.open( fname.c_str(), std::ios_base::in | std::ios_base::binary ); std::string iline; // the input line