/*! Returns TRUE if the property is scriptable for object \a o; otherwise returns FALSE. If no object \a o is given, the function returns a static approximation. */ bool QMetaProperty::scriptable( QObject* o ) const { if ( o ) { int idx = _id >= 0 ? _id : (*meta)->indexOfProperty( this, TRUE ); return idx >= 0 && o->qt_property( idx, 4, 0 ); } if ( testFlags( ScriptableOverride ) ) { const QMetaObject* mo = (*meta); const QMetaProperty* parent = mo->resolveProperty( this ); return parent ? parent->scriptable() : FALSE; } return !testFlags( NotScriptable ); }
/*! Returns TRUE if the property shall be stored for object \a o; otherwise returns FALSE. If no object \a o is given, the function returns a static approximation. */ bool QMetaProperty::stored( QObject* o ) const { if ( !isValid() || !writable() ) return FALSE; if ( o ) { int idx = _id >= 0 ? _id : (*meta)->indexOfProperty( this, TRUE ); return idx >= 0 && o->qt_property( idx, 5, 0 ); } if ( testFlags( StoredOverride ) ) { const QMetaObject* mo = (*meta); const QMetaProperty* parent = mo->resolveProperty( this ); return parent ? parent->stored() : FALSE; } return !testFlags( NotStored ); }
HRESULT csMenu::QueryContextMenu(HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT /*idCmdLast*/, UINT uFlags) { if( uFlags & CMF_DEFAULTONLY ) { return MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, 0); } UINT uPos = 0; UINT uCmdID = idCmdFirst; const DWORD flags = regReadFlags(); const csWString parallel = regReadParallel(); const DWORD parallelCount = regReadParallelCount(); const bool hasParallel = !parallel.empty() && parallelCount > 1; HMENU submenu = CreatePopupMenu(); insertMenuItem(submenu, uPos++, uCmdID++, L"List", !_files.empty()); insertMenuItem(submenu, uPos++, uCmdID++, L"List (path)", !_files.empty()); insertMenuItem(submenu, uPos++, uCmdID++, L"List (path, tabular)", !_files.empty()); insertSeparatorMenuItem(submenu, uPos++); insertMenuItem(submenu, uPos++, uCmdID++, L"Create symbolic link...", _files.size() == 1); insertSeparatorMenuItem(submenu, uPos++); insertCheckableMenuItem(submenu, uPos++, uCmdID++, L"Batch processing", testFlags(flags, CMD_FLAG_BATCH)); insertCheckableMenuItem(submenu, uPos++, uCmdID++, L"Parallel execution", testFlags(flags, CMD_FLAG_PARALLEL), hasParallel); insertCheckableMenuItem(submenu, uPos++, uCmdID++, L"Resolve UNC paths", testFlags(flags, CMD_FLAG_UNC)); insertCheckableMenuItem(submenu, uPos++, uCmdID++, L"UN*X path separators", testFlags(flags, CMD_FLAG_UNIX)); insertSubMenuItem(hmenu, submenu, indexMenu, uCmdID++, L"CS::Menu", _menuBitmap); const csWStringList scripts = regReadScripts(); if( !scripts.empty() && !_files.empty() ) { insertSeparatorMenuItem(submenu, uPos++); for(csWStringList::const_iterator it = scripts.begin(); it != scripts.end(); it++) { insertMenuItem(submenu, uPos++, uCmdID++, it->c_str()); } } return MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, uCmdID-idCmdFirst); }
void LiveSocket::sendNode(uint32_t clientId, QTreeNode* node, int32_t ndx, int32_t ndy, uint32_t floorMask) { bool underground; if(floorMask & 0xFF00) { if(floorMask & 0x00FF) { underground = false; } else { underground = true; } } else { underground = false; } node->setVisible(clientId, underground, true); // Send message NetworkMessage message; message.write<uint8_t>(PACKET_NODE); message.write<uint32_t>((ndx << 18) | (ndy << 4) | ((floorMask & 0xFF00) ? 1 : 0)); if(!node) { message.write<uint8_t>(0x00); } else { Floor** floors = node->getFloors(); uint16_t sendMask = 0; for(uint32_t z = 0; z < 16; ++z) { uint32_t bit = 1 << z; if(floors[z] && testFlags(floorMask, bit)) { sendMask |= bit; } } message.write<uint16_t>(sendMask); for(uint32_t z = 0; z < 16; ++z) { if(testFlags(sendMask, 1 << z)) { sendFloor(message, floors[z]); } } } send(message); }
/*! Returns whether the property shall be stored for object \a o or not. */ bool QMetaProperty::stored( QObject* o ) const { if ( !isValid() || set == 0 || testFlags( NotStored | UnresolvedStored ) ) return FALSE; if ( store == 0 ) return TRUE; typedef bool (QObject::*ProtoBool)() const; ProtoBool m = (ProtoBool)store; return (o->*m)(); }
int main(void){ wchar_t dest[11]; plan(31); ok(SUCCEEDED(StringCbPrintfExW(dest, 11 * sizeof(wchar_t), NULL, NULL, 0, L"test")), "Print short string without any extended functionality."); is_wstring(L"test", dest, "Result of printing short string."); testDestEnd(); testRemaining(); testFlags(); return 0; }
void LiveSocket::receiveNode(NetworkMessage& message, Editor& editor, Action* action, int32_t ndx, int32_t ndy, bool underground) { QTreeNode* node = editor.map.getLeaf(ndx * 4, ndy * 4); if(!node) { log->Message(wxT("Warning: Received update for unknown tile (") + std::to_string(ndx * 4) + wxT("/") + std::to_string(ndy * 4) + wxT("/") + (underground ? "true" : "false") + wxT(")")); return; } node->setRequested(underground, false); node->setVisible(underground, true); uint16_t floorBits = message.read<uint16_t>(); if(floorBits == 0) { return; } for(uint_fast8_t z = 0; z < 16; ++z) { if(testFlags(floorBits, 1 << z)) { receiveFloor(message, editor, action, ndx, ndy, z, node, node->getFloor(z)); } } }
void LiveSocket::receiveFloor(NetworkMessage& message, Editor& editor, Action* action, int32_t ndx, int32_t ndy, int32_t z, QTreeNode* node, Floor* floor) { Map& map = editor.map; uint16_t tileBits = message.read<uint16_t>(); if(tileBits == 0) { for(uint_fast8_t x = 0; x < 4; ++x) { for(uint_fast8_t y = 0; y < 4; ++y) { action->addChange(new Change(map.allocator(node->createTile(ndx * 4 + x, ndy * 4 + y, z)))); } } return; } // -1 on address since we skip the first START_NODE when sending const std::string& data = message.read<std::string>(); mapReader.assign(reinterpret_cast<const uint8_t*>(data.c_str() - 1), data.size()); BinaryNode* rootNode = mapReader.getRootNode(); BinaryNode* tileNode = rootNode->getChild(); Position position(0, 0, z); for(uint_fast8_t x = 0; x < 4; ++x) { for(uint_fast8_t y = 0; y < 4; ++y) { position.x = (ndx * 4) + x; position.y = (ndy * 4) + y; if(testFlags(tileBits, 1 << ((x * 4) + y))) { receiveTile(tileNode, editor, action, &position); tileNode->advance(); } else { action->addChange(new Change(map.allocator(node->createTile(position.x, position.y, z)))); } } } mapReader.close(); }
void LiveSocket::sendFloor(NetworkMessage& message, Floor* floor) { uint16_t tileBits = 0; for(uint_fast8_t x = 0; x < 4; ++x) { for(uint_fast8_t y = 0; y < 4; ++y) { uint_fast8_t index = (x * 4) + y; Tile* tile = floor->locs[index].get(); if(tile && tile->size() > 0) { tileBits |= (1 << index); } } } message.write<uint16_t>(tileBits); if(tileBits == 0) { return; } mapWriter.reset(); for(uint_fast8_t x = 0; x < 4; ++x) { for(uint_fast8_t y = 0; y < 4; ++y) { uint_fast8_t index = (x * 4) + y; if(testFlags(tileBits, 1 << index)) { sendTile(mapWriter, floor->locs[index].get(), nullptr); } } } mapWriter.endNode(); std::string stream( reinterpret_cast<char*>(mapWriter.getMemory()), mapWriter.getSize() ); message.write<std::string>(stream); }
void LinearScaleY::changeDiapason (double dataDiapason, double plotDiapason) { Mx = -plotDiapason/(testFlags(Scale::ManualDiapason) ? fabs(max-min) : dataDiapason); x0 = (int)( plotDiapason - min*Mx ); };
bool QMetaProperty::isEnumType() const { return testFlags( EnumOrSet ); }
bool NLS::Item::hasSlipPrevention() const { return testFlags(Items::Flags::Spikes); }
bool NLS::Item::hasTradeBlock() const { return testFlags(Items::Flags::TradeUnavailable); }
bool NLS::Item::hasKarma() const { return testFlags(Items::Flags::KarmaScissors); }
bool NLS::Item::hasLock() const { return testFlags(Items::Flags::Lock); }
bool NLS::Item::hasWarmSupport() const { return testFlags(Items::Flags::ColdProtection); }
bool executeCommand(const UINT cmd, const csWStringList& files) { const csWString parallel = regReadParallel(); const DWORD parallelCount = regReadParallelCount(); const bool hasParallel = !parallel.empty() && parallelCount > 1; const DWORD flags = regReadFlags(); const bool isBatch = testFlags(flags, CMD_FLAG_BATCH); const bool isParallel = testFlags(flags, CMD_FLAG_PARALLEL) && hasParallel; const bool isUnc = testFlags(flags, CMD_FLAG_UNC) && cmd != Cmd_List; const bool isUnix = testFlags(flags, CMD_FLAG_UNIX); const csWString scriptPath = regReadScriptsPath(); const csWStringList scripts = regReadScripts(); if( cmd == Cmd_List || cmd == Cmd_ListWithPath || cmd == Cmd_ListWithPathTabular ) { int size = 0; for(csWStringList::const_iterator it = files.begin(); it != files.end(); it++) { wchar_t *uncName = 0; if( isUnc && (uncName = resolveUNC(it->c_str())) != 0 ) { size += lenFN(csWString(uncName), cmd); delete[] uncName; } else { size += lenFN(*it, cmd); } } wchar_t *text = new wchar_t[size+1]; if( text == 0 ) { return false; } int pos = 0; for(csWStringList::const_iterator it = files.begin(); it != files.end(); it++) { wchar_t *uncName = 0; if( isUnc && (uncName = resolveUNC(it->c_str())) != 0 ) { catFN(text, pos, csWString(uncName), cmd); delete[] uncName; } else { catFN(text, pos, *it, cmd); } } text[size] = L'\0'; if( files.size() == 1 ) { // Overwrite trailing <CR><LF> text[size-1] = text[size-2] = L'\0'; } if( isUnix ) { replace(text, size, L'\\', L'/'); } setClipboardText(text); delete[] text; return true; } else if( cmd == Cmd_CreateSymbolicLink ) { csWString symLink; IFileSaveDialog *saveDialog = NULL; HRESULT hr = CoCreateInstance(CLSID_FileSaveDialog, NULL, CLSCTX_INPROC_SERVER, IID_IFileSaveDialog, (LPVOID*)&saveDialog); if( hr == S_OK ) { saveDialog->SetTitle(L"Create symbolic link"); const int index = files.front().lastIndexOf(L'\\'); if( index >= 0 ) { const csWString path = files.front().mid(0, index); const csWString name = files.front().mid(index+1); PIDLIST_ABSOLUTE pidl = NULL; SHParseDisplayName(path.c_str(), NULL, &pidl, 0, NULL); if( pidl != NULL ) { IShellItem *item = NULL; SHCreateItemFromIDList(pidl, IID_IShellItem, (LPVOID*)&item); if( item != NULL ) { saveDialog->SetFolder(item); item->Release(); } CoTaskMemFree(pidl); } saveDialog->SetFileName(name.c_str()); } const COMDLG_FILTERSPEC filterSpec = { L"All files", L"*.*" }; saveDialog->SetFileTypes(1, &filterSpec); const FILEOPENDIALOGOPTIONS opts = FOS_OVERWRITEPROMPT | FOS_FORCEFILESYSTEM | FOS_PATHMUSTEXIST | FOS_CREATEPROMPT | FOS_NOREADONLYRETURN | FOS_NODEREFERENCELINKS | FOS_DONTADDTORECENT; saveDialog->SetOptions(opts); if( saveDialog->Show(NULL) == S_OK ) { IShellItem *item = NULL; if( saveDialog->GetResult(&item) == S_OK ) { wchar_t *filename = NULL; if( item->GetDisplayName(SIGDN_FILESYSPATH, &filename) == S_OK ) { symLink = filename; CoTaskMemFree(filename); } item->Release(); } } saveDialog->Release(); } if( !symLink.empty() ) { if( csFileExists(symLink.c_str()) ) { MessageBoxW(NULL, L"Symbolic link target already exists!", L"Error", MB_OK | MB_ICONERROR); return false; } const DWORD linkFlags = csIsDirectory(files.front().c_str()) ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0; if( CreateSymbolicLinkW(symLink.c_str(), files.front().c_str(), linkFlags) == 0 ) { const DWORD lastError = GetLastError(); csWString msg(L"ERROR(0x"); msg += csWString::number(lastError, 16); msg += L"): "; msg += formatError(lastError); MessageBoxW(NULL, msg.c_str(), L"Error", MB_OK | MB_ICONERROR); return false; } } return true; } else if( cmd == Cmd_CheckBatchProcessing ) { regWriteFlags(flags ^ CMD_FLAG_BATCH); return true; } else if( cmd == Cmd_CheckParallelExecution ) { regWriteFlags(flags ^ CMD_FLAG_PARALLEL); return true; } else if( cmd == Cmd_CheckResolveUncPaths ) { regWriteFlags(flags ^ CMD_FLAG_UNC); return true; } else if( cmd == Cmd_CheckUnixPathSeparators ) { regWriteFlags(flags ^ CMD_FLAG_UNIX); return true; } else if( Cmd_ExecuteScripts <= cmd && cmd < Cmd_ExecuteScripts+scripts.size() ) { csWString script(scriptPath + L"\\"); UINT i = 0; for(csWStringList::const_iterator it = scripts.begin(); it != scripts.end(); it++) { if( i == cmd-Cmd_ExecuteScripts ) { script += *it; break; } i++; } if( isParallel ) { csWStringList args(files); args.push_front(script); args.push_front(csWString::number(parallelCount)); ShellExecuteW(NULL, L"open", parallel.c_str(), joinFileNames(args).c_str(), NULL, SW_SHOWNORMAL); } else { // DO NOT use parallelizer if( isBatch ) { const csWString args = joinFileNames(files); ShellExecuteW(NULL, L"open", script.c_str(), args.c_str(), NULL, SW_SHOWNORMAL); } else { // NO batch processing for(csWStringList::const_iterator it = files.begin(); it != files.end(); it++) { ShellExecuteW(NULL, L"open", script.c_str(), quoteFileName(*it).c_str(), NULL, SW_SHOWNORMAL); } } } return true; } return false; }
MODULE* GPCB_FPL_CACHE::parseMODULE( LINE_READER* aLineReader ) throw( IO_ERROR, PARSE_ERROR ) { #define TEXT_DEFAULT_SIZE ( 40*IU_PER_MILS ) #define OLD_GPCB_UNIT_CONV IU_PER_MILS // Old version unit = 1 mil, so conv_unit is 10 or 0.1 #define NEW_GPCB_UNIT_CONV ( 0.01*IU_PER_MILS ) int paramCnt; double conv_unit = NEW_GPCB_UNIT_CONV; // GPCB unit = 0.01 mils and Pcbnew 0.1 wxPoint textPos; wxString msg; wxArrayString parameters; std::auto_ptr<MODULE> module( new MODULE( NULL ) ); if( aLineReader->ReadLine() == NULL ) THROW_IO_ERROR( "unexpected end of file" ); parameters.Clear(); parseParameters( parameters, aLineReader ); paramCnt = parameters.GetCount(); /* From the Geda PCB documentation, valid Element definitions: * Element [SFlags "Desc" "Name" "Value" MX MY TX TY TDir TScale TSFlags] * Element (NFlags "Desc" "Name" "Value" MX MY TX TY TDir TScale TNFlags) * Element (NFlags "Desc" "Name" "Value" TX TY TDir TScale TNFlags) * Element (NFlags "Desc" "Name" TX TY TDir TScale TNFlags) * Element ("Desc" "Name" TX TY TDir TScale TNFlags) */ if( parameters[0].CmpNoCase( wxT( "Element" ) ) != 0 ) { msg.Printf( _( "unknown token \"%s\"" ), GetChars( parameters[0] ) ); THROW_PARSE_ERROR( msg, aLineReader->GetSource(), (const char *)aLineReader, aLineReader->LineNumber(), 0 ); } if( paramCnt < 10 || paramCnt > 14 ) { msg.Printf( _( "Element token contains %d parameters." ), paramCnt ); THROW_PARSE_ERROR( msg, aLineReader->GetSource(), (const char *)aLineReader, aLineReader->LineNumber(), 0 ); } // Test symbol after "Element": if [ units = 0.01 mils, and if ( units = 1 mil if( parameters[1] == wxT( "(" ) ) conv_unit = OLD_GPCB_UNIT_CONV; if( paramCnt > 10 ) { module->SetDescription( parameters[3] ); module->SetReference( parameters[4] ); } else { module->SetDescription( parameters[2] ); module->SetReference( parameters[3] ); } // Read value if( paramCnt > 10 ) module->SetValue( parameters[5] ); // With gEDA/pcb, value is meaningful after instantiation, only, so it's // often empty in bare footprints. if( module->Value().GetText().IsEmpty() ) module->Value().SetText( wxT( "Val**" ) ); if( paramCnt == 14 ) { textPos = wxPoint( parseInt( parameters[8], conv_unit ), parseInt( parameters[9], conv_unit ) ); } else { textPos = wxPoint( parseInt( parameters[6], conv_unit ), parseInt( parameters[7], conv_unit ) ); } int orientation = parseInt( parameters[paramCnt-4], 1.0 ); module->Reference().SetOrientation( (orientation % 2) ? 900 : 0 ); // Calculate size: default height is 40 mils, width 30 mil. // real size is: default * ibuf[idx+3] / 100 (size in gpcb is given in percent of default size int thsize = parseInt( parameters[paramCnt-3], TEXT_DEFAULT_SIZE ) / 100; thsize = std::max( (int)( 5 * IU_PER_MILS ), thsize ); // Ensure a minimal size = 5 mils int twsize = thsize * 30 / 40; int thickness = thsize / 8; // gEDA/pcb aligns top/left, not pcbnew's default, center/center. // Compensate for this by shifting the insertion point instead of the // aligment, because alignment isn't changeable in the GUI. textPos.x = textPos.x + twsize * module->GetReference().Len() / 2; textPos.y += thsize / 2; // gEDA/pcb draws a bit too low/left, while pcbnew draws a bit too // high/right. Compensate for similar appearance. textPos.x -= thsize / 10; textPos.y += thsize / 2; module->Reference().SetTextPosition( textPos ); module->Reference().SetPos0( textPos ); module->Reference().SetSize( wxSize( twsize, thsize ) ); module->Reference().SetThickness( thickness ); // gEDA/pcb shows only one of value/reference/description at a time. Which // one is selectable by a global menu setting. pcbnew needs reference as // well as value visible, so place the value right below the reference. module->Value().SetOrientation( module->Reference().GetOrientation() ); module->Value().SetSize( module->Reference().GetSize() ); module->Value().SetThickness( module->Reference().GetThickness() ); textPos.y += thsize * 13 / 10; // 130% line height module->Value().SetTextPosition( textPos ); module->Value().SetPos0( textPos ); while( aLineReader->ReadLine() ) { parameters.Clear(); parseParameters( parameters, aLineReader ); if( parameters.IsEmpty() || parameters[0] == wxT( "(" ) ) continue; if( parameters[0] == wxT( ")" ) ) break; paramCnt = parameters.GetCount(); // Test units value for a string line param (more than 3 parameters : ident [ xx ] ) if( paramCnt > 3 ) { if( parameters[1] == wxT( "(" ) ) conv_unit = OLD_GPCB_UNIT_CONV; else conv_unit = NEW_GPCB_UNIT_CONV; } wxLogTrace( traceFootprintLibrary, wxT( "%s parameter count = %d." ), GetChars( parameters[0] ), paramCnt ); // Parse a line with format: ElementLine [X1 Y1 X2 Y2 Thickness] if( parameters[0].CmpNoCase( wxT( "ElementLine" ) ) == 0 ) { if( paramCnt != 8 ) { msg.Printf( wxT( "ElementLine token contains %d parameters." ), paramCnt ); THROW_PARSE_ERROR( msg, aLineReader->GetSource(), (const char *)aLineReader, aLineReader->LineNumber(), 0 ); } EDGE_MODULE* drawSeg = new EDGE_MODULE( module.get() ); drawSeg->SetLayer( F_SilkS ); drawSeg->SetShape( S_SEGMENT ); drawSeg->SetStart0( wxPoint( parseInt( parameters[2], conv_unit ), parseInt( parameters[3], conv_unit ) ) ); drawSeg->SetEnd0( wxPoint( parseInt( parameters[4], conv_unit ), parseInt( parameters[5], conv_unit ) ) ); drawSeg->SetWidth( parseInt( parameters[6], conv_unit ) ); drawSeg->SetDrawCoord(); module->GraphicalItems().PushBack( drawSeg ); continue; } // Parse an arc with format: ElementArc [X Y Width Height StartAngle DeltaAngle Thickness] if( parameters[0].CmpNoCase( wxT( "ElementArc" ) ) == 0 ) { if( paramCnt != 10 ) { msg.Printf( wxT( "ElementArc token contains %d parameters." ), paramCnt ); THROW_PARSE_ERROR( msg, aLineReader->GetSource(), (const char *)aLineReader, aLineReader->LineNumber(), 0 ); } // Pcbnew does know ellipse so we must have Width = Height EDGE_MODULE* drawSeg = new EDGE_MODULE( module.get() ); drawSeg->SetLayer( F_SilkS ); drawSeg->SetShape( S_ARC ); module->GraphicalItems().PushBack( drawSeg ); // for and arc: ibuf[3] = ibuf[4]. Pcbnew does not know ellipses int radius = ( parseInt( parameters[4], conv_unit ) + parseInt( parameters[5], conv_unit ) ) / 2; wxPoint centre( parseInt( parameters[2], conv_unit ), parseInt( parameters[3], conv_unit ) ); drawSeg->SetStart0( centre ); // Pcbnew start angles are inverted and 180 degrees from Geda PCB angles. double start_angle = parseInt( parameters[6], -10.0 ) + 1800.0; // Pcbnew delta angle direction is the opposite of Geda PCB delta angles. double sweep_angle = parseInt( parameters[7], -10.0 ); // Geda PCB does not support circles. if( sweep_angle == -3600.0 ) drawSeg->SetShape( S_CIRCLE ); // Angle value is clockwise in gpcb and Pcbnew. drawSeg->SetAngle( sweep_angle ); drawSeg->SetEnd0( wxPoint( radius, 0 ) ); // Calculate start point coordinate of arc wxPoint arcStart( drawSeg->GetEnd0() ); RotatePoint( &arcStart, -start_angle ); drawSeg->SetEnd0( centre + arcStart ); drawSeg->SetWidth( parseInt( parameters[8], conv_unit ) ); drawSeg->SetDrawCoord(); continue; } // Parse a Pad with no hole with format: // Pad [rX1 rY1 rX2 rY2 Thickness Clearance Mask "Name" "Number" SFlags] // Pad (rX1 rY1 rX2 rY2 Thickness Clearance Mask "Name" "Number" NFlags) // Pad (aX1 aY1 aX2 aY2 Thickness "Name" "Number" NFlags) // Pad (aX1 aY1 aX2 aY2 Thickness "Name" NFlags) if( parameters[0].CmpNoCase( wxT( "Pad" ) ) == 0 ) { if( paramCnt < 10 || paramCnt > 13 ) { msg.Printf( wxT( "Pad token contains %d parameters." ), paramCnt ); THROW_PARSE_ERROR( msg, aLineReader->GetSource(), (const char *)aLineReader, aLineReader->LineNumber(), 0 ); } D_PAD* pad = new D_PAD( module.get() ); static const LSET pad_front( 3, F_Cu, F_Mask, F_Paste ); static const LSET pad_back( 3, B_Cu, B_Mask, B_Paste ); pad->SetShape( PAD_SHAPE_RECT ); pad->SetAttribute( PAD_ATTRIB_SMD ); pad->SetLayerSet( pad_front ); if( testFlags( parameters[paramCnt-2], 0x0080, wxT( "onsolder" ) ) ) pad->SetLayerSet( pad_back ); // Set the pad name: // Pcbnew pad name is used for electrical connection calculations. // Accordingly it should be mapped to gEDA's pin/pad number, // which is used for the same purpose. // gEDA also features a pin/pad "name", which is an arbitrary string // and set to the pin name of the netlist on instantiation. Many gEDA // bare footprints use identical strings for name and number, so this // can be a bit confusing. pad->SetPadName( parameters[paramCnt-3] ); int x1 = parseInt( parameters[2], conv_unit ); int x2 = parseInt( parameters[4], conv_unit ); int y1 = parseInt( parameters[3], conv_unit ); int y2 = parseInt( parameters[5], conv_unit ); int width = parseInt( parameters[6], conv_unit ); wxPoint delta( x2 - x1, y2 - y1 ); double angle = atan2( (double)delta.y, (double)delta.x ); // Get the pad clearance and the solder mask clearance. if( paramCnt == 13 ) { int clearance = parseInt( parameters[7], conv_unit ); // One of gEDA's oddities is that clearance between pad and polygon // is given as the gap on both sides of the pad together, so for // KiCad it has to halfed. pad->SetLocalClearance( clearance / 2 ); // In GEDA, the mask value is the size of the hole in this // solder mask. In Pcbnew, it is a margin, therefore the distance // between the copper and the mask int maskMargin = parseInt( parameters[8], conv_unit ); maskMargin = ( maskMargin - width ) / 2; pad->SetLocalSolderMaskMargin( maskMargin ); } // Negate angle (due to Y reversed axis) and convert it to internal units angle = - RAD2DECIDEG( angle ); pad->SetOrientation( KiROUND( angle ) ); wxPoint padPos( (x1 + x2) / 2, (y1 + y2) / 2 ); pad->SetSize( wxSize( KiROUND( EuclideanNorm( delta ) ) + width, width ) ); padPos += module->GetPosition(); pad->SetPos0( padPos ); pad->SetPosition( padPos ); if( !testFlags( parameters[paramCnt-2], 0x0100, wxT( "square" ) ) ) { if( pad->GetSize().x == pad->GetSize().y ) pad->SetShape( PAD_SHAPE_CIRCLE ); else pad->SetShape( PAD_SHAPE_OVAL ); } module->Add( pad ); continue; } // Parse a Pin with through hole with format: // Pin [rX rY Thickness Clearance Mask Drill "Name" "Number" SFlags] // Pin (rX rY Thickness Clearance Mask Drill "Name" "Number" NFlags) // Pin (aX aY Thickness Drill "Name" "Number" NFlags) // Pin (aX aY Thickness Drill "Name" NFlags) // Pin (aX aY Thickness "Name" NFlags) if( parameters[0].CmpNoCase( wxT( "Pin" ) ) == 0 ) { if( paramCnt < 8 || paramCnt > 12 ) { msg.Printf( wxT( "Pin token contains %d parameters." ), paramCnt ); THROW_PARSE_ERROR( msg, aLineReader->GetSource(), (const char *)aLineReader, aLineReader->LineNumber(), 0 ); } D_PAD* pad = new D_PAD( module.get() ); pad->SetShape( PAD_SHAPE_CIRCLE ); static const LSET pad_set = LSET::AllCuMask() | LSET( 3, F_SilkS, F_Mask, B_Mask ); pad->SetLayerSet( pad_set ); if( testFlags( parameters[paramCnt-2], 0x0100, wxT( "square" ) ) ) pad->SetShape( PAD_SHAPE_RECT ); // Set the pad name: // Pcbnew pad name is used for electrical connection calculations. // Accordingly it should be mapped to gEDA's pin/pad number, // which is used for the same purpose. pad->SetPadName( parameters[paramCnt-3] ); wxPoint padPos( parseInt( parameters[2], conv_unit ), parseInt( parameters[3], conv_unit ) ); int padSize = parseInt( parameters[4], conv_unit ); pad->SetSize( wxSize( padSize, padSize ) ); int drillSize = 0; // Get the pad clearance, solder mask clearance, and drill size. if( paramCnt == 12 ) { int clearance = parseInt( parameters[5], conv_unit ); // One of gEDA's oddities is that clearance between pad and polygon // is given as the gap on both sides of the pad together, so for // KiCad it has to halfed. pad->SetLocalClearance( clearance / 2 ); // In GEDA, the mask value is the size of the hole in this // solder mask. In Pcbnew, it is a margin, therefore the distance // between the copper and the mask int maskMargin = parseInt( parameters[6], conv_unit ); maskMargin = ( maskMargin - padSize ) / 2; pad->SetLocalSolderMaskMargin( maskMargin ); drillSize = parseInt( parameters[7], conv_unit ); } else { drillSize = parseInt( parameters[5], conv_unit ); } pad->SetDrillSize( wxSize( drillSize, drillSize ) ); padPos += module->GetPosition(); pad->SetPos0( padPos ); pad->SetPosition( padPos ); if( pad->GetShape() == PAD_SHAPE_CIRCLE && pad->GetSize().x != pad->GetSize().y ) pad->SetShape( PAD_SHAPE_OVAL ); module->Add( pad ); continue; } } // Recalculate the bounding box module->CalculateBoundingBox(); return module.release(); }